Is it possible to generate select like:
<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>
I tried to use the grouped_options_for_select
, but I failed to find I way to pass both option and groups to it. Is there any way to achieve this? I am open to suggestions using SimpleForm as well.
Thanks!
This is hard to answer precisely without knowing what the data looks like, but I'm going to guess that you have something like this:
@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"],
]
],
]
With that, you have a couple options. In plain ERB, you can do it like this:
<%= 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 %>
Personally, though, I would write a helper. The Enumerable#chunk
method splits an array into runs of values that return the same thing for the given block, making it easy to separate the grouped from the non-grouped items so we can use grouped_options_for_select
and options_for_select
, respectively:
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
You could then use it this:
<%= select "thing", "some_attr" do %>
<%= ungrouped_and_grouped_options_for_select(@grouped_options) %>
<% end %>
You can see both of these approaches in action on repl.it: https://repl.it/@jrunning/UnacceptablePlaintiveServer (see views/tests/index.html.erb
, controllers/tests_controller.rb
, and helpers/application_helper.rb
).