# frozen_string_literal: true module ActiveAdmin module Filters # This form builder defines methods to build filter forms such # as the one found in the sidebar of the index page of a standard resource. class FormBuilder < ::ActiveAdmin::FormBuilder include ::ActiveAdmin::Filters::FormtasticAddons self.input_namespaces = [::Object, ::ActiveAdmin::Inputs::Filters, ::ActiveAdmin::Inputs, ::Formtastic::Inputs] # TODO: remove input class finders after formtastic 4 (where it will be default) self.input_class_finder = ::Formtastic::InputClassFinder def filter(method, options = {}) if method.present? && options[:as] ||= default_input_type(method) template.concat input(method, options) end end protected # Returns the default filter type for a given attribute. If you want # to use a custom search method, you have to specify the type yourself. def default_input_type(method, options = {}) if method =~ /_(eq|equals|cont|contains|start|starts_with|end|ends_with)\z/ :string elsif klass._ransackers.key?(method.to_s) klass._ransackers[method.to_s].type elsif reflection_for(method) || polymorphic_foreign_type?(method) :select elsif column = column_for(method) case column.type when :date, :datetime :date_range when :string, :text :string when :integer, :float, :decimal :numeric when :boolean :boolean end end end end # This module is included into the view module ViewHelper # Helper method to render a filter form def active_admin_filters_form_for(search, filters, options = {}) defaults = { builder: ActiveAdmin::Filters::FormBuilder, url: collection_path, html: { class: "filter_form" } } required = { html: { method: :get }, as: :q } options = defaults.deep_merge(options).deep_merge(required) form_for search, options do |f| filters.each do |attribute, opts| next if opts.key?(:if) && !call_method_or_proc_on(self, opts[:if]) next if opts.key?(:unless) && call_method_or_proc_on(self, opts[:unless]) filter_opts = opts.except(:if, :unless) filter_opts[:input_html] = instance_exec(&filter_opts[:input_html]) if filter_opts[:input_html].is_a?(Proc) f.filter attribute, filter_opts end buttons = content_tag :div, class: "buttons" do f.submit(I18n.t("active_admin.filters.buttons.filter")) + link_to(I18n.t("active_admin.filters.buttons.clear"), "#", class: "clear_filters_btn") + hidden_field_tags_for(params, except: except_hidden_fields) end f.template.concat buttons end end private def except_hidden_fields [:q, :page] end end end end