Search code examples
jqueryruby-on-railshamlcocoon-gem

Cocoon/jQuery: append items to relevant table


I have a Rails view that allows many PanelItems to be added to many Panels on a Page.

Models

class Page < ActiveRecord::Base
  has_many :panels
  accepts_nested_attributes_for :panels, allow_destroy: true

class Panel < ActiveRecord::Base
  has_many :panel_items
  accepts_nested_attributes_for :panel_items, allow_destroy: true, reject_if: :all_blank

class PanelItem < ActiveRecord::Base

Views

app/views/pages/_form.html.haml

= simple_form_for @page, html: { class: 'form-inline' } do |form|
  = form.input :name, required: :required, autofocus: :autofocus

  %table.table.table-hover
    %tbody
      = form.simple_fields_for :panels do |panel_form|
        %tr
          %td
            .table-responsive
              %table.table.table-hover
                %tbody.panel-items
                  = panel_form.simple_fields_for :panel_items do |panel_item_fields|
                    = render 'panel_item_fields', f: panel_item_fields
            = link_to_add_association panel_form, :panel_items,
                'data-association-insertion-method' => 'append',
                class: 'btn btn-success pull-right' do
              %span{class: 'glyphicon glyphicon-plus-sign'}
              New item
  = form.button :submit, "Update Page", class: 'btn-success'

app/views/pages/_panel_item_fields.html.haml

%tr.nested-fields
  %td
    = f.input :content_item_id,
        collection: current_site.content_items,
        selected: f.object.content_item_id,
        prompt: 'Select a content item'
  %td
    = link_to_remove_association f, title: 'remove this item',
        data: { toggle: 'tooltip', association: 'panel-item' } do
      %span.sr-only remove this item
      %span{class: 'glyphicon glyphicon-minus-sign'}

I want the New item button to append the panel_item_fields partial at the end of the associated table. I've tried many combinations of data-association-insertion-node and data-association-insertion-traversal attributes with no joy.

Cocoon uses the data- attributes to set the variables insertionTraversal and insertionNode, used in the following jQuery code:

$this[insertionTraversal](insertionNode)

but I don't really know how to read that.

EDIT: If I use:

'data-association-insertion-node' => '.panel-items',
'data-association-insertion-method' => 'append',

The new row gets appended to every table on the page, instead of just the closest table.


Solution

  • It seems that append'ing to a table appends to the tbody, so by making the New item button a sibling of the table:

    .table-responsive
      %table.table.table-hover
        %tbody.panel-items
          = panel_form.simple_fields_for :panel_items do |panel_item_fields|
            = render 'panel_item_fields', f: panel_item_fields
      = link_to_add_association panel_form, :panel_items,
          'data-association-insertion-method' => 'append',
          'data-association-insertion-traversal' => 'prev',
          'data-association-insertion-node' => 'table',
          class: 'btn btn-success pull-right' do
        %span{class: 'glyphicon glyphicon-plus-sign'}
        New item
    

    cocoon can now append to the previous table.