Rafał Jaroszewicz

Create dynamic dependant dropdowns with Javascript in Rails 6.1.4

a gif showing final effect
What we want to do here

I managed to pull this stunt off in an app I’m working on. Let’s say we want to have a payment module. On top of the form we have three dropdowns. To make things easier for the user, I want these dropdowns to be dependant, so first I choose the building, then another dropdown only server me flats that actually belong to the building and finally after choosing a flat, I will only be able to choose tenant that is living there.

Key points:

  1. Flat and Tenant dropdowns are empty until previous dropdown has changed.
  2. After Building and Flat dropdown change, I want to fetch the data for next dropdown.
  3. I want to use the data from fetch to fill out dropdowns.

I’m setting up my arrays in the controller so I can access all the data in my view.

Now, if I want to fetch any data from the server I will need an endpoint that will allow me to access the data in JSON format so I can easily parse it and fill my dropdowns with it.
First, I create entries in my config/routes.rb file.

That will reflect my actions in controllers:

Now that I have my backend setup, I can proceed with the front.

Here I have my dropdowns that I need to fill out dynamically.

At the time of writing this post, Rails 7 has already been released, but I already started my app in 6.1.4 and managed to understand a fraction of webpacker so I decided to stick with it. My JS code is inside javascript folder.
app/javascript/forms/fetch_building_data.js

Also, I added the require statement in application.js
require('forms/fetch_building_data')

Here, I load my variables as soon as turbolinks:load is finished. That’s the correct way of adding this handler, because if you try to add DOMContentLoaded or load it won’t work. Rails way🛤.

Because I’m also using this script on Tenants view used to create them to have only two dropdowns (for Building and Flat) I have bundled this code into one file.
Now, first of all I set up length of dependant select tags to 1, that way only my placeholder will be available until you actually choose something. The rest of the function takes care of collecting the input from the dropdown
buildingSelect.addEventListener('input', function (event)
and storing it let buildingId = event.target.value
Functions at the bottom create options for my select and append them.

That’s it.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top