Home > Enterprise >  How to include both a class and data attributes in a form select in Rails 7?
How to include both a class and data attributes in a form select in Rails 7?

Time:07-25

In my Rails 7 app, I am using Stimulus and need to add data attributes to a form select to link it to a JavaScript controller. I am also trying to format the field (not the options) with a class.

Here is the form select element:

<%= f.select(:repeat, Batch.repeats, {class: "class_name"}, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}) %>

The above code results in the data attributes being applied to the select field, but leaving the class out.

I also tried to flip the class and the data attributes, as follows:

<%= f.select(:repeat, Batch.repeats, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}, { class: "class_name" }) %>

The result was the opposite of the first approach: this time, the field was styled per the class, but the data attributes were not associated with the select element.

Per this question, I became aware that:

select helper takes two options hashes, one for select, and the second for html options. So all you need is to give default empty options as first param after list of items and then add your class to html_options.

From there, I thought that I needed to include both the class and the data attributes in the first option hash, and leave the second one empty, along the following lines:

<%= f.select(:repeat, Batch.repeats, { { class: "class_name" }, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}}, {}) %>

However, the above revised code resulted in an ActionView::SyntaxErrorInTemplate in BatchesController#new error.

In yet another attempt, I tried to shuffle things around, leaving the first option hash empty and including both the class and the data attributes in the second one, as follows:

<%= f.select(:repeat, Batch.repeats, {}, { { class: "class_name" }, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}}) %>

That revision also resulted in an ActionView::SyntaxErrorInTemplate in BatchesController#new error.

The question referenced above is more than 11 years old and: is there a different convention now, particularly in Rails 7, with regards to form select elements? How can I both include a class and data attributes here?

CodePudding user response:

A hash looks like this: { key1: value1, key2: value2 }

So, take your attempted code: { { class: "class_name" } } - the inner hash there is { class: "class_name" } so let's assign that to a variable: value1 = { class: "class_name" } and then let's use that variable in your attempted code: { value1 }

See how that's not a hash, there's no key for the value. A hash must always have keys and values. This is why you're getting the syntax errors in your second two examples.

So let me go through your other two attempts:

<%= f.select(:repeat, Batch.repeats, {class: "class_name"}, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}) %>

So here, :repeat is the first argument, Batch.repeats is the second, the third argument (which is the select options) is the hash with a single key/value pair: { class: "class_name" }, and the fourth argument (which is the html options) is the hash with a single key/value pair: { data: { the: data, hash: here }

Your second attempt:

<%= f.select(:repeat, Batch.repeats, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}, { class: "class_name" }) %>

First two arguments the same, the third argument (the select options) is now the hash with the :data key/value, and the fourth argument (the html options) is now the hash with the single :class key/value.

What you want to do is provide an empty hash for the third argument (the select options), and then a hash with TWO key/value pairs for the fourth argument (the html options):

{ class: "class_name", data: { the: data, hash: here } }

(Note, I intentionally didn't feed you the full answer, because I feel that you're the sort of person who will benefit from discovering it on your own, but say so if I've misjudged, happy to edit this answer if you need it)

  • Related