app/models/effective/form_inputs/select_or_text.rb
# frozen_string_literal: true module Effective module FormInputs class SelectOrText < Effective::FormInput attr_accessor :name_text attr_accessor :select_collection attr_accessor :select_options attr_accessor :text_options VISIBLE = {} HIDDEN = { wrapper: { style: 'display: none;' } } def initialize(name, options, builder:) @name_text = options.delete(:name_text) || raise('Please include a text method name') @select_collection = options.delete(:collection) || raise('Please include a collection') @shared_options = (options[:input_html] || {}) @select_options = { placeholder: '', hint: "Can't find your #{(options[:name] || name).to_s.chomp('_id')}? <a class='effective-select-or-text-switch' title='Switch to enter freeform' data-effective-select-or-text='true' href='#'>Click here</a> to add one", required: false, }.merge(options[:select] || options.presence || {}).merge(@shared_options) @text_options = { placeholder: '', hint: "Looking for an existing #{(options[:name] || name).to_s.chomp('_id')}? <a class='effective-select-or-text-switch' title='Switch to search for existing' data-effective-select-or-text='true' href='#'>Click here</a> to search", required: false }.merge(options[:text] || options[:text_field] || options.presence || {}).merge(@shared_options) @email_field = options.fetch(:email, name_text.to_s.include?('email')) super end def to_html(&block) wrapper_class = ['effective-select-or-text', (select? ? 'select-enabled' : 'text-enabled'), options.dig(:wrapper, :class)].compact.join(' ') content_tag(:div, (options[:wrapper] || {}).merge(class: wrapper_class)) do if select? @builder.send(email_field? ? :email_field : :text_field, name_text, text_options) + @builder.select(name, select_collection, select_options) else @builder.select(name, select_collection, select_options) + @builder.send(email_field? ? :email_field : :text_field, name_text, text_options) end end end def select? return true if object.errors[name].present? return false if object.errors[name_text].present? value = object.send(name) return true if (value.present? && select_collection.include?(value)) return true if (value.to_i > 0 && select_collection.find { |obj| obj.respond_to?(:id) && obj.id == value.to_i }) return true if value.blank? && object.send(name_text).blank? end def text? !select? end def email_field? @email_field end def select_options @select_options.merge(select? ? VISIBLE : HIDDEN) end def text_options @text_options.merge(text? ? VISIBLE : HIDDEN) end end end end