Skip to main content
Ask A Question
Notifications
You’re not receiving notifications from this thread.
Subscribe

How do I build a dynamic drop down menu in Rails with Simple Form?

Rails • Asked by Steve

I would like some help on how to build a dynamic dropdown menu with Rails Simple form.

I'm really new to programming so any help will be appreciated.

Many Thanks,

SS

Here is my Simple Form code.

  <%= f.input :country :  collection: ["Canada", "United States"] %>
  <%= f.button :submit %>

Here's is some code in HTML and JS. This works, but I was wondering if Rails can do something similar.

  <script>
    function select_countries(selectElem) {
      var regionCode = selectElem.options[selectElem.selectedIndex].value;

      if (regionCode == 'us') {
        document.getElementById("us_region").style.display = 'block';
        document.getElementById("ca_region").style.display = 'none';
      } else if (regionCode == 'can') {
        document.getElementById("ca_region").style.display = 'block';
        document.getElementById("us_region").style.display = 'none';
      }
    }

      function select_region(selectElem) {
        var cityCode = selectElem.options[selectElem.selectedIndex].value;

        if (cityCode == "on") {
            document.getElementById("on_cities").style.display = 'block';
            document.getElementById("qc_cities").style.display = 'none';

          } else if (cityCode == "qc") {
            document.getElementById("qc_cities").style.display = 'block';
            document.getElementById("on_cities").style.display = 'none';

          } else if (cityCode == "ny") {
            document.getElementById("ny_cities").style.display = 'block';
            document.getElementById("ca_cities").style.display = 'none';
          } else if (cityCode == "ca") {
            document.getElementById("ca_cities").style.display = 'block';
            document.getElementById("ny_cities").style.display = 'none';
          }
        }

  </script>

  <body>

      <form name="form1" method="post" action="">
          <p>
          <label for="countries">Countries:</label>
          <select id="countries" name="countries" onChange="select_countries(this);">
          <option disabled selected value>No Country Selected</option>
          <option value="can">Canada</option>
          <option value="us">United States</option>
          </select>
          </p>

          <p id="ca_region">
          <label for="provinces">Provinces:</label>
          <select id="provinces" name="provinces" onChange='select_region(this);'>
          <option disabled selected value>No Province Selected</option>
          <option value="on">Ontario</option>
          <option value="qc">Quebec</option>
          </select>
          </p>

          <p id="us_region">
          <label for="states">States:</label>
          <select id="states" name="states" onChange='select_region(this);'>
          <option disabled selected value>No State Selected</option>
          <option value="ny">New York</option>
          <option value="ca">California</option>
          </select>
          </p>

          <p class="cities" id="on_cities">
          <label for="on_cities">Cities:</label>
          <select id="on_cities" name="on_cities" onChange='select_cities("on_cities");'>
          <option value="hamilton">Hamilton</option>
          <option value="toronto">Toronto</option>
          </select>
          </p>

          <p class="cities" id="qc_cities">
          <label for="qc_cities">Cities:</label>
          <select id="qc_cities" name="qc_cities" onChange='select_cities("qc_cities");'>
          <option value="montreal">Montreal</option>
          <option value="quebec">Quebec City</option>
          </select>
          </p>

          <p class="cities" id="ny_cities">
          <label for="ny_cities">Cities:</label>
          <select id="ny_cities" name="ny_cities" onChange='select_cities("ny_cities");'>
          <option value="newyork">New York City</option>
          <option value="albany">Albany</option>
          </select>
          </p>

          <p class="cities" id="ca_cities">
          <label for="ca_cities">Cities:</label>
          <select id="ca_cities" name="ca_cities" onChange='select_cities("ca_cities");'>
          <option value="losangeles">Los Angeles</option>
          <option value="sanfrancisco">San Francisco</option>
          </select>
          </p>

        </form>

Hey Stephen!

Rails doesn't have anything built-in to support this kind of feature. It doesn't make many decisions on how you should handle the frontend for you which makes sense since it's a backend framework more or less.

As far as what you've got, I'd say it's definitely not bad. There are some improvements you could make by having it become more dynamically created.

For example, you could store a Hash of all the data in Javascript or somewhere in the HTML and load that up into the JS. Once you had the data in an object in JS, you can then dynamically create the select options and everything from there. An example of that would look something like this: http://stackoverflow.com/a/6601129/277994 Yours would need to be a little more complex because you have different groups of data to show, but the concept is similar.

You can imagine having an object in JS that looks like this full of data (you could structure this any way you wanted):

var regions = {
  "us": {
      "name": "United States",
        "states": [
          "ca": {
              "name": "California",
                "cities": {
                  "losangeles": "Los Angeles",
                    "sanfrancisco": "San Francisco"
        }
          }
        ]
    }
}

And if you had all the data like this, you could then grab out portions of it to fill out your fields. Such as you could gather all the name values of the top level regions to populate the region select. Once a region was selected, you could grab the states from it and populate the state/province level from there and so on.

It would require a lot of work to change, so don't feel like you need to clean it up right away. You can always improve this code later once it's working.


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 31,353+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.