Rails генерируют выбор с опциями и группами опций - PullRequest
0 голосов
/ 11 июня 2019

Можно ли создать выбор как:

<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.

Спасибо!

1 Ответ

1 голос
/ 11 июня 2019

Трудно ответить точно, не зная, как выглядят данные, но я собираюсь догадаться, что у вас есть что-то вроде этого:

@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 разбивает массив на серии значений, которые возвращают одно и то же для данного блока, упрощая разделение сгруппированных и не сгруппированных элементов, поэтому мы можем использовать grouped_options_for_select и options_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.erb, controllers/tests_controller.rb и helpers/application_helper.rb).

...