我需要为option
控件的每个select
添加自定义HTML属性。我在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']
]
希望避免制作自定义控件/包装器。谢谢!
答案 0 :(得分:18)
你关闭了!最简单的方法实际上不是在这里使用simple_form。这里是simple_form documentation
<% 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 %>
答案 1 :(得分:6)
仅限简单形式:
= f.input :group, @groups.map{|l| [l[0], l[1], {data: {type: l[2]}}]}
答案 2 :(得分:1)
使用f.input do end
方法的一个(小)缺点是任何默认输入html选项(例如简单形式的required
或optional
类或required
属性简单地将一个块传递给b.use :input, class: 'input-element'
, tldr:输入没有被装饰时,任何默认选项(如f.input
)都会丢失。
如果你依赖这些额外的类和属性,你必须手动传递(不干)。
为了克服这个问题,我已经为我的特殊选择创建了一个自定义输入,所以我可以像我想要的那样定义我的选择的主体(<option>
标签),但是select会像往常一样进行装饰: / p>
# 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就没办法。
总而言之,这为您的特殊选择在视图中添加了一些额外的嘈杂代码解决了这个问题。
答案 3 :(得分:0)
这似乎是这样做的正确方法:
答案 4 :(得分:0)
对于关联,请选择:
f.association :product, collection: Product.all.map { |product| [product.name, product.id] }