使用Twitter Bootstrap& amp;标签链接的唯一嵌套子标识符茧

时间:2013-02-01 19:11:06

标签: ruby-on-rails twitter-bootstrap simple-form nested-forms cocoon-gem

我有一个Ruby on Rails应用程序,部分使用Twitter Bootstrap选项卡,用户可以使用Simple Form和Cocoon添加该部分的多个实例。

为了使标签链接正常工作,我必须为部分的每个新子项中的标签具有唯一的名称(以便点击特定标签激活其自己的唯一内容而不是相同标签的内容前一个子部分中的名称出现在同一页面上。)

我看到代码已添加到Cocoon中以实现此目标:https://github.com/nathanvda/cocoon/pull/100

在该讨论中,有一个迹象表明在Cocoon Simple Form Demo项目中尝试了新功能。但是在尝试新功能的过程中所做的任何改变都没有在那里进行(至少据我所知)。

查看github上的提交,通过在'insertionNode.trigger'调用(https://github.com/woto/cocoon/commit/cb206d501e4749a05e0c1d868911da159c8200c1)上的参数中添加'[contentNode]',可以在Cocoon javascript代码中完成添加:

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

我对这些东西不太熟练。

那么,如何为嵌套子项的每个新实例实现/获取唯一标识符?

非常感谢任何帮助或指示。

以下是我的申请中的代码供参考:

- #/ app / control / 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

- #/应用/视图/ 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 --- --- TAB HREF NAME是我需要的唯一身份识别者--- ---

.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'

- #/应用/视图/ 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'

编辑/关注问题:

下面的Nathan的答案用于添加唯一标识符,但添加唯一标识符已经破坏了Bootstrap的标签功能。这似乎有些道理,因为我的印象是Bootstrap javascript可能只是在文档最初加载时评估选项卡和链接之间的对应关系。

有人能指出我如何让​​Bootstrap javascript重新初始化并找到新的ID和链接吗?

EDIT2

原来(我认为)分隔.well.span.nested-fields的div .tabbable阻止了Bootstrap能够初始化新命名的href和标签ID 。疯狂的旅程,但最终还是令人满意。

1 个答案:

答案 0 :(得分:4)

首先,在cocoon_simple_form_demo项目中,您会看到最后一次提交使用cocoon:before-insertcocoon:after-insert事件添加动画。

after_insert事件为您提供了插入的DOM元素,因此您可以随意执行任何操作,例如:填写一个独特的href。

所以在你的情况下,这将是类似下面的内容(注意:完全未经测试的代码,但我希望它能让你前进):

$('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
});

这只是标准的jquery DOM操作。希望这会有所帮助。

你可以在插入后重新触发标签行为(这需要在插入后,否则没有用):

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

你应该有这样的代码吗?另一种方法是使用更好的on,如下所示:

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

当加载页面时,这只需要进行一次,并且在添加标签时这将继续工作。

HTH。