So You Need To Fill a Dropdown Dynamically

Avatar of Chris Coyier
Chris Coyier on (Updated on )

You have one dropdown menu, and depending on the user’s choice in that one, a second dropdown gets filled with choices. Let’s cover three different ways you can go about that.

View Demo   Download Files

The Markup

For our example, the markup will always be the same, just two simple select elements. The first one has three options. The first just informs the user to select an option, and the next two are actual choices. The second select only has one option telling the user to please pick from the first dropdown first. The options in the second dropdown will be dynamically replaced.

<select id="first-choice">
  <option selected value="base">Please Select</option>
  <option value="beverages">Beverages</option>
  <option value="snacks">Snacks</option>
</select>

<br>

<select id="second-choice">
  <option>Please choose from above</option>
</select>

Option 1: Using Text Files

The idea for this post came from Robert Young who wrote to me sharing this technique. The idea is that it’s easy to use and understand. Not everybody wants to deal with databases and whatnot.

Have one text file for each possibility:

Inside those text files, have the replacement HTML for new options ready to go:

<option>Coffee</option>
<option>Coke</option>

Now we’ll use jQuery to watch for the changing of the first select. All our examples will use jQuery.

$("#first-choice").change(function() {
   $("#second-choice").load("textdata/" + $(this).val() + ".txt");
});

This works fine. It is indeed easy to do. The potential downsides are 1) storing data in HTML tags like that may not be the way to go, hard to repurpose that data for other reasons. 2) not super scalable, requiring a new text file for every single possibility.

Option 2: Using JSON Data

An alternative is to store the data that you need in JSON format. You could have it right in your JavaScript that you are loading, or keep it in an external file. For this demo it will be an external file called data.json. This is its contents:

{
  "beverages": "Coffee,Coke",
  "snacks": "Chips,Cookies"
}

We again watch for a change in the first select’s value, then load the JSON and figure out which parts of it we need:

$("#first-choice").change(function() {

	var $dropdown = $(this);

	$.getJSON("jsondata/data.json", function(data) {
	
		var key = $dropdown.val();
		var vals = [];
							
		switch(key) {
			case 'beverages':
				vals = data.beverages.split(",");
				break;
			case 'snacks':
				vals = data.snacks.split(",");
				break;
			case 'base':
				vals = ['Please choose from above'];
		}
		
		var $secondChoice = $("#second-choice");
		$secondChoice.empty();
		$.each(vals, function(index, value) {
			$secondChoice.append("<option>" + value + "</option>");
		});

	});
});

The advantage here is that we are storing the data fairly generically, so it would be easy to repurpose it for other things. Notice we add the option tags in the JavaScript itself, that’s pretty flexible. The downsides to this technique is that it’s a bit more complicated (but really, it’s not that bad). We might want to consider breaking up the JSON into separate files so we don’t need to load all data on every change, but then we run into the same scalability issue as text files. Having the database return us JSON is also a possibility here.

Option 3: Using a Database

We’re still going to watch the first select with jQuery, and still load in the new options dynamically with jQuery’s .load() function. But to pull from a database, we’ll need an intermediary partner that can do that database talking for us (JavaScript can’t do that by itself). So we’ll use a file “getter.php”, and that will be the file that returns us what we need.

First we’ll need a very simple database to pull from:

CREATE TABLE `dd_vals` (
  `index` int(11) NOT NULL,
  `category` varchar(255) NOT NULL,
  `dd_val` varchar(255) NOT NULL,
  UNIQUE KEY `index` (`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `dd_vals` (`index`, `category`, `dd_val`) VALUES (1, 'snacks', 'Chips'),
(2, 'snacks', 'Cookies'),
(3, 'beverages', 'Coffee'),
(4, 'beverages', 'Coke');

Now we can query that database, in the “dd_vals” table for entries that have snacks or beverages as their category and get just what we want. Our query needs to end up something like this:

SELECT * FROM dd_vals WHERE category='beverages'

So let’s make our getter.php file connect to that database, and have a GET parameter for the category choice, plug that into the query, and return what it finds in option tags.

<?php

	$username = "username";
	$password = "password";
	$hostname = "localhost";
	
	$dbhandle = mysql_connect($hostname, $username, $password) or die("Unable to connect to MySQL");
	$selected = mysql_select_db("dropdownvalues", $dbhandle) or die("Could not select examples");
	$choice = mysql_real_escape_string($_GET['choice']);
	
	$query = "SELECT * FROM dd_vals WHERE category='$choice'";
	
	$result = mysql_query($query);
		
	while ($row = mysql_fetch_array($result)) {
   		echo "<option>" . $row{'dd_val'} . "</option>";
	}
?>
Keith Silgard wrote in to help me make sure this was secure. Whenever you run a database command with data that you recieve via POST or GET, you need to make sure that data is safe. As in, it doesn’t contain incredibly malious code like “; DROP TABLE … “, which is commonly known as SQL injection. This code has been updated to use mysql_real_escape_string to ensure that doesn’t happen. Also note this function only works properly if used after the database connection is established.

Now our JavaScript is really simple, we again watch for changes to the first dropdown and load in the getter.php file into the second dropdown. The fancy trick here is to pass the getter.php file URL parameter which is the value from the first dropdown.

$("#first-choice").change(function() {
  $("#second-choice").load("getter.php?choice=" + $("#first-choice").val());
});

For very little website and isolated examples, a database can feel like a lot of work or even overkill, but this is easily the most flexible option. The code is clean, it’s fast, the data is stored in a way we can do just about anything with it, etc.

That’s not all?

Like anything on the web, there are even more ways to approach this. We could have stored the values in an associate array. We could have used MongoDB. We could have had the different selects ready to go in the HTML and hide-and-show them as needed with JavaScript. They all have advantages and disadvantages.

View Demo   Download Files

Note: I’m not including the database example in the download because it won’t work until you have your own database to connect to and all that. It’ll just be less confusing that way.