HTML Selectbox Updating With Javascript and Dynamic Ruby

The Goal

You’re making a form with 2 selectboxes: based on the user’s selection in the first box, the second box updates. A possible use is an interactive menu with a selectbox (drink, appetizer, dessert), and a second selectbox that updates (coffee, juice, tea — if you select drink).

How do we write the HTML, Ruby, CSS, and Javascript to make it work?

HTML & Javascript Overview

Use the .change() jQuery method as the event listener for the first selectbox. Based on the name attribute of option selected, use CSS to reveal the correct set of 2nd-selectbox options.

I created a .hide {display: none;} CSS rule and applied it to all 2nd-selectbox options. For these same selectboxes, I gave them the same ID as the name attribute of the matching option of the first selectbox.

Furthermore, I used Ruby and ERB to grab “Subjects” and “Details” from my database. In the code below, Detail belongs_to :subject, and Subject has_many :details.

See the Javascript and HTML code below:

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<h3>Pick your subject:</h3>

<select id="first-selectbox">
  <option value="" name="select-one">Select One</option>
<% Subject.list.each do |subject| %>
  <option value=<%= cssable(subject) %> name="<%= cssable(subject) %>"><%= subject.titleize %></option>
<% end %>
</select>

<h3>Pick your detail:</h3>

<select class="show" id="no-details">
  <option value="">Select One</option>
</select>

<% @subjects.each do |subject| %>
  <select class="hide" id="<%= cssable(subject.title) %>">
    <option value="">Select One</option>
  <% subject.detail_list.each do |detail| %>
    <option value="<%= detail %>">
      <%= detail.titleize %>
    </option>
  <% end %>
  </select>
<% end %>

Javascript

1
2
3
4
5
6
7
8
9
10
11
jQuery(function(){
  $( "#first-selectbox" ).change(function() {
    var detail_id = ( "#" + $( "#first-selectbox option:selected").attr('name').toLowerCase() );
    $( ".show").addClass("hide");
    $( detail_id ).removeClass("hide").addClass("show");
    
    if (detail_id === "#select-one") {
      $( "#no-details" ).removeClass("hide").addClass("show");
    }
  });
});

Cross the Ts: Getting the Ruby and HTML Details Right

As you can see, the actual code is a lot more complex than the overview. This is because:

  1. I made a default selectbox for the 2nd selectbox, which requires some fandangaling to handle because it falls outside of the “subject equals 2nd selectbox id” pattern.
  2. I created my own methods (subject.detail_list and Subject.list) to return a list of associated subjects and details, to avoid making unnecessary queries to the database.
  3. I created a view helper cssable(string) to make subjects longer than one word, like “Main Course,” separated by dashes, like “main-course,” so that the value could be captured in HTML.

Conclusion

Updating selectbox selections is a straightforward concept that nonetheless requires some attention to detail to get working perfectly. My approach was to get the basic concept working (as can be found in this JS Fiddle), then to make it work in my actual application.