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_selectoption_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 %>