grouped_collection_select accepts nine parameters, including an options attribute. How do you add a custom attribute in options, a data tag, to be used when an option is selected?
The select is coded as of now as:
= f.grouped_collection_select :course_id, Discipline.order(:name), :courses, :name, :id, :display
I want to add a custom data attribute so that the output is like:
<select id="enrollment_course_id" name="enrollment[course_id]">
<option selected="selected" value="7" data-duration=8>Introduction to Guitar (8 weeks)</option>
<option value="8" data-duration=8>Strings 1-3 (8 weeks)</option>
<option value="9" data-duration=10>Strings 4-6 (10 weeks)</option>
<option value="10" data-duration=12>Basic Chords (12 weeks)</option>
</select>
How do we generate the custom attribute programmatically?
There seems to be no nice and properly documented way to do this.
Solution 1. use non fully documented features of grouped_collection_select:
f.grouped_collection_select :course_id, Discipline.order(:name), :courses_with_duration_data, :name, ->(el){el.first.id}, ->(el){el.first.display}
Where you need to implement courses_with_duration_data like this:
class Discipline
has_many :courses
def courses_with_duration_data
courses.map {|course| [course,{data: {duration: course.duration}}]}
end
end
It relies on that if you pass array of arrays to options_for_select the hash within the arrays will be treated as html options.
It has a disadvantage of putting view related methods to your model. And it something that might break with future rails releases as this use is not documented on grouped_collection_select, so you're probably better of generating the options yourself.
Solution 2. Reimplement options yourself:
Reimplement custom option_groups_from_collection_for_select in a helper. This could look something like this:
def options_for_disciple_with_courses(disciplines)
disciplines.map do |discipline|
option_tags = options_for_select(
discipline.courses.map {|course| [course.display, course.id, {data: {duration: course.duration}}]}
)
content_tag(:optgroup, option_tags, label: discipline.name)
end.join.html_safe
end
And your view would became:
f.select :course_id, options_for_disciple_with_courses(Discipline.order(:name))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With