lib/active_admin/views/components/active_admin_form.rb
# frozen_string_literal: true module ActiveAdmin module Views class FormtasticProxy < ::Arbre::Rails::Forms::FormBuilderProxy def split_string_on(string, match) return "" unless string && match part_1 = string.split(Regexp.new("#{match}\\z")).first [part_1, match] end def opening_tag @opening_tag || "" end def closing_tag @closing_tag || "" end def to_s opening_tag + children.to_s + closing_tag end end class ActiveAdminForm < FormtasticProxy builder_method :active_admin_form_for def build(resource, options = {}, &block) @resource = resource options = options.deep_dup options[:builder] ||= ActiveAdmin::FormBuilder form_string = helpers.semantic_form_for(resource, options) do |f| @form_builder = f end @opening_tag, @closing_tag = split_string_on(form_string, "</form>") instance_eval(&block) if block # Rails sets multipart automatically if a file field is present, # but the form tag has already been rendered before the block eval. if multipart? && !@opening_tag.include?('multipart') @opening_tag.sub!(/<form/, '<form enctype="multipart/form-data"') end end def inputs(*args, &block) if block form_builder.template.assigns[:has_many_block] = true end if block && block.arity == 0 wrapped_block = proc do wrap_it = form_builder.already_in_an_inputs_block ? true : false form_builder.already_in_an_inputs_block = true content = form_builder.template.capture do block.call end form_builder.already_in_an_inputs_block = wrap_it content end insert_tag(SemanticInputsProxy, form_builder, *args, &wrapped_block) else # Set except option to prevent sensitive fields from being shown in forms by default. opts = args.extract_options! opts[:except] ||= [] ActiveAdmin.application.filter_attributes.each { |e| opts[:except] << e } args << opts proxy_call_to_form(:inputs, *args, &block) end end def input(*args) proxy_call_to_form :input, *args end def actions(*args, &block) if block insert_tag(SemanticActionsProxy, form_builder, *args, &block) else add_create_another_checkbox actions(*args) { commit_action_with_cancel_link } end end def commit_action_with_cancel_link action(:submit) cancel_link end def add_create_another_checkbox if %w(new create).include?(helpers.action_name) && active_admin_config && active_admin_config.create_another current_arbre_element.add_child(create_another_checkbox) end end def has_many(*args, &block) insert_tag(HasManyProxy, form_builder, *args, &block) end def multipart? form_builder && form_builder.multipart? end def object form_builder.object end private def create_another_checkbox create_another = params[:create_another] label = @resource.class.model_name.human Arbre::Context.new do div class: "boolean input input-create-another" do label for: "create_another" do input( checked: create_another, id: "create_another", name: "create_another", type: "checkbox" ) text_node I18n.t("active_admin.create_another", model: label) end end end end end class SemanticInputsProxy < FormtasticProxy def build(form_builder, *args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs" legend = args.shift if args.first.is_a?(::String) legend = html_options.delete(:name) if html_options.key?(:name) legend_tag = legend ? "<legend class=\"fieldset-title\">#{legend}</legend>" : "" fieldset_attrs = html_options.map { |k, v| %Q{#{k}="#{v}"} }.join(" ") @opening_tag = "<fieldset #{fieldset_attrs}>#{legend_tag}<ol>" @closing_tag = "</ol></fieldset>" super(*(args << html_options), &block) end end class SemanticActionsProxy < FormtasticProxy def build(form_builder, *args, &block) @opening_tag = "<fieldset class=\"actions\"><ol>" @closing_tag = "</ol></fieldset>" super(*args, &block) end end class HasManyProxy < FormtasticProxy def build(form_builder, *args, &block) text_node form_builder.has_many(*args, &block) end end end end