class ActiveAdmin::FormBuilder

def action(*args)

def action(*args)
  form_buffers.last << with_new_form_buffer{ super }
end

def actions(*args, &block)

def actions(*args, &block)
  form_buffers.last << with_new_form_buffer do
    block_given? ? super : super{ commit_action_with_cancel_link }
  end
end

def active_admin_input_class_name(as)

def active_admin_input_class_name(as)
  "ActiveAdmin::Inputs::#{as.to_s.camelize}Input"
end

def cancel_link(url = {:action => "index"}, html_options = {}, li_attrs = {})

def cancel_link(url = {:action => "index"}, html_options = {}, li_attrs = {})
  li_attrs[:class] ||= "cancel"
  li_content = template.link_to I18n.t('active_admin.cancel'), url, html_options
  form_buffers.last << template.content_tag(:li, li_content, li_attrs)
end

def commit_action_with_cancel_link

def commit_action_with_cancel_link
  action(:submit)
  cancel_link
end

def field_set_and_list_wrapping(*args, &block)

the most recent part of the Active Admin form buffer.
valid return value but it was otherwise built correctly, we instead use
and wraps the resulting HTML in a fieldset. If your block doesn't have a
This method calls the block it's passed (in our case, the `f.inputs` block)
def field_set_and_list_wrapping(*args, &block)
  block_given? ? super{
    (val = yield).is_a?(String) ? val : form_buffers.last
  } : super
end

def has_many(association, options = {}, &block)

def has_many(association, options = {}, &block)
  options = { :for => association, :new_record => true }.merge(options)
  options[:class] ||= ""
  options[:class] << "inputs has_many_fields"
  # Add Delete Links
  form_block = proc do |has_many_form|
    # @see https://github.com/justinfrench/formtastic/blob/2.2.1/lib/formtastic/helpers/inputs_helper.rb#L373
    contents = if block.arity == 1  # for backwards compatibility with REE & Ruby 1.8.x
      block.call(has_many_form)
    else
      index = parent_child_index(options[:parent]) if options[:parent]
      block.call(has_many_form, index)
    end
    if has_many_form.object.new_record?
      contents += template.content_tag(:li, :class => 'has_many_delete') do
        template.link_to I18n.t('active_admin.has_many_delete'), "#", :onclick => "$(this).closest('.has_many_fields').remove(); return false;", :class => "button"
      end
    elsif options[:allow_destroy]
      has_many_form.input :_destroy, :as => :boolean, :wrapper_html => {:class => "has_many_remove"},
                                                      :label => I18n.t('active_admin.has_many_remove')
    end
    contents
  end
  form_buffers.last << with_new_form_buffer do
    template.content_tag :div, :class => "has_many #{association}" do
      # Allow customization of the nested form heading
      unless options.key?(:heading) && !options[:heading]
        form_heading = options[:heading] ||
          object.class.reflect_on_association(association).klass.model_name.human(:count => 1.1)
        form_buffers.last << template.content_tag(:h3, form_heading)
      end
      inputs options, &form_block
      js = options[:new_record] ? js_for_has_many(association, form_block, template) : ""
      form_buffers.last << js.html_safe
    end
  end
end

def initialize(*args)

def initialize(*args)
  @form_buffers = ["".html_safe]
  super
end

def input(method, *args)

to the form buffer. Else, return it directly.
If this `input` call is inside a `inputs` block, add the content
def input(method, *args)
  content = with_new_form_buffer{ super }
  @use_form_buffer ? form_buffers.last << content : content
end

def input_class_by_trying(as)

use auto-loading in development environment
def input_class_by_trying(as)
  begin
    custom_input_class_name(as).constantize
  rescue NameError
    begin
      active_admin_input_class_name(as).constantize
    rescue NameError
      standard_input_class_name(as).constantize
    end
  end
rescue NameError
  raise Formtastic::UnknownInputError, "Unable to find input class for #{as}"
end

def input_class_with_const_defined(as)

Overrides Formtastic's version to include ActiveAdmin::Inputs::*
def input_class_with_const_defined(as)
  input_class_name = custom_input_class_name(as)
  if ::Object.const_defined?(input_class_name)
    input_class_name.constantize
  elsif ActiveAdmin::Inputs.const_defined?(input_class_name)
    active_admin_input_class_name(as).constantize
  elsif Formtastic::Inputs.const_defined?(input_class_name)
    standard_input_class_name(as).constantize
  else
    raise Formtastic::UnknownInputError, "Unable to find input class #{input_class_name}"
  end
end

def inputs(*args, &block)

def inputs(*args, &block)
  @use_form_buffer = block_given?
  form_buffers.last << with_new_form_buffer{ super }
end

def js_for_has_many(association, form_block, template)

Capture the ADD JS
def js_for_has_many(association, form_block, template)
  assoc_reflection = object.class.reflect_on_association(association)
  assoc_name       = assoc_reflection.klass.model_name
  placeholder      = "NEW_#{assoc_name.to_s.upcase.split(' ').join('_')}_RECORD"
  opts = {
    :for         => [association, assoc_reflection.klass.new],
    :class       => "inputs has_many_fields",
    :for_options => { :child_index => placeholder }
  }
  js = with_new_form_buffer{ inputs_for_nested_attributes opts, &form_block }
  js = template.escape_javascript js
  onclick = "$(this).before('#{js}'.replace(/#{placeholder}/g, new Date().getTime())); return false;"
  text    = I18n.t 'active_admin.has_many_new', :model => assoc_name.human
  template.link_to(text, "#", :onclick => onclick, :class => "button").html_safe
end

def semantic_errors(*args)

def semantic_errors(*args)
  form_buffers.last << with_new_form_buffer{ super }
end

def with_new_form_buffer

def with_new_form_buffer
  form_buffers << ''.html_safe
  return_value = (yield || '').html_safe
  form_buffers.pop
  return_value
end