Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add class to Rails select form helper when using as a block

The documentation for Rails select form helper states (see documentation):

select(object, method, choices = nil, options = {}, html_options = {}, &block)

Which allows adding a class simple, like so:

<%= f.select :some_attr, MYOPTIONS, {}, {class: 'my-class'} %>

My question is, how do I add a class to it when using it as a block? Rails documentation states:

select(report, "campaign_ids") do
  available_campaigns.each do |c|
    content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json })
  end
end

It doesn't work when I use it like so:

<%= f.select :some_attr, {}, {class: 'my-class'} do %>
  <% MYOPTIONS.each do |MYOPTION| do %>
    <%= content_tag :option, MYOPTION.label, value: MYOPTION.value %>
  <% end %>
<% end %>

Nor does it work if I use:

f.select :some_attr, class: 'my-class' do

The class is not applied to the select tag in the HTML.

like image 790
user1647525 Avatar asked May 08 '16 00:05

user1647525


2 Answers

I solved my own problem, although I don't fully understand the answer, so if someone else understands this better, I'd love to hear your answer.

To get it to work, I simply added an additional empty hash to the beginning, like so:

<%= f.select :some_attr, {}, {}, {class: 'my-class'} do %>
  <% MYOPTIONS.each do |MYOPTION| do %>
    <%= content_tag :option, MYOPTION.label, value: MYOPTION.value %>
  <% end %>
<% end %>

The second hash is still options and the last is still html_options, so as an example, you can also add include_blank like so:

f.select :some_attr, {}, {include_blank: true}, {class: 'my-class'}

However, I don't know what the first hash is, nor what values can be passed there. I've looked at the Rails source, but I still have no clue. If you have insight into this, I'd love to hear it.

like image 97
user1647525 Avatar answered Oct 28 '22 03:10

user1647525


A couple oddities to be aware of:

In your example, you're using f.select, which you can find a reference for here: https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select

Only the first parameters is required, the rest have defaults. However, to assign that HMTL class, you had to have a value for the fourth parameter, which necessitated having something for the second and third parameters as well.

What you ended up with is a valid solution:

<%= f.select :some_attr, {}, {}, {class: 'my-class'} do %>
  <% MYOPTIONS.each do |MYOPTION| do %>
    <%= content_tag :option, MYOPTION.label, value: MYOPTION.value %>
  <% end %>
<% end %>

The block, when provided, takes precedence over the literal value (an empty hash in this case).

Surprisingly, if you were rendering this tag using select_tag instead of f.select, passing a block wouldn't be an option:

https://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag

like image 31
Nick Davies Avatar answered Oct 28 '22 03:10

Nick Davies