4

パーシャル内に Twitter Bootstrap タブを含む Ruby on Rails アプリケーションがあり、そのパーシャルの複数のインスタンスをユーザーが Simple Form と Cocoon を使用して追加できます。

タブ リンクが適切に機能するためには、パーシャルの新しい子ごとにタブに一意の名前を付ける必要があります (特定のタブをクリックすると、タブ内の同じ名前のタブのコンテンツではなく、独自の一意のコンテンツがアクティブになります)。同じページに表示される前の子パーシャル)。

https://github.com/nathanvda/cocoon/pull/100で、この目的を達成するために Cocoon にコードが追加されていることがわかりました。

その議論では、新しい機能が Cocoon Simple Form Demo プロジェクトで試されたという指摘があります。しかし、新しい機能を試す過程で加えられた変更は、そこにはコミットされていませんでした (少なくとも私が知る限り)。

github のコミットを見ると、'insertionNode.trigger' 呼び出しのパラメーターに '[contentNode]' を追加することで、Cocoon JavaScript コードでその追加が行われたようです ( https://github.com/woto/cocoon/コミット/cb206d501e4749a05e0c1d868911da159c8200c1 ):

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

私はこのことについてあまり洗練されていません。

では、ネストされた子の新しいインスタンスごとに一意の識別子を実装/取得するにはどうすればよいですか?

どんな助けや指示も大歓迎です。

参照用の私のアプリケーションのコードは次のとおりです。

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

-#/app/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 --- --- タブ HREF 名は、一意の識別子が必要な場所です --- ---

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

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

編集/フォローオン質問:

以下のネイサンの回答は、一意の識別子を追加するために機能しましたが、一意の識別子を追加すると、Bootstrap のタブ機能が壊れました。Bootstrap javascript はおそらく、ドキュメントが最初に読み込まれたときにタブとリンクの間の対応を評価しているだけだという私の印象を考えると、これはある程度理にかなっているように思えます。

Bootstrap JavaScript を再初期化して新しい ID とリンクを見つける方法を教えてもらえますか??

EDIT2

それはdivの.well.span分離.nested-fieldsであり、Bootstrapが新しい名前とタブID.tabbableを初期化できなかったことがわかりました(私は思います)。hrefクレイジーな旅ですが、最終的には満足です。

4

1 に答える 1

4

まず、cocoon_simple_form_demoプロジェクトでは、最後のコミットでcocoon:before-insertorcocoon: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もう 1 つの方法は、次のように、より良いものを使用することです。

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

これは、ページがロードされたときに一度だけ実行する必要があり、タブが追加されたときに引き続き機能します。

HTH。

于 2013-02-04T23:54:36.490 に答える