simpleform simple_form_for simple rails form example collection ruby-on-rails simple-form

ruby-on-rails - example - simple_form_for rails 5



¿Cómo agrego atributos HTML para seleccionar opciones con Simple Form Rails? (4)

Necesito agregar un atributo HTML personalizado a cada option para un control de select . Estoy usando simple_form en Rails. ¿Alguien sabe como hacer esto? El atributo será consumido por el cliente JS.

Por ejemplo, quiero hacer algo como esto:

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

Lo que produciría (simplificado):

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

Donde @groups pueden verse así:

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

Con la esperanza de evitar tener que hacer un control / envoltorio personalizado. ¡Gracias!


¡Usted está cerca! La forma más fácil es en realidad no utilizar simple_form aquí. Aquí está la documentación de 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 %>

Para su código exacto sería:

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



Un (pequeño) inconveniente de usar el método f.input do end es que todas las opciones html de entrada predeterminadas (como las clases required u optional del formulario simple o el atributo required ) y las opciones predeterminadas (como b.use :input, class: ''input-element'' ) faltan cuando simplemente se pasa un bloque a f.input , tldr: la entrada no se decora .

Si confía en estas clases y atributos adicionales, tendría que pasarlos manualmente (no en seco).

Para superar esto, he creado una entrada personalizada para mis selecciones especiales, por lo que puedo definir el cuerpo de mi selección como quiero (las etiquetas <option> ) pero la selección se decora como de costumbre:

# 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

Simplemente llámalo así:

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

El options_html es una solución, porque en realidad sería más fácil pasar un bloque a nuestra entrada personalizada:

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

Pero debido a la forma en que funciona SimpleForm::FormBuilder#def_input , el bloque se deja llevar incluso antes de que el código toque las entradas. Así que de ninguna manera sin refactorizar simple_form.

Todo esto resuelve el problema con un poco más de código ruidoso en sus vistas para sus selecciones especiales.


sólo forma simple:

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