Auto-populating Select Boxes using jQuery & AJAX
Update: due to popular demand, I've caved in, and written a plugin and demos with multiple-select boxes populating each other and driven from MySQL.
If you are familiar with using select boxes for categorisation and sub-categories, such as ebay does when selling an item, usually this can require a lot of JavaScript to maintain the select boxes, but jQuery can hugely simplify this task by adding a dash of AJAX.
The Goal
Allow the user to select a top level category from one select box and to automatically populate the sub-category.
Prerequisites
- Latest copy of jQuery
- A basic understanding of JSON (don’t let this put you off - it’s really very, very easy)
- A server-side script that can respond to the AJAX request (though I’ve provided a simple example)
Demo
Our demo will specifically look to build a simple form that allows us to book human resource for a project. The top level category is the resource type, and the sub-category will list the individual’s names.
How it works
Once the top level category select is changed, it sends an AJAX request for the sub-categories. The result of which are converted to select options and the sub-category select’s elements are replaced.
Unobtrusive JavaScript
First things first: as with any page that is loaded with JavaScript and AJAX functionality, it should work without JavaScript.
To achieve this for our tutorial here’s what we need to ensure:
- When the page is loaded, the sub-category is loaded (if the top level has a selected item).
- There is a ‘load sub-category’ button the user can select to re-load the page. We will hide this button with a <noscript> tag in our demo.
The Code
There are 4 parts to this demo.
- The page’s HTML.
- The server-side code to produce the dynamic page (i.e. to pre-load the select boxes when the user first visits).
- The jQuery & JavaScript.
- The JSON response (which will reuse the server-side code).
HTML
<form action="/select_demo.php">
<label for="ctlJob">Job Function:</label>
<select name="id" id="ctlJob">
<option value="1">Managers</option>
<option value="2">Team Leaders</option>
<option value="3">Developers</option>
</select>
<noscript>
<input type="submit" name="action" value="Load Individuals" />
</noscript>
<label for="ctlPerson">Individual:</label>
<select name="person_id" id="ctlPerson">
<option value="1">Mark P</option>
<option value="2">Andy Y</option>
<option value="3">Richard B</option>
</select>
<input type="submit" name="action" value="Book" />
</form>
Server-side
This is just a simple example, but it should be obvious that you can expand this to go off to a database and return an object in a JSON data structure:
<?php
if ($_GET['id'] == 1) {
echo <<<HERE_DOC
[ {optionValue: 0, optionDisplay: 'Mark'}, {optionValue:1, optionDisplay: 'Andy'}, {optionValue:2, optionDisplay: 'Richard'}]
HERE_DOC;
} else if ($_GET['id'] == 2) {
echo <<<HERE_DOC
[{optionValue:10, optionDisplay: 'Remy'}, {optionValue:11, optionDisplay: 'Arif'}, {optionValue:12, optionDisplay: 'JC'}]
HERE_DOC;
} else if ($_GET['id'] == 3) {
echo <<<HERE_DOC
[{optionValue:20, optionDisplay: 'Aidan'}, {optionValue:21, optionDisplay:'Russell'}]
HERE_DOC;
}?>
Note that this is not accessible. To ensure accessibility, the server side will handle the pre-population of the select boxes as the page is loaded. Here is an example (excluding the headers, footers and JavaScript) of the accessible example.
JSON Response
If I pass the server side id = 2, i.e. /select.php?id=2&ajax=true, the return value is (the ajax=true is an arbitrary flag that I’m using to differentiate between a normal user request and one done via AJAX):
[ {optionValue:10, optionDisplay: 'Remy'},
{optionValue:11, optionDisplay: 'Arif'},
{optionValue:12, optionDisplay: 'JC'}]
The enclosing square brackets denotes an array and each element is separated by a comma.
Within the array are three objects. If you’re familiar with PHP or Perl, you can basically treat these as hashes. The objects have keys (in this case two keys, one called ‘optionValue’ and one called ‘optionDisplay’), and values. Note that keys don’t need to be wrapped in quotes (though in some cases you will need them sometimes).
There are two ways which we can get the data out of this structure (assuming j is the structure):
alert(j['optionDisplay'])
Or:
alert(j.optionDisplay)
jQuery & AJAX Request
Our JavaScript is going to attach itself after the page is load, and fire an event each time the job function select box is changed.
The event will send the new value of the select box and reload the contents of the person select box.
Note that I’m be a bit naughty here, in that I’m plugging HTML directly in to the DOM.
Each item in the JSON response is looped round and used to build up the new options for the select box. As the response is an array (as mentioned earlier), we can call the .length method on it.
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" charset="utf-8">
$(function(){
$("select#ctlJob").change(function(){
$.getJSON("/select.php",{id: $(this).val(), ajax: 'true'}, function(j){
var options = '';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
}
$("select#ctlPerson").html(options);
})
})
})
</script>
Where to take it next
So that’s the primer. Next steps: upgrade, integrate, extend and stylise. Below is an example of the category selection when submitting an item for sale on Ebay.

It should be a simple next step to integrate a database behind the selection methods and create more complicated selection like this Ebay example.
Let me know if you spot are glaring errors or have any comments.
Thank you for example!
Hi Remy,
you saved my day. What a nice example ... and after reading it ... it seemed so simple. Thanks a lot for this.
One minor error I'd like to mention. Instead of
options = '' j[i].optionDisplay '';
it should be
options = '' j[i].name '';
Best regards
Stefan
I changed some of the variables after someone else commented that their names may be obscure.
Thanks for pointing that one out - I've updated the tutorial so the naming is consistent now.
It's interesting that after the select box is populated, Firefox 2 will select the last option, while Opera and IE seem to work correctly and select the first option. Any idea how to fix this ? I tried to use the 'select' attribute, or use selectedIndex , nothing seems to help.
@Sergui - you're right, FF does select the last item. Odd. Anyway - to fix this - I would change the following line:
options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';To:
options += '<option value="' + j[i].optionValue + '"'if (i == 0) options += ' selected="selected"';
options += '>' + j[i].optionDisplay + '</option>';
This is nice example and it is made me esay for solve category problem thank you for this example.
thanks and regard.
For the selected issue in FF, I used the equivalent of:
$("select#ctlPerson").html(options);
$("option:first", "select#ctlPerson").attr("selected","selected");
Thanks for the example.
In order to be not-so-naughty, you could use jQuery's $.appendTo function so you're not plugging html directly into the dom. (I guess you really are no way around it).
for(var i = 0; i < j.length; i ) {
$("j[i].optionDisplay").appendTo($("select#ctlPerson"));
}
Looks like some of my code got stripped:
...
$(<option value='j[i].optionValue'>j[i].optionDisplay</option>).appendTo($(”select#ctlPerson”));
...
This is great, thanks! I removed the default options for the select#ctlPerson and added the following code which sets the value of select#ctlJob and triggers the change function.
// trigger the initial select changer
$("select#ctlJob").attr("value","1");
$("select#ctlJob").trigger("change");
How can we do the listbox population using Mysql
please help me
Thanks to al
you don't happen to have an example using php & mysql-
That would be most helpful.
Thanks for sharing your talent.
Any Jquery experts out there know how to have NONE of the options in the 2nd box selected upon populating?
You could prepend a blank option to the beginning of the select with the selected="selectec" attribute.
That would at least have an empty option be the selected choice.
That example of "/select.php?id=2&ajax=true" still says id and name, instead of optionDisplay etc. Since I directly used the DB for this I used that link as example, and it took me some time to figure out why alert(j.optionDisplay) kept returning "Undefined".
Anyway, the final appendTo part doesn't work for me. I can't even get it to add it to body for testing. Also tried a test link function with $(bleh).appendTo($('.ctlJob')); but no options are being added. And no errors in firebug either. :/
@Mav - good catch - I'll update the post to fix that discrepancy.
I've tweaked the demo a little to get around the 'last selected' problem.
Add the following line after the .html() part (as Glen above suggests):
$('#ctlPerson option:first').attr('selected', 'selected');I don't think you particularly need the .appendTo().
If you still get stuck, let me know and I'll contact you directly.
Thanks to you I think I finally found the way to fall in love with javascript. Keep writing that way!
Thanks, but I figured it all out. I finally found out what my problem was. I was trying to make it easy to add more select boxes when needed too, to get some sort of flexible category/tagging thing. And I was having problems with cloning and appending complete select boxes, but that turned out to be a bug: http://dev.jquery.com/ticket/1087
PrependTo & AppendTo simply strip out the select tag. No errors, but no results either. Thought I'd mention that here, for those that are fiddling with select boxes too at the moment.
Thanks for this article, it helped a lot and it all works excellent now!
Has anyone actually got this to work with the eBay style... I've tried but am having a really hard time figuring this out... I would LOVE to see a tutorial on this, if anyone has done it...
While using this solution (thanks, by the way) I noticed IE6 complaining about attr('selected','selected'). The error is:
Could not set the selected property. Unspecified Error.
The reason this error occurs is because IE does not create the new html/dom until it gets back control from the script; first:option does not yet exist. You can get around this using the following:
$('#Test').html(optionstring);
setTimeout("$('#Test option:first').attr('selected','selected')",1);
I'm not sure if there is a jQuery solution (I'm still learning) but I thought this might help someone else out.
Thank you!
Now, I've got 3 select boxes, the first changes the second, the second the third. What I would like, is when the first is changed again, the third is removed or reset to a empty selector (hidden is fine, I'll qaqc after the submit to ensure that all three do parent-child chain). Anyway, what can I change in the JQuery (example code below) to chain the hiding of the of the last select box (#city)?
Thank you again.
$(function(){
$('#country').selectCombo('index.cfm?fuseaction=_ajax.return_plprov', '#prov');
$('#prov').selectCombo('index.cfm?fuseaction=_ajax.return_plcity', '#city');
});
Hi,
I’m new to all of this and am having trouble getting your code to work for some reason. Could you please make a zipped working example package for download that includes a separate JSON data file?
I somehow need to make a chain of 3 select boxes that use the value/key of a selected option (not the text) to base the populating of the next select box with.
Thanks
@Guy - thanks for point out that bug in IE6 ::groan:: - IE6 really must do things it's own way! Though I would suggest a small change to the code so you don't have to rely on the timeout in the other browsers (though it could be improved to select IE6 downwards - but you get the picture):
$('#Test').html(optionstring);var selectFirst = function() {
$('#Test option:first').attr('selected','selected');
};
$.browser.msie ? setTimeout(selectFirst,1) : selectFirst();
@Stephen - you need the following code change to empty the third select box when the first is selected (I'm not able to test it, but I'm fairly sure it should do the trick):
$('#country').selectCombo('index.cfm?fuseaction=_ajax.return_plprov', '#prov').change(function() {$('#city options').remove();
});
@Lance - I'll get back to you soon with a working example that you can download.
Hope that helps you all! Cheers for the feedback.
@Remy - thank you for the code suggestion. I've tweaked it a bit, the "remove" removed the 3rd select completely, and it wouldn't come back even on change of the second select. I've used "hide" instead:
change(function(){$('#city').hide();})
and it works (hide the third choice, but it comes back on the selection of the second).
I want to say thank you - this is one of the first jquey items I've worked with, and I knew I wanted to chain things, just couldn't figure out what/how. You feedback not only helps with the specific example, but improves my understanding of chaining with jquery. Thank you.
I can't seem to get this to work. I can't duplicate the example. I don't really understand how the html (with js) and php files work (i.e. I don't see where the php script is being called so I'm probably naming something wrong). Can you offer any help ?
@J.B.C - the key is in the getJSON call here:
$.getJSON("/select.php",{id: $(this).val(), ajax: 'true'}, function(j) { ...This is the JS that makes the AJAX call to the select.php on your web server. The response is then fed in to the function that we also pass in to the getJSON method.
Is it possible to implement this without the use of a server side for testing purposes. Like just static json and output the entire 3 column select box? Also completely using the jquery library?
Ok making it like the ebay with multiple selected does not work at all. Are you guys even sure that this works? I've been having trouble with how you all explain your changes. When I select from the first column, everything from the second column gets selected too. And it does not work for IE. For those who did get it working, can you provide the code you did?
[...] the calls to the server. I found a couple examples that did something similar to what I needed but did not use a database, did not have third box functinality, or did not work in all browsers. I encountered a known [...]
Very good Remy. Do you can share with us your know how to create a 3 related selects? Cheers.
For people interested in using this tutorial with mysql
1. include your connection
choose a table
Hope this will be useful to somebody
wow great example! i love it, i'm gonna use it in my next web app.. hihihi.. thanks.. ^_^
would really like a full example that shows the database piece.
Dear sir,
I want to use a text box for the user to type letters and query the database to get some results and populate in a list box. Is it possible to do that. like google doing it in browser toolbar.
Thanks,
Uday
@Uday - I think what you're after is here:
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
We too are having trouble getting it to work like ebay. Any suggestions? I am willing to donate for your time if we could get a working version.
Remy - thank you for the nice example. I was able to easily get it working using ColdFusion instead of PHP for a project I am working on. Always nice to have clear practical examples like this - thanks!
thanks for the example!but i badly need help!
suppose i need to send more than 1 id in the function,how can this be done!
$.getJSON("/select.php",{id: $(this).val(), i need to send 1 more id here to form a url based on these two id: $(this).val(), ,ajax: 'true'}, function(j){
@youshrin - Without knowing more about the particular example, I would do this:
thank you very much!
it works!
It's very nice but why not use Select Box Manipulation plug-in?
http://jquery.com/plugins/project/selectboxes
i have a real problem with mootools n jquery! i have build a column left using jquery(include jquery only on left column) and include it on all my pages,now on the main page i have used mootools(include mootools only in main page) to build a pop! jquery stop working on this page! please help n give suggestion of how to make both work on the page as column left is included on all pages.
Nice tutorial. AJAX with JSON looks pretty easy with JQuery.
Might even be enough to pull me from the rich feature set of prototype!
The small size, non-bloated feature set of the library is very tempting when building applications with performance optimisation in mind!
Thanks mate, I guess you just saved me few hours
I implemented your solution in like half an hour, and it works flawlessly. jQuery rulez!
[...] Autopopulating Select Boxes [...]
Great example, thanks!
For the FF last option selected, someone might want to have nothing select - you could try:
$(“select#ctlPerson > option”).removeAttr(”selected”);
I know this is very late in the day, but it might help someone...
Regarding the IE bug when selecting an item, maybe common knowledge but IE doesn't appear to like inner-functions passed via setTimeout, here's a working example of building a country list:
If selectItem() is defined inside buildCountrySelect() it will fail in IE, however this is probably better appraoch anyway since you can now use selectItem() to select an item in any list.
[...] Autopopulating Select Boxes [...]
I am making a computer hardware selector, When someone choose AMD proccessor only mainboards that suits for a AMD proc must left so i will do it with jquery ajax but it looks like i need to recalculate all fields any idea ?
I'm getting "an error occurred." and when i switch the alert to display alert(desc); I'm getting "parseerror"
I'm new to JSON is there something obvious that I just don't know about?
My understanding is that I make a dynamic page that just outputs my data like:
[{optionValue:15, optionDisplay: 'ICB Onecare ExecuHealth'},{optionValue:16, optionDisplay: 'Whatever Here'}]
Am I missing something?
[...] Autopopulating Select Boxes [...]
I will definitely use this on my site. Actually I was looking for a jQuery example to make a parts selecter, something like this http://welie.com/patterns/showPattern.php?patternID=parts-selector
the following mistake will only occurr when the url is viewed with a Firefox-browser:
I guess you might be someone who simply knows the reason for the mistakes that occurrs on this site
may I ask you to take a "firefox-look" at my demo?
regards!
Stefan
@Stefan - the problem is that you're trying to set the 'index' property of an option element, which you can't do.
The option element already has an index property but it only supports 'getting' rather than 'setting'.
From your code, you're using this 'index' attribute for tracking. It should work again if either you move the index track off the DOM node, or if you call the property something different to index.
i want to multiple values from combo(select) and display in a text area
pl give me solution
thanks
Thx! the script works great, but I am having problems displaying a non-standard characters like á, it just displays gibberish ? like icon.
Can anyone help me on how can I display it properly?
Owh I've use this to start the script:
changing the utf-8 to iso-8859-1 didn't solve the problem
Solved it! I just convert the strings with iconv() before displaying them in the JSON file
[...] Auto-populating Select Boxes using jQuery & AJAX is a great tutorial on working with jQuery, Ajax, and JSON… with select boxes. I was able to recently complete some client functionality thanks to this. Tags: Ajax, jQuery [...]
[...] Auto-populating Select Boxes [...]
[...] Autopopulating Select Boxes [...]
hi Sunil, did u find the solution of adding values to textarea??
HI All,
Please could anyone let me know how i should pass the value to my JQUERY.
see here what i want to do.
Here is the issue
{id: $(this).val(), ajax: 'true'}you guys have combo box or drop down so you get id of that and by id you could get the value for that controls. but we do have different scenario here like this<a href="?id=10" rel="nofollow">Click me</a>then how it will get the id from that and pass there in Ajax query string or how i should do because we have link there and on that link we are calling that and this links id is looping into while so everyone have diffrent. please if i m not clear then please reply me and please help us.Thanks to all of you.
[...] http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/ [...]
Hi remy, I need your help!
I'm trying to use your script in a thickbox, thickbox created with jQuery and with thickbox.js. The "auto-change" of select didn't work...
How can I do it?!
Thank you very much!
Awesome tutorial, thanks
I'm using 2 tables vs. 1 like in your example. I have everything working but actually populating the 2nd dependent select. I've modeled my code after yours, just not sure how to get the data in there, can you tell me what needs to be done here:
<script src="/jquery/jquery-1.2.3.js" type="text/javascript"></script> <script src="select-chain.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> jQuery.noConflict(); jQuery(function () { var type = jQuery('#spType'); var sp = jQuery('#specie'); sp.selectChain({ target: specie, url: 'request_processor.cfm', type: 'post', data: { ajax: true } }); // note that we're assigning in reverse order // to allow the chaining change trigger to work type.selectChain({ target: sp, url: 'request_processor.cfm', type: 'post', data: { ajax: true } }).trigger('change'); }); </script> <cfset s = createObject("component","specie").gettypes()> <cfif not structisempty(form)> <cfelse> <form action=""> <select name="specie" id="spType"> <cfoutput query="s"> <option value="#s.typeid#">#s.type#</option> </cfoutput> </select> <select name="specie" id="specie"> <option></option> </select> </form> </cfif>Thanks for the tool, I hope to be able to put it to use one day!@HJ - you might want to check out the next version of this (the link at the top of the page) - it explains how to chain select boxes:
http://remysharp.com/2007/09/18/auto-populate-multiple-select-boxes/
I hope that (starts) to help.
Would love to see a mysql connection example using this.
Anyone done one who could share?
@Jimmy - I'm not trying to be funny here, but have you checked out the link at either the top of the page, or perhaps directly above your comment? It includes MySQL connections, queries, chained select boxes - the whole she-bang
[...] Auto-populating Select Boxes using jQuery & AJAX [...]
[...] Auto-populating Select Boxes using jQuery & AJAX (tags: jquery javascript) [...]
[...] 17. Auto-populating Select Boxes using jQuery & AJAX [...]
Thanks for a great article - saved me hours!
[...] Auto-populating select boxes using jQuery and Ajax - A key technique in Ajax applications is to populate content without a page refresh. [...]
[...] 17.自动填充选择框 使用jQuery&AJAX,无须刷新页面,自动填充内容 Auto-populating Select Boxes demo [...]
[...] 17. Auto-populating Select Boxes using jQuery & AJAX [...]
[...] Login Form15.Yazılar için Ajax efekti | Demosu burada.16.Form Tamamlayıcı | Demo burada 17.Auto-populating Select Boxes using jQuery & AJAX | Demo burada.18.Ajax Açılır Menü19.Ajax/PHP shoutbox20.Ajax Tab Menü21.How to Load In and [...]
[...] 17. Auto-populating Select Boxes using jQuery & AJAX: http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/ 18. Ajax Açılır Menü: http://www.webmonkey.com/tutorial/Build_an_Ajax_Dropdown_Menu 19. [...]
Quite useful indeed. Thanks for sharing.
[...] copyright: this article is copied from http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/, the copyright belongs to the author not [...]