Check out my latest project: Full Frontal JavaScript Conference

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.

View: Auto-populate multiple select boxes

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

  1. Latest copy of jQuery
  2. A basic understanding of JSON (don’t let this put you off - it’s really very, very easy)
  3. 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.

See the demo in action

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:

  1. When the page is loaded, the sub-category is loaded (if the top level has a selected item).
  2. 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.

  1. The page’s HTML.
  2. The server-side code to produce the dynamic page (i.e. to pre-load the select boxes when the user first visits).
  3. The jQuery & JavaScript.
  4. 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.

Ebay Category Selection

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 any glaring errors or have any comments.

160 Responses to “Auto-populating Select Boxes using jQuery & AJAX”

  1. It's very nice but why not use Select Box Manipulation plug-in? :)

    http://jquery.com/plugins/project/selectboxes

  2. 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.

  3. 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!

  4. 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!

  5. [...] Autopopulating Select Boxes [...]

  6. 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...

  7. 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:

    var countries = new Array();
    countries[ countries.length ] = "Afghanistan";
    countries[ countries.length ] = "Albania";
    countries[ countries.length ] = "Algeria";
    //...
    
    //call this with target element ID and default item
    function buildCountrySelect(targetEl, selected) {
        $.each(countries, function(index, country) {
            $(targetEl).append("" +country + "");
        });
    
        $.browser.msie ? setTimeout("selectItem('" + targetEl + "', '" + escape(selected) + "');", 1) : selectItem(targetEl, selected);
    }
    
    function selectItem(targetEl, selected) {
        if(selected=="") { selected="default"; }
        $("option:contains('" + selected + "')", $(targetEl)).attr("selected","selected");
    }

    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.

  8. [...] Autopopulating Select Boxes [...]

  9. 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 ?

  10. 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?

  11. [...] Autopopulating Select Boxes [...]

  12. 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

  13. 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

  14. @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.

  15. i want to multiple values from combo(select) and display in a text area

    pl give me solution

    thanks

  16. 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

  17. Solved it! I just convert the strings with iconv() before displaying them in the JSON file

  18. [...] 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 [...]

  19. [...] Auto-populating Select Boxes [...]

  20. [...] Autopopulating Select Boxes [...]

Leave a Reply
Not required

CODE: Please escape code and wrap in <pre><code>, doing so will automatically syntax highlight