Dynamic populate a select menu based on the choice of another

Updated: 29-Jan-2022 / Tags: Javascript and JSON / Views: 2801 - Author: George

Introduction

In this article we are gonna see how to dynamically populate the options of a select drop down menu depending on the choice we make on another.

Let me explain.
We have two select menus, the first menu is populated with countries, and the second menu is empty (at start). So when we choose a country in the first menu, our code (which we will write) will run and fetches the associated cities and fill the second menu.

We are going to do this with javascript and JSON. The data (countries and cities) as you will see later on, are stored in a JSON file, and from there we are going to fetch them and display them in the second drop down menu (the cities).

You can see a live demo clicking on the button bellow.

The stored data

We have a JSON file named countries.json.
In this file we have an object which has as properties the countries, and every property has an array of cities as value.
The logic here is that from the javascript file, we are going to target the country, and get the array of the cities.

{
	"England": ["London","Nottingham","Bristol","Liverpool"],
	"France": ["Paris","Lyon","Marseille","Nantes"],
	"Spain": ["Madrid","Barcelona","Bilbao","Seville"],
	"Germany": ["Berlin","Frankfurt","Cologne","Gladbach"]
}

Files we have

  • index.html (homepage) where we have our form with the two select drop down menus.
  • script.js where we have the JavaScript code.
  • And we saw above the countries.json file, where we store our data.

The index file

In the index file we have the form element with the two select menus.
In the first select menu we display the countries, and in the second select menu we are adding the cities from the javascript file.

<body>
<form>
    <select onchange="getCities(this.value)" name="countries">
        <option value="">Choose a country</option>
        <option value="England">England</option>
        <option value="France">France</option>
        <option value="Spain">Spain</option>
        <option value="Germany">Germany</option>
    </select>

    <select name="cities" id="cities" disabled>
        <option value="">Choose a city</option>
    </select>
</form>

<script src="script.js"></script> <!-- Link to the javascript file -->
  • In line 3 we have the first select menu where we have added an onchange event-listener. So every time we select an option the getCities() function will run.
    The getCities() has an argument (this.value) which means that we are targeting the selected option value.
  • In line 11 we have the second select element where we will display the cities. The element is currently disabled, we will enable it from the javascript file as soon as we select a country.
  • And in line 16 we have a link to the javascript.

The logic (Algorithm) to get the cities

  • Every time the onchange event-listener is triggered, a function will run which will send the selected value to the javascript file where we declare the getCities() function.
  • From the javascript file we send an ajax request to the server to fetch the data from the JSON file.
  • When we get the data from the server, we convert them to a javascript object so we can work with them.
  • Then base on the option (country) we selecting , we targeting the objects property to give us the cities. We saw the JSON structure above.
  • Then we loop trough the array which holds the cities, and we add them as options in the second select menu.

The javascript code

In the javascript file we will write the getCities() function.

function getCities(country){
	let citiesDropDown = document.querySelector("#cities");

	if(country.trim() === ""){
		citiesDropDown.disabled = true;
		citiesDropDown.selectedIndex = 0;
		return false;
	}

	// AJAX request with fetch()
	fetch("countries.json")
	.then(function(response){
		return response.json();
	})
	.then(function(data){
		let cities = data[country];
		let out = "";
		out += `<option value="">Choose a city</option>`;
		for(let city of cities){
			out += `<option value="${city}">${city}</otion>`;
		}
		citiesDropDown.innerHTML = out;
		citiesDropDown.disabled = false;
	});
}

Code breakdown

Lets break the javascript code down line by line.

function getCities(country){

}
  • We starting our code with the getCities() function which has the variable country as parameter. The variable country holds the selected country coming from the select menu.
    Ex. if we selecting Spain in the select menu, the variable country will hold the string "Spain".

In line 2 we targeting the second select menu to have access to it.

let citiesDropDown = document.querySelector("#cities");

In line 4-8 we have an if statement and we are checking if the incoming value (country) is an empty string.
This can happen if we select the first option <option value="">Choose a country</option> . Here the value is an empty string.

if(country.trim() === ""){
	citiesDropDown.disabled = true;
	citiesDropDown.selectedIndex = 0;
	return false;
}
  • If the country is empty we are making some changes to the second select menu.
  • In line 5 we are disabling the element.
  • In line 6 we are telling the select element to display the first option.
  • And in line 7 we stop the function with the return false statement.

Next we are gonna use an HTTP request to grab the data from the countries.json file. Do to so we are using the Fetch API and its global method fetch().

// AJAX request with fetch()
fetch("countries.json")
.then(function(response){
	return response.json();
})
.then(function(data){
	let cities = data[country];
	let out = "";
	out += `<option value="">Choose a city</option>`;
	for(let city of cities){
		out += `<option value="${city}">${city}</otion>`;
	}
	citiesDropDown.innerHTML = out;
	citiesDropDown.disabled = false;
});
  • In line 11, we are starting the HTTP request with the fetch() method, and because this i s a simple get request we have only one argument to pass in the method, and that is the path to the json file "countries.json".
  • The fetch() method returns a promise. To catch and resolve that promise we have to use the .then() method, in line 12-14 and resolve it to a response.json() object in line 13.

    The .then() method takes as an argument a callback function which takes also a variable as an argument which holds the response.

    The .json() method parses the JSON string and produces a javascript object so we can work with. But the .json() returns also a promise, and we have to catch that promise with another .then().

  • So in line 15 we have another .then() to catch the promise which is now a javascript object.

    As an argument we have again a callback function which has also an argument (the data variable) which holds the javascript object. Now we can extract the data we want (cities) from the data variable.

  • In line 16 we extracting the cities using the country variable data[country] (which holds the selected country) as key, and store them in the cities variable.
  • In line 17 we creating a variable out so we can add the cities when we loop through the cities array.
  • In line 18 we adding the first option in the out variable.
  • In line 19-21 we are looping through the cities and adding them in option tags to the out variable.
  • In line 22 we adding the out variable (which holds the option tags) in the second select menu to display the cities.
  • And in line 23 we enabling the cities drop down select menu so the we can choose a city.

I hope you find this article informative and helpful.
Thanks for reading.

Source code

You can download the source code and use it in any way you like.

Times downloaded: 452

Buy me a coffee

If you like to say thanks, you can buy me a coffee.

Buy me a coffee with paypal