# frozen_string_literal: true module Satis module Dropdown class Component < ViewComponent::Base attr_reader :url, :form, :attribute, :title, :options def initialize(form:, attribute:, **options, &block) super @form = form @attribute = attribute @title = title @options = options @url = options[:url] @chain_to = options[:chain_to] @free_text = options[:free_text] @needs_exact_match = options[:needs_exact_match] @reset_button = options[:reset_button] || options[:include_blank] @toggle_button = options[:toggle_button] != false options[:input_html] ||= {} options[:input_html][:value] = hidden_value options[:input_html][:autofocus] ||= false if options[:input_html][:autofocus] options[:autofocus] = "autofocus" options[:input_html].delete(:autofocus) end unless options[:input_html]["data-reflex"] actions = [options[:input_html]["data-action"], "change->satis-dropdown#display", "focus->satis-dropdown#focus"].join(" ") end options[:input_html].merge!("data-satis-dropdown-target" => "hiddenSelect", "data-action" => actions) @block = block @page_size = options[:page_size] || 25 end # Deal with context def hidden_value value = @options[:selected] value ||= @options.dig(:input_html, :value) value ||= form.object&.send(attribute) value = value.id if value.respond_to?(:id) value = value.second if value.is_a?(Array) && value.size == 2 && value.first.casecmp?(value.second) value end def options_array(obj) return [[]] unless obj if obj.is_a?(Array) obj.filter_map {|item| option_value(item) } else [option_value(obj)] end end def option_value(item) text = value = "" if item.respond_to?(:id) value = item.send(:id) text = if item.respond_to?(:name) item.send(:name) else "" end elsif item.is_a?(Array) value = item.first text = item.second elsif item.is_a?(String) text = value = item end return nil if value.blank? [text, item, {selected: true}] end def placeholder return title if title.present? if form.object.class.respond_to?(:human_attribute_name) form.object.class.human_attribute_name(attribute) else attribute.to_s.humanize end end def value_method options[:value_method] || :id end def text_method options[:text_method] || :name end def custom_item_html? !!@block end def item_html(item) form.template.capture { @block.call(item) } end end end end