我有很多控件的复杂形式,由于其灵活性,我目前正在使用simple_form gem。但是当我想做一些更复杂的事情时,我遇到了一些目前看起来模糊不清的问题。我想介绍组合集合输入,它将呈现optgroups和单个非分组选择。我想要实现的生成的html应该是这样的:
<select name="select" multiple="multiple">
<option value="1">Milk</option>
<optgroup label="Soda">
<option value="2">Cola</option>
<option value="3">Fanta</option>
</optgroup>
</select>
我已经尝试创建自定义输入类,但是坚持input
方法的实现细节,我根本无法找到如何生成正确的输出。
更新
目前,自定义输入的快速和脏实现看起来像这样,但我不认为放弃所有goodness以及simple_form给我的选项是个好主意。
class CombinedMultiselectInput < SimpleForm::Inputs::CollectionSelectInput
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
def input
out = ActiveSupport::SafeBuffer.new
option_tags = ungrouped_options.safe_concat(grouped_options)
out << select_tag(options[:name], option_tags, class: ['select', 'form-control'])
out
end
private
def ungrouped_options
# this can be retrieved from general collection like collection[:ungrouped]
collection = [["Foo", 2], ["Bar", 3]]
options_for_select(collection)
end
def grouped_options
# and this using collection[:grouped]
collection = [["Group", [["Foobar", 4]]]]
grouped_options_for_select(collection)
end
end
答案 0 :(得分:2)
使用您当前的设计,您可以将options_for_select
和option_groups_from_collection_for_select
方法结合起来。
def ungrouped_options
[["Foo", 2], ["Bar", 3]]
end
def grouped_options
[["Group", [["Foobar", 4]]]]
end
def your_hash
{"ungrouped" => ungrouped_options, "grouped" => grouped_options}
end
然后在您看来,这样的事情应该有效:
<%= content_tag(:select,nil,{multiple: true,name: "select"}) do
<%= your_hash.each do |k,v| %>
<% if k == "ungrouped" %>
<%= options_for_select(v) %>
<% else %>
#this works because:
# last will be the collection of children for a member
# first will be the group name
# last on the child will be the value method
# first on the child will be the text displayed
<%= option_groups_from_collection_for_select(v, :last, :first, :last, :first) %>
<% end %>
<% end %>
<% end %>
这将创建以下内容:
<select name=\"select\" multiple=\"true\">
<option value=\"2\">Foo</option>
<option value=\"3\">Bar</option>
<optgroup label=\"Group\">
<option value=\"4\">Foobar</option>
</optgroup>
</select>
显然,这是简化的,以显示如何做到这一点,但希望这可以指出你正确的方向。
你也应该能够为simple_form包装它,尽管我还没有测试过它。
<%= f.input :some_attribute do %>
<%= f.select :some_attribute do %>
<%= your_hash.each do |k,v| %>
<% if k == "ungrouped" %>
<%= options_for_select(v) %>
<% else %>
<%= option_groups_from_collection_for_select(v, :last, :first, :last, :first) %>
<% end %>
<% end %>
<% end %>
<% end %>