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.

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

  1. Hi,

    This module is exactly what I'm looking for, however my JQuery knowledge is weak.

    I have things working to the point where I can click something in box 1 and box 2 gets populated with the correct number of options, but all the options say "undefined".

    This is what the JSON object looks like that I'm sending back - any idea?

    [{"optionDisplay":"2009-10-27","optionValue":"2009-10-27"},{"optionDisplay":"2009-10-13","optionValue":"2009-10-13"},{"optionDisplay":"2009-10-07","optionValue":"2009-10-07"}]

    TIA!!

  2. this menu is great on MOZILA BUT with IE it doesn't work.. any solution??

  3. Hey,
    You are a great developer.
    Thanks so much. As I don't want to use plugin(s) for "JSON select options", I found this code really helpful:
    for (var i = 0; i < j.length; i++) {
    options += '' + j[i].optionDisplay + '';
    }
    $("select#ctlPerson").html(options);

    Again, thanks man!

  4. Hello!

    I have a problem and i hope you could help me because i need to finish my project and i am a little late :).

    When i use this "auto-populating" method with "jqTransform (http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/)" the "auto-populating" doesn't work.

    I really appreciate any help. Thanks a lot

  5. Hi

    i was hoping someone could assist me witha slight problem i have. i'm attempting to convert this method to use an ASP server side scrip[t instead of PHP and as yet have struck out.

    i have simpley placed the following code in my body tags

    
    <%
    if (request.QueryString("id") = "1") Then
    	response.Write("[{optionValue: 0, optionDisplay: 'Mark'}, {optionValue:1, optionDisplay: 'Andy'}, {optionValue:2, optionDisplay: 'Richard'}]")
    	Elseif (request.QueryString("id") = "2") Then
    	response.Write("[{optionValue:10, optionDisplay: 'Remy'}, {optionValue:11, optionDisplay: 'Arif'}, {optionValue:12, optionDisplay: 'JC'}]")
    	Elseif (request.QueryString("id") = "3") Then
    	response.Write("[{optionValue:20, optionDisplay: 'Aidan'}, {optionValue:21, optionDisplay:'Russell'}]")
    	End If
    %>
    
    

    and this give me the same response as the php test when i browse to it and manually set the id. and when using the html page it get NO java script error it just dosnt populat the boxes.

    I hope some can shed some light as its probably something really simple that i'm missing

    thank You in advance

  6. i need help parsing this jason using jquery.

    I have great dificulty.

    I made static html page with jason so use that as a request heare is the jason i need to iterate all the elememtns on the jason.

    thanks,

    "items": [
    {
    "title": "sample 1",
    "author": "author 1"
    },
    {
    "title": "sample 2",
    "author": "author 2"
    }
    ]

  7. Here's a bug with the latest version of JQuery is 1.4.1

  8. this aint working in no version of ie, 6,7,8
    you dont have idea how to do it, fix it, otherwise dont post articles, ive spent 3 days with it without results

  9. i found out the solution to why it doesnt work in IE, who want it urgently mail me to fantomx1@gmail.com
    for very small fee i will share it to you

  10. You're asking a fee??? Damn that's sad

    Here you go guys, this code should work:

    
    $('#select1').change(function() {
       $.getJSON('/path/to/file.php',{"id":$(this).val()},function(data) {
          $('#select2 option').remove();
          $.each(data,function(i,item) {
             $('#select2').append('<option value="'+item.id+'">'+item.value+'</option>');
          });
       });
    });
    

    Uhm, dunno, probably this system strips tags that I put..
    $('#select2').append('option value="'+item.id+'"'+item.value+'/option');
    Add brackets to form html tags in the line above

    The json may look like this:

    
    [
    {"id":"1","value":"somevalue"},
    {"id":"2","value":"someothervalue"}
    ]
    

    By the way, PHP can convert arrays to json, you need json php module for that.
    The function is json_encode()

  11. HI All,

    I am doing a similar one in struts2 but I have very less knowledge about JSON and JQUERY .I have a 2 select boxes.In the first box I select a value and made an Ajax call in which I send the selectedValue which will take me to action class.In my action class I wrote like this...

    @JSON(name="jSONArray")
    public void getCityVals()
    {
    Country c=StorageBean.getCountryList().get(selectedCountry); //this is passed from jsp via AJax call

    atrHMap1=c.getCityList();
    JSONArray jSONArray=new JSONArray();
    jSONArray.addAll((Collection) atrHMap1);

    for (int i = 0; i "+jSONArray.getString(i));
    }
    }

    and in my JSP I have...


    $(document).ready(function() {
    $(function() {
    $("select#countries").change(function() {
    $.getJSON("cityAction.action?search=",{countryId: $(this).val(), ajax: 'true'}, function(j){
    var options = '';
    for (var i = 0; i < j.length; i++) {
    options += '' + j[i].name + '';
    }
    $("select#cities").html(options);
    })
    })
    })
    });

    I dunno how to use my JSON data and use the above one(just modified it based on example given !!! ) to populate them in my 2nd select box...
    Kindly need guidance !!!

  12. i didnt shared solution, just for i wanted to know how many will ask me, so far just one, so i will share it, moreover this isnt usual, many will get paid for this solution in their web projects, this inst linux, i fought for solution googled, trialed in error and needed in in very urgent situation and get paid very few for what i did. but i will, have to check it in my project though :) i forgot

  13. IE needs these three lines in your ie PHP project, its php code

    header('Cache-Control: no-cache, must-revalidate');
    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
    //
    //
    header('Content-type: application/json');

    i will be glad for each your saying thanks

Leave a Reply
Not required

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