simple_form - 无法生成组合选择输入

时间:2015-03-13 11:07:16

标签: ruby simple-form

我有很多控件的复杂形式,由于其灵活性,我目前正在使用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

1 个答案:

答案 0 :(得分:2)

使用您当前的设计,您可以将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 %>