Unique nested child identifiers for tabs using Twitter Bootstrap & Cocoon

I have a Ruby on Rails application with Twitter Bootstrap tabs in partial, and several instances of this particle can be added by the user using Simple Form and Cocoon.

For tab links to work correctly, I must have unique names for the tabs of each new partial child element (so that clicking on a specific tab activates its own unique content, and not the content for the tab of the same name in the previous child partial appearance on the same page).

I saw that the code was added to Cocoon to achieve this goal here: https://github.com/nathanvda/cocoon/pull/100 .

There is an indication in this discussion that the new functionality has been tested in the Cocoon Simple Form Demo project. But there were no changes in the process of testing new features (at least as far as I could tell).

Looking at the commit on github, this addition seems to have been done in Cocoon's javascript code, adding "[contentNode]" to the call parameters of "insertionNode.trigger" ( https://github.com/woto/cocoon/commit/cb206d501e4749a05e0c1d868911da159c8200c1d868911da159c8200c1008cc00001c8200c10081c8200c10082

insertionNode.trigger('cocoon:before-insert', [contentNode]); 

I am not very good at it.

So, how do I implement / capture a unique identifier for each new instance of a nested child?

Any help or guidance would be greatly appreciated.

Here is the code from my application for reference:

- # / app / controllers / parent_records_controller.rb

 class ParentRecordsController < ApplicationController # GET /parent_records/1/edit def edit @parent_record = ParentRecord.find(params[:id]) @parent_record.items.build end end 

- # / application / views / parent_records / _form.html.haml

 .row-fluid =simple_form_for(@parent_record, :wrapper => :inline4, :html => {:class => 'form-inline', :multipart => true}) do |f| .row-fluid = f.simple_fields_for :items do |item| =render :partial => '/parent_records/form_partials/item', :locals => { :f => item } .row .span2.offset9 = link_to_add_association 'Add Another Item', f, :items, :class => 'btn btn-primary', :partial => 'parent_records/form_partials/item' = f.button :submit , :class => 'btn btn-success' 

- # / app / views / parent_records / form_partials / _item --- --- TITLE BACK TAB - WHERE I NEED UNIQUE IDENTIFICATIONS --- ---

 .nested-fields .well.span .tabbable %ul.nav.nav-tabs %li.active %a{"data-toggle" => "tab", :href => "#tab1"} Item Info %li %a{"data-toggle" => "tab", :href => "#tab2"} Pictures .tab-content #tab1.tab-pane.active = f.input :short_name,:label => 'Item Title' = f.input :brand,:label => 'Brand' = f.input :description,:label => 'Description' #tab2.tab-pane = f.simple_fields_for :pictures do |picture| =render :partial => '/parent_record/form_partials/picture', :locals => { :f => picture } .span2.offset9 = link_to_add_association 'Add A Picture', f, :pictures, :class => 'btn btn-primary', :partial => 'parent_records/form_partials/picture' .span2 = link_to_remove_association "Remove Item", f, :class => 'btn btn-danger' 

- # / application / views / parent_records / form_partials / _picture

 .nested-fields .well.span = f.input :image, :label => 'Seclect Image to be Uploaded' = f.input :rank, :label => 'Image Rank for this Item' .row .span2 = link_to_remove_association "Remove Picture", f, :class => 'btn btn-danger' 

QUESTION EDIT / FOLLOW-ON:

Nathan's answer below worked on adding unique identifiers, but adding unique identifiers violated Tabstab functionality. It seems to make sense, given my impression that the Bootstrap JavaScript script probably evaluates the correspondence between tabs and links when the document is initially loaded.

Can someone tell me how to get javascript Bootstrap to reinitialize and search for new identifiers and links?

EDIT2

It turns out (I think) that the .well.span div, separating .nested-fields and .tabbable , did not allow Bootstrap to be able to initialize the newly named href and tab ids. Crazy trip, but in the end satisfaction.

+4
source share
1 answer

First of all, in the cocoon_simple_form_demo project , you will see that the last commit adds animations using the cocoon:before-insert or cocoon:after-insert event.

The after_insert event provides a DOM element that is inserted, so you can do whatever you like with it, for example. fill in a unique href.

So, in your case, it will be something like the following (note: completely untested code, but I hope it catches you):

 $('form').bind('cocoon:before-insert', function(e,item_to_be_added) { new_id = new Date().getTime(); item_to_be_added.find('a[href="#tab1"]').attr('href', "#tab1_" + new_id); item_to_be_added.find('#tab1').attr('id', "tab1_" + new_id); // do the same for #tab2 }); 

This is the standard jQuery DOM manipulation. Hope this helps.

You can either restart the behavior of the tabs after pasting (this should be after pasting, and the other is useless):

  $('form').bind('cocoon:after-insert', function(e,item_to_be_added) { $('nav-tabs a').click(function(e) { e.preventDefault(); $(this).tab('show'); }); }); 

You should already have this code? Another alternative is to use a better on , for example:

 $('form').on 'click', '.nav-tabs a', function(e) { e.preventDefault(); $(this).tab('show'); }); 

This needs to be done only once when the page loads, and this will continue to work when adding tabs.

NTN.

+4
source

All Articles