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.
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>";
}
?>
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.
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.
This is a great tut and very useful! Thanks Chris!
gr8
I recently had to tackle this problem; Initially I went with JSON, but this turned out not to be that good of an idea. JSON adds a little slowdown to every action, and it turned out a few of my users had experience when they would loose Wi-Fi connection and the request would fail silently; What I did was just store the entire selection data in the html (long live json_encode()) and just changed my original json getter function to use that.
The markup may not be as clean this way, but my users were pretty happy, and that’s what stands above all.
If i understood well, this way you do not use any “external” data to dinamically fill your form… you just use a predefined js array/object that contains all the possible elements…
This could be an easy way until you have a very limited number of elements (as normally is), otherwise i think you should prefer a dinamic solution possibily with asynchronous requests.
@Loige, if I understand Crafty_Shadow correctly, I believe he is using external, dynamic data. From his description, it seems like he is using PHP to pull an array from a database, and then echo it out into the reaw HTML of the served page. This allows him to dynamically update the fields through the database without an AJAX call, as the database contents is embedded into the original page.
Whilst this solution is preferable for a small number of items, if the database expanded into thousands of items, returning to the more traditional AJAX method is probably recommended, as the filesize of the served HTML file would balloon unnecessarily.
@Benjamin
That’s exactly what i meant :)
Thanks for providing a better explaination! Your english is surely better than mine :P
This is so cool. It used to be a lot of work and code to do this. Great work!
Really nice tutorial, i’ve already done a similar script but in a little different way but yours is very cool ! I’ve learn some function that i have not seen before.
Have a nice day
Great stuff as always Chris, thanks!
Looks like the ‘Please select’ option is missing a value in the demo.
<pre>
<option value=”base”>Please choose from above</option>
</pre>
I really like the different options. Great tutorial and thanks for the tips.
All 3 examples use $(“#first-choice”).change(function() {…});
to fire the $.load when the first list changes. But what about when the page is reloaded or the BACK button is used? Often you will get a different value from default in list#1, but no options in list#2.
An additional $(“#first-choice”).change(); command will force the script to load the correct 2nd list as soon as the page loads. You could even tack it on to the end of the main command like so:
$("#first-choice").change(function() {
$("#second-choice").load("getter.php?choice=" + $("#db-one").val());
}).change();
shouldn’t it be:
$("#first-choice").change(function() {
$("#second-choice").load("getter.php?choice=" + $("#db-one").val());
}).trigger("change");
with the
trigger()
method…Yep. The first thing jQuery says about .change() is:
“This method is a shortcut for .bind(‘change’, handler) in the first variation, and .trigger(‘change’) in the second.”
So either way will work. Thanks for pointing that out. I’ve always just used $.click() or $.change() and didn’t know about the trigger() method that they were shortcuts for.
@Rob Young
Thank you for pointing out…
As far as I know using trigger it will truly simulate an event activation (and an event object is created and passed to the callback). So the call bubbles and the propagation can be stopped…
Maybe i’m wrong, but I don’t think you can do the same by grossly calling the event function…
I will dive further into the documentation to understand well this aspect of the library ;)
For the last bit of code, shouldn’t $(“#db-one”).val() be $(this).val() or $(“#first-choice”).val()!?
Yes thank you, I changed the ID’s for sake of clarity in the written article and missed on. Fixed.
Could you make a stand-alone version of the database demo work by using SQLite?
I don’t know much about SQLite, but that’d be rad. If you can get it worked I’d be glad to do a follow up article.
SQLite is fairly equal to MySQL. Difference being that it’s not stored on the main server behind the screens and accessed from memory, no, instead SQLite databases are single files directly in your FTP that you can open in PHP and read/write to it, just like MySQL.
There’s a couple of catches though:
* If it get’s big, it will be very slow (whenever you need data from it it needs to ‘open’ that entire file from the harddrive
* Locks (two people can’t access at the same time). although this doesn’t happen that often in practice, it can be a real bummer.
Good side though:
* It doesn’t require username/password or any ‘back-end’ stuff. Creating the time and having write/read access (CHMOD) to it is enough and it’s running. Which means if you’re building a light weight application that you dont want the customer to have to setup stuff in Phpmyadmin, with SQLIte it’s uploading and go (the php script could even create the sqlite if it doesn’t exist already).
Examples for PHP5:
* http://devzone.zend.com/article/760
* http://www.switchonthecode.com/tutorials/php-tutorial-creating-and-modifying-sqlite-databases
hello,
i did create the database and the files and it doesn’t work.
thanks,
i have an index.html
Now where did I just see that? ;) http://screenr.com/AKZ
Very cool tutorial, and waaaaaay easier than I thought it would be.
Nice approach,
For further bullet proofing the functionnality, you could make the whole system work in php using the same table that you actually have
+-------+----------+----------+
| index | category | dd_val |
+-------+----------+----------+
| 1 | snack | chips |
| 2 | snack | Cookies |
| 3 | beverage | Coke |
| 4 | beverage | Coffee |
+-------+----------+----------+
in the first drop down you only load the categories and in the second you load all the dd_vals. Once the user submit the form you cross-check if the category fits with the dd_val, if you get a match proceed as planned, otherwise throw an error.
Once this part works, you had a jquery layer to populate the second list with the right dd_vals based on the category selected in the first drop down.
This way, you have a nice fallback if javascript doesn’t work (either because the user have deactivated the feature in his browser or because there is a bug in the javascript itself)
I enjoy reading your articles. For the json portion, I would suggest:
{
"beverages": "Coffee,Coke",
"snacks": "Chips,Cookies"
}
be changed to
{
"beverages": ["Coffee", "Coke"],
"snacks": ["Chips", "Cookies"]
}
It uses a few more characters, but captures the intent of the data structures better.
In addition, it removes the need for calling the
split
method as the values are already in an array.Exactly what I was about to say :) Using JSON as it was intended.
Being the javascript fan I am, I was looking for a comment like yours Steven ;) Using an array for that listing woud allow you to write something like
vals = data[key] || [‘Please choose from above’];
Which gets the listing from data by key, and if it is undefined it falls back to [‘please choose’]
But that may just be besides the point of this article, which does a good job showing some of your options.
This is awesome, thanks a ton man.
I was rackin’ my brain a few months ago trying to figure this out…. ended up giving up.
Thanks for the tutorial, Just great, as it’s already been said, used to be lots of coding, and now just a simple nice easy to understand two line of jquery and php.
The PHP code is open to SQL injection attacks, since you’re not escaping the $choice variable. In addition, you’re using the old MySQL library (which is now deprecated), so it will only work with MySQL. I’d suggest changing it to use PDO, which is newer and works with a few databases (SQLite, PostgreSQL, MySQL among others).
See: http://www.webdevrefinery.com/forums/topic/1272-your-mysql-code-sucks/
Thanks for an excellent post on dynamic dropdowns and three ways of approaching, some nice ideas, we like to use databases as said for flexibility, clean code and scalability. LT
There is already a JQuery Select Chain plugin by Remy Sharp, http://remysharp.com/2007/09/18/auto-populate-multiple-select-boxes/, which provides a wrapper for the functionality.
We use it alot, all we had to do was write a PHP wrapper function to generate a JSON string from an array of values in the , so that the source of the values does not matter, whether from a database, file or web service
I agree with Steven Albano and I would add the base value to the json instead of keeping it in the code.
The adding of the options isn’t working because there is no function call.
Check the jsfiddle to see how i would write the code.
The MySQL variety is a little clunky compared to the other two, sometimes the request can be so slow it takes several seconds. Probably something to stay away from unless there is no alternative.
Argh.. i see deprecated mysql_*-Function.
Good Tut anyway.
Hi Chris great tuts. I downloaded the files and works fine and easy to follow however it does not work on Google Chrome (works fine in FF though). Am I the only one experiencing this issue?
Hi,
Thanks for this great tutorial ;)
I had a problem with dynamic dropdowns using a database.
I made 3 menu: the second depends on the first, the third depends on the second.
But there is a probleme. The second contains some elements with spaces and elements from one word.
For element with one word everything is ok.
But when i select an element composed from two parts (that contain space) the third menu don’t show any result!
What do you think? what’s the probleme with spaces?!
I found the solution:
you need to add escape() for the variable!!! and no more problems with spaces ;)
escape($(this).val())
Maybe you better add this to your code to be perfect :D
$(“#first-choice”).change(function() {
$(“#second-choice”).load(“textdata/” + $(this).val() + “.txt”);
});
Bye, and thanks again
@cristi
I uploaded Option 3: Using a Database here: http://rapidshare.com/files/428684871/dropdown.rar
Put the ‘dropdown’ folder in your ‘www’ folder. In phpMyAdmin create new database and name it ‘dropdown’. Then import the file dd_vals.sql, which can be found into the rar file and you are good to go. Hope it helps.
It’s nice to see such advanced design topics discussed in such detail. I’ve been doing web design for quite a few years now, and I really wish resources like this had been around back when I started. I probably would have gotten a lot further with my web design career.
I also couldn’t get the JSON example to work (missing function call when pushing select options onto $secondChoice). David’s jsfiddle link helped a lot.
Hello, in regards to using the text files method.. How would you expand the code to allow for more than two drop down fields?
List 1 populates list 2…
List 2 populates list 3…
List 3 populates list 4…
Thank you.
Hi,
I have seen your tutorial. it seems it is very easy way to handle drop down menu. but sorry to say i can get output. the error message i am receiving is ” Undefined index: choice in”
need your help.
Ripon
Hey there,
your tutorial is very helpfull but im having trouble with the third example. if you could upload again (link is bronken) it would be nice.
If its not ask to much i would like to do everything without making a external file like getter.php.
Sorry How do you change or add more options to this drop down system.
Are any of these examples able to be ran from localhost. I downloaded your source files and tried to test from my localhost. Neither text example or Json works from that location. My localhost is connected properly. Thanks
thanx alot Chris Coyier really its a great tutorial, i wanna ask you one question how can i use PDO with the third example the database one