simple_form - 无法生成组合 select 输入
simple_form - can't generate combined select input
我的表单很复杂,有很多控件,我目前正在使用 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>
我已经尝试创建自定义输入 class,但卡在 input
方法的实现细节上,我根本找不到如何生成正确的输出。
更新
目前自定义输入的快速和肮脏的实现看起来像这样,但我不认为放弃所有优点 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
使用您当前的设计,您可以像这样组合 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 %>
我的表单很复杂,有很多控件,我目前正在使用 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>
我已经尝试创建自定义输入 class,但卡在 input
方法的实现细节上,我根本找不到如何生成正确的输出。
更新
目前自定义输入的快速和肮脏的实现看起来像这样,但我不认为放弃所有优点 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
使用您当前的设计,您可以像这样组合 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 %>