2013-02-08 7 views
6

に値に依存するデータの属性を追加しますフォーム内で上位の選択ウィジェットの値。 (例えば、ロボット選択から「トラッカーロボット」を選択すると、「足の部分」チェックボックスが消え、「ホイール」チェックボックスが表示されます。)私はそうのような単一のコレクションのチェックボックスのリストを生成していますsimple_formチェックボックスコレクション

私がしたいのは、そのパーツを使用できるロボットを列挙した属性値を持つ個々のパーツチェックボックス。いくつかのJSは、チェックボックスを隠す/表示する作業を行います。しかし、私はsimple_formを使ってこれらのデータ属性をどのように生成できるのか分かりません。

私は通常、カスタムの「部品」入力を作成しますが、カスタム入力を作成する際に問題があるようです。それは存在しないform_builder.rbの中で名前付きのメソッド(collection_parts)を探し、私がFormBuilderを試して拡張しようとすると、私を大規模なウサギの穴に送ります。

私は、生成されたHTMLにデータattrsをロードするJSを書くことができましたが、私はRailsデータに基づいてカスタムJSを生成しなければなりません。

私はあなたがこのようにそれを行うことができると思い

答えて

7

= f.input :parts do 
    = f.collection_check_boxes :parts, @parts_list, :id, :to_s, item_wrapper_tag: :label, item_wrapper_class: :checkbox do |b| 
    - b.check_box(data: { YOUR DATA ATTRIBUTES HERE }) + b.text 
+0

に行く場合は、この作業を見ることができますしかし、どのように動的にこれを行うことができますか? ... – andrewdotnich

+1

b.objectはコレクションの個々の要素なので、{identifier:b.object.identifier}などのデータをグループ内の各チェックボックスに与えます。アトリビュート(input_htmlに入れた場合は、すべて同じ値と反対です) –

+0

まず、1年半の応答遅れで申し訳ありません! 私はこの答えが一番好きです。書くことができる余分なRuby&JSコードがあるにもかかわらず、とてもシンプルです。私はそれをテストしていません(私は長い間、そのプロジェクトと雇用者の両方から移ってきました)が、それがうまくいくと仮定すると、各要素のロボットのリストをデータ要素に入れておくと意味があり、と対戦する。ありがとうございました! – yoz

0

SimpleFormの一部の入力オプションは、コレクション内のすべての項目に対して呼び出されるラムダ受け入れる:

f.input :role_ids, :collection => (1..10).to_a, 
    :label_method => :to_i, :value_method => :to_i, 
    :as => :check_boxes, :required=> true, 
    :disabled => ->(item){ item.even? } 

をしかしinput_htmlありませんそれらの1つと思われる。

おそらく解決策は、データ属性自体を適用するカスタムSimpleFormコレクション入力を作成することです。多分柔軟ではないかもしれませんが、私はこれが今のところ行くための唯一の方法だと思います。

There's a tutorial page on GitHubこれは、あなたを始めてくれるはずです。

9

フォームがOrderモデル用で、regionというフィールドの値に基づいてpartsコレクションを変更しているとします。

フォームビューを更新します。フォームのIDはregionフィールド、partsフィールドを指定します。

= simple_form_for(@order, :html => { :id => "order-form"}) do |f| 
    = f.input :region, :wrapper_html => { :id => "order-form-region",      | 
     "data-parts-url" => parts_orders_path(:id => @order.id, :region => @order.region)} | 

    = f.input :parts, as: check_boxes, collection: @parts_list,       | 
     :wrapper_html => { id' => 'parts-check-box-list'}         | 

route.rbファイルにpartsと呼ばれる新しいアクションを追加します。

resources :orders do 
    collection do 
    get :parts 
    end 
end 

$('#parts-check-box-list').replaceWith('<%= j(parts_collection(@order, @parts_list)) %>'); 

登録データ(orders/parts.js.erb)アクションのためのJSビューを追加ヘルパー

def parts_collection(order, parts_list) 
    "".tap do |pc| 
    # to generate the markup for collection we need a dummy form 
    simple_form_for(order) do |f| 
     pc << f.input(:parts, as: check_boxes, collection: parts_list, 
     :wrapper_html => {:id => 'parts-check-box-list'}) 
    end 
    end 
end 

を追加するには、コントローラに

class OrdersController < ApplicationController 

    # expects id and region as parameters 
    def parts 
    @order = params[:id].present? ? Order.find(params[:id]) : Order.new 
    @parts_list = Part.where(:region => params[:region]) 
    end 
end 

を新しいアクションを追加します。変更イベントあなたのapplication.js

$(document).ready(function() { 
    $('#order-form').on("change", "#order-form-region", function() { 
    // Access the data-parts-url set in the region field to submit JS request 
    $.getScript($(this).attr('data-parts-url')); 
    }); 
}); 
+0

コードの不具合を修正しました。 –

+0

まず、1年半のお返事遅れて申し訳ありません!これは完全な答えです。素晴らしいです。ありがとうございました! 最終的に私はShuo Chenの答えに行きました - その不完全さにもかかわらず、AJAXを使わずに、私が本当に簡単な方法でページに必要なものすべてを手に入れることができることを示しています。しかし、私の特定の状況よりも複雑なものについては、あなたは行くべき素晴らしい方法のように見え、私は将来何かのためにそれが必要になると確信しています。ありがとうございました! – yoz

1

regionフィールドのハンドラは、これは単純かもしれません。

仮定

@robots - an array containing the list of robots 
@parts - a hash containing a list of parts for each robot 

サンプルコード

# controller 
@robots = %w[tracker nontracker] 
@parts = { tracker: %w[wheels lcd resistor], nontracker: %w[lcd resistor] } 

# view 
= f.input :robots, as: :select, collection: @robots, input_html: { id: 'robot-select' } 

#parts-list 

:javascript 
    var parts = #{@parts.to_json}; 

    $(document).ready(function() { 
    $('#robot-select').change(function() { 
     $('#parts-list').html(''); 

     $(parts[$(this).val()]).each(function(index, text) { 
     $('#parts-list').append('<input type="checkbox" value=' + text + '>' + text + '</input>') 
     })   
    }) 
    }) 

あなたがhttps://github.com/jvnill/simple_form_search_appのクローンを作成し、/robots

+0

まず、1年半のお返事遅れて申し訳ありません!私はこのコードがどれほどシンプルなのか、とても小さいです。私が好きでないのは、クライアント側でフォームのチャンクを構築していることです。チェックボックスには、パーツの正しい名前を付ける必要があります。でもありがとう! – yoz

関連する問題