# This is a unique form input # Takes in the same collection as a grouped select # Displays the groups on the left, and each of the items on the right panel # Only supports one category, and one kind of objects # No polymorphic stuff module Effective module FormBuilderInputs class EffectivePanelSelect < Effective::FormBuilderInput delegate :grouped_collection_select, :hidden_field_tag, :text_field_tag, :render, to: :@template def default_options { label_method: :to_s, value_method: :to_s, group_label_method: :first, group_method: :second, option_value_method: :first, option_key_method: :second, sidebar_class: 'nav-stacked' } end def default_input_js { placeholder: 'Please choose', invade: '.row', collapseOnSelect: true, resetOnCollapse: true, showCount: false, showSearch: true } end def default_input_html { class: 'effective_panel_select' } end def to_html render('effective/effective_panel_select/input', input: self) end def method_name @method_name ||= @method.to_s.titleize.downcase end def ajax? return true if js_options[:ajax] end def show_count? return true if js_options[:showCount] end def show_search? return true if js_options[:showSearch] end # option_value 1 # option_label Post A # group_label Active # 163 def option_value value end # Post A def option_label return nil unless value.present? @option_label || (_initialize_group_and_option; @option_label) end # Active def group_label return nil unless value.present? @group_label || (_initialize_group_and_option; @group_label) end # Active def group_value return nil unless value.present? @group_value || (_initialize_group_and_option; @group_value) end def _initialize_group_and_option collection.each do |group, items| items.each do |item| if item.send(options[:option_key_method]) == value @group_label = group.send(options[:group_label_method]) @group_value = group.send(options[:group_method]) @option_label = item.send(options[:option_value_method]) return end end end end # This is a grouped polymorphic collection # [['Active', [['Post A', 1], ['Post B', 2]]], ['Past', [['Post C', 3], ['Post D', 4]]] def collection @collection ||= begin collection = options.delete(:collection) || [] grouped = collection[0].kind_of?(Array) && collection[0][1].respond_to?(:to_a) && (collection[0][1] != nil) # Array or ActiveRecord_Relation if !grouped && collection.present? raise "Grouped collection expecting a Hash {'Posts' => Post.all, 'Events' => Event.all} or a Hash {'Posts' => [['Post A', 1], ['Post B', 2]], 'Events' => [['Event A', 1], ['Event B', 2]]}" end collection.each_with_index do |(name, group), index| collection[index][1] = group.respond_to?(:call) ? group.call : group.to_a end if collection[0][0].kind_of?(String) options[:group_label_method] = :to_s options[:group_method] = :to_s end collection.respond_to?(:call) ? collection.call : collection.to_a end end end end end