34

optionコントロールのそれぞれにカスタム HTML 属性を追加する必要がありますselect。Rails で simple_form を使用しています。誰もこれを行う方法を知っていますか? 属性は、クライアント側の JS によって消費されます。

たとえば、次のようなことをしたい:

<%= f.input :group, collection: @groups, option_html: { data-type: lambda { |g| g[2] } } %>

どちらが生成されますか (簡略化):

<select>
    <option value="1" data-type="primary">First Group</option>
    <option value="2" data-type="secondary">Second Group</option>
    <option value="3" data-type="secondary">Third Group</option>
</select>

@groupsのようになります。

[
    ['First Group', 1, 'primary'],
    ['Second Group', 2, 'secondary'],
    ['Third Group', 3, 'secondary']
]

カスタム コントロール/ラッパーを作成する必要がないようにしたいと考えています。ありがとう!

4

5 に答える 5

23

あなたは近いです!最も簡単な方法は、実際にはここで simple_form を使用しないことです。ここにsimple_formのドキュメントがあります

<% options = @group.map { |g| [g.name, g.id, {'data-type' => g.group_type}] } %>
<%= f.input :group, label: 'Group' do %>
  <%= f.select :group, options, include_blank: 'Select a Group', class: 'form-control' %>
<% end %>

正確なコードの場合は次のようになります。

<% options = @group.map { |g| [g[0], g[1], {'data-type' => g[2]}] } %>
<%= f.input :group, label: 'Group' do %>
  <%= f.select :group, options, include_blank: 'Select a Group', class: 'form-control' %>
<% end %>
于 2015-01-16T00:47:33.553 に答える
1

メソッドを使用する (小さな) 欠点は、単にブロックをtldr: に渡すだけf.input do endで、デフォルトの入力 html オプション (単純なフォームrequiredoptionalクラス、required属性など) とデフォルト オプション ( などb.use :input, class: 'input-element') が欠落していることです: 入力は装飾されませんf.input

これらの追加のクラスと属性に依存する場合は、それらを手動で渡す必要があります (ドライではありません)。

これを克服するために、特別な選択用のカスタム入力を作成したので、必要に応じて選択の本体 (<option>タグ) を定義できますが、選択は通常どおり装飾されます。

# app/inputs/select_container_input.rb
class SelectContainerInput < SimpleForm::Inputs::Base 
  def input(wrapper_options)
    options_html = input_options.delete(:options_html)

    # since we pass our options by our self (and have to select the correct
    # option), set `selected` to `''` to prevent rails calling
    # `object.send(attribute_name)` only to set `selected` which is not used.
    input_options[:selected] = ''    

    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    @builder.select attribute_name, nil, input_options, merged_input_options do
      options_html
    end
  end
end

次のように呼び出すだけです。

<% options_html = capture do %>
  <option>bla</option>
<% end %>
<%= f.input :attribute, as: :select_container, options_html: options_html %>

これoptions_htmlは回避策です。実際には、ブロックをカスタム入力に渡す方が簡単だからです。

<%= f.input :attribute, as: :select_container do %>
  <option>bla</option>
<% end %>

しかし、SimpleForm::FormBuilder#def_inputの動作方法により、コードが入力に触れる前にブロックが取り除かれます。そのため、simple_form をリファクタリングせずにはいられません。

全体として、これにより、特別な選択のためにビューに少し余分なノイズの多いコードが含まれる問題が解決されます。

于 2016-01-16T14:17:08.057 に答える
0

これはこれを行う正しい方法のようです:

Rails Simple Form カスタム関連付け選択フィールド

于 2013-07-09T18:17:00.147 に答える