Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveAdmin: how to add a Panel into a Form block?

I have reused a panel for Attachments, that are shown on the show block.

I'd like that also be shown on the form block, for Edit.

Is that possible?

I've tried something like this:

form do |f|
  #! attachments_panel:
  panel "Attachments" do
  ul do
    # (..) li components
  end

  #! Editing form
  f.inputs 'Details' do
    f.input :name
    # (..) other inputs
  end

end

But it is only showing the Panel, the form is not included. Altering the other also shows only the panel.


EDIT: Based on the solution of @CMaresh, I've created an initializer that monkeypatches the ActiveAdmin gem.

#! config/initializers/active_admin_patches.rb
ActiveAdmin::FormBuilder.class_eval do
  def append_panel(&block)
    self.form_buffers.last << Arbre::Context.new({}, self.template, &block)
  end
end

This way, it allows to use the original example code as follows:

form do |f|
  #! attachments_panel:
  f.append_panel do            # <----
    panel "Attachments" do
    ul do
      # (..) li components
    end
  end

  #! Editing form
  f.inputs 'Details' do
    f.input :name
    # (..) other inputs
  end

end
like image 465
sequielo Avatar asked Feb 15 '23 16:02

sequielo


1 Answers

That issue is caused by how the underlying form and Arbre buffers function. The two buffering techniques aren't quite compatible with each other, but to accomplish what you want you can act directly on the form's buffer:

form do |f|
  f.form_buffers.last << Arbre::Context.new({}, f.template) do
    panel "Panel Above Form" do
      ul do
        li "item 1"
        li "item 2"
      end

      attributes_table_for(f.object) do
        row :name
      end
    end
  end

  f.inputs
end

The Arbre::Context takes two arguments: an assigns hash and a helpers object. It is important to pass in f.template to provide access to all the same helper methods available in views.

An ApplicationHelper

A helper could be written to alleviate the noise of creating a new context every time:

# app/helpers/application_helper.rb
module ApplicationHelper
  def append_arbre(f, &block)                                                   
    f.form_buffers.last << Arbre::Context.new({}, f.template, &block)           
  end
end

# app/admin/resource.rb
form do |f|
  append_arbre(f) do
    panel "Panel Above Form" do
      para "Without all the noise."
    end
  end

  f.inputs
end
like image 143
Charles Maresh Avatar answered Feb 17 '23 04:02

Charles Maresh