Rails 生成带有选项和选项组的 select

Rails generate select with both options and option groups

是否可以生成 select 如:

<select>
  <option value>Some nill value label</option>
  <option value="1">Option one</option>
  <optgroup label="Option Group 1" class="css-class-for-option-group-1">
    <option value="1:1">Option one in group 1</option>
    <option value="1:2">Option two in group 1</option>
  </optgroup>
  <optgroup label="Option Group 2" class="css-class-for-option-group-2">
    <option value="2:1">Option one in group 2</option>
    <option value="2:2">Option two in group 2</option>
  </optgroup>
</select>

我尝试使用 grouped_options_for_select,但我找不到将选项和组都传递给它的方法。有什么办法可以做到这一点?我也愿意接受使用 SimpleForm 的建议。

谢谢!

如果不知道数据是什么样子,很难准确回答这个问题,但我猜你有这样的东西:

@grouped_options = [
  ["Some nil value label"],
  ["Option one", "1"],
  ["Option Group 1",
    [
      ["Option one in group 1", "1:1"],
      ["Option two in group 1", "1:2"],
    ]
  ],
  ["Option Group 2",
    [
      ["Option one in group 2", "2:1"],
      ["Option two in group 2", "2:2"],
    ]
  ],
]

有了这个,你有几个选择。在普通的 ERB 中,你可以这样做:

<%= select "thing", "some_attr" do %>
  <% @grouped_options.each do |label, value_or_options| %>
    <% if Array === value_or_options %>
      <%= tag.optgroup options_for_select(value_or_options), label: label %>
    <% else %>
      <%= tag.option label, value: value_or_options %>
    <% end %>
  <% end %>
<% end %>

不过,就我个人而言,我会编写一个帮助程序。 Enumerable#chunk 方法将一个数组分成一系列值,这些值 return 对于给定块来说是相同的,这样可以很容易地将分组与 non-grouped 项分开,因此我们可以使用 grouped_options_for_selectoptions_for_select,分别是:

def ungrouped_and_grouped_options_for_select(choices, selected_key = nil)
  capture do
    choices
      .chunk {|_, choice_or_group| Array === choice_or_group }
      .each do |is_group, choices_or_grouped_choices|
        if is_group
          concat grouped_options_for_select(choices_or_grouped_choices, selected_key)
        else
          concat options_for_select(choices_or_grouped_choices, selected_key)
        end
      end
  end
end

然后您可以这样使用它:

<%= select "thing", "some_attr" do %>
  <%= ungrouped_and_grouped_options_for_select(@grouped_options) %>
<% end %>

您可以在 repl.it 上看到这两种方法的实际应用:https://repl.it/@jrunning/UnacceptablePlaintiveServer(请参阅 views/tests/index.html.erbcontrollers/tests_controller.rbhelpers/application_helper.rb)。

假设数据按照 Jordan 的描述进行格式化,您还可以通过对它们的 return 求和来组合两种 'select options' 方法(options_for_selectgrouped_options_for_select),例如所以:

<%= f.select :selected_ids, options_for_select([['Option 1', 1]]) + grouped_options_for_select([['Option Group 1', ['group1opt1', 11], ['group1opt2', 12]], ['Option Group 2', ['group2opt1', 21], ['group2opt2', 22]]]), {}, { class: 'class' } %>