Подтвердить что ты не робот

Как добавить атрибуты HTML для выбора опций с помощью Simple Form Rails?

Мне нужно добавить собственный атрибут HTML для каждого option для элемента управления select. Я использую simple_form в Rails. Кто-нибудь знает как это сделать? Атрибут будет потребляться клиентской стороной JS.

Например, я хочу сделать что-то вроде этого:

<%= f.input :group, collection: @groups, option_html: { data-type: lambda { |g| g[2] } } %>

Что создаст (упрощен):

<select>
    <option value="1" data-type="primary">First Group</option>
    <option value="2" data-type="secondary">Second Group</option>
    <option value="3" data-type="secondary">Third Group</option>
</select>

Где @groups может выглядеть так:

[
    ['First Group', 1, 'primary'],
    ['Second Group', 2, 'secondary'],
    ['Third Group', 3, 'secondary']
]

В надежде избежать необходимости создавать настраиваемый элемент управления/обертку. Спасибо!

4b9b3361

Ответ 2

Ты рядом! Самый простой способ на самом деле здесь не использовать simple_form. здесь документация simple_form

<% options = @group.map { |g| [g.name, g.id, {'data-type' => g.group_type}] } %>
<%= f.input :group, label: 'Group' do %>
  <%= f.select :group, options, include_blank: 'Select a Group', class: 'form-control' %>
<% end %>

Для вашего точного кода это будет:

<% options = @group.map { |g| [g[0], g[1], {'data-type' => g[2]}] } %>
<%= f.input :group, label: 'Group' do %>
  <%= f.select :group, options, include_blank: 'Select a Group', class: 'form-control' %>
<% end %>

Ответ 3

только в простой форме:

= f.input :group, @groups.map{|l| [l[0], l[1], {data: {type: l[2]}}]}

Ответ 4

A (малый) недостаток с использованием метода f.input do end заключается в том, что любые параметры ввода html по умолчанию (например, простые формы required или optional) или атрибут required) и любые параметры по умолчанию (например, b.use :input, class: 'input-element') отсутствует при простом передаче блока f.input, TL;DR: вход не оформляется.

Если вы полагаетесь на эти дополнительные классы и атрибуты, вам придется вручную передать их (не сушите).

Чтобы преодолеть это, я создал пользовательский ввод для своих специальных выборок, поэтому я могу определить тело моего выбора, как я хочу (теги <option>), но выбор будет оформлен как обычно:

# app/inputs/select_container_input.rb
class SelectContainerInput < SimpleForm::Inputs::Base 
  def input(wrapper_options)
    options_html = input_options.delete(:options_html)

    # since we pass our options by our self (and have to select the correct
    # option), set `selected` to `''` to prevent rails calling
    # `object.send(attribute_name)` only to set `selected` which is not used.
    input_options[:selected] = ''    

    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
    @builder.select attribute_name, nil, input_options, merged_input_options do
      options_html
    end
  end
end

Просто назовите его так:

<% options_html = capture do %>
  <option>bla</option>
<% end %>
<%= f.input :attribute, as: :select_container, options_html: options_html %>

options_html - это обходной путь, потому что на самом деле было бы легче перейти в блок к нашему пользовательскому вводу:

<%= f.input :attribute, as: :select_container do %>
  <option>bla</option>
<% end %>

Но из-за способа SimpleForm:: FormBuilder # def_input работает, блок увлекается, прежде чем код даже коснется входов. Таким образом, нет способа без реорганизации simple_form.

В целом это решает проблему с немного более шумным кодом в ваших представлениях для ваших специальных выборов.

Ответ 5

Для ассоциации выберите:

f.association :product, collection: Product.all.map { |product| [product.name, product.id] }