Please consider donating: a local project in memory of my daughter

Auto-populate multiple select boxes

To follow on from Auto-populating Select Boxes using jQuery & AJAX, I've had more than a few requests for how to do this for multiple select boxes.

In response, I've written a jQuery plugin and have included a simple example of three select boxes populating each other driven by a MySQL database.

Download

Prerequisites

  • jQuery (this has been tested with 1.1.1 and 1.2 - so it should be fine).
  • Basic knowledge of JSON
  • Access to the server side for PHP and MySQL if you want the selects driven by a database.

Disclaimer

I have to admit I wrote the plugin pretty quickly, so it might not have all the bells and whistles you might want it to have - but it definitely does the job.

Also, the demo I've provided does not degrade if JavaScript is turned off. I advocate that you practise accessible JavaScript. This example is just to show the plugin working. Remember to make it work via the server-side too!

Demonstration

This demonstration uses three select boxes, the first (element category) drives the next (elements) which drives the next (attributes).

You should keep in mind this demo was written quickly, and I would never normally use the same name attribute on a select box, because when it comes to actually submitting the form, it would be a mess of values.

See the multiple-select population in action

Usages / Config

$('#categorySelect').selectChain({
    target: $('#childCategorySelect'),
    url: 'update-options.php'
});

Required

  • target: jQuery object or HTML element
  • url: string to Ajax request

Optional

  • key: key of the key/value pair if you're returning an array of objects. Defaults to 'id'.
  • value: value of the key/value pair if you're returning an array of objects. Defaults to 'label'.
  • data: additional data values to send in the request (can be a string or object)
  • type: Ajax request type, i.e. post or get

What next?

Here's a list of small bits that I think could be added to improve this plugin, but should be simple enough for anyone to write:

  • Caching Ajax results.
  • Ability to send the data (posted or get) based on a dynamic criteria - i.e. perhaps there's another static select box.
  • Using meta data in the classes to link the targets to the parents - but this might make for sloppy markup.

Feel free to add any suggestions or improvements.

150 Responses to “Auto-populate multiple select boxes”

  1. [...] Select List. Multiple Selects. Select box manipulation. Select Combo Plugin. jQuery - LinkedSelect Auto-populate multiple select boxes. Choose Plugin (Select Replacement). 四、表单基本、输入框、选择框等(Form Basics, [...]

  2. [...] Select List. Multiple Selects. Select box manipulation. Select Combo Plugin. jQuery - LinkedSelect Auto-populate multiple select boxes. Choose Plugin (Select [...]

  3. [...] Select List. Multiple Selects. Select box manipulation. Select Combo Plugin. jQuery - LinkedSelect Auto-populate multiple select boxes. Choose Plugin (Select [...]

  4. [...] Select List. Multiple Selects. Select box manipulation. Select Combo Plugin. jQuery - LinkedSelect Auto-populate multiple select boxes. Choose Plugin (Select [...]

  5. Thanks for the code.

    Is there any way to bind two menus to the same menu. (ie. When I select a value in one menu I need two other (sibling) menus to be updated and then these two in turn cascade their changes down to other menus)?

    Matt

  6. [...] Select List. Multiple Selects. Select box manipulation. Select Combo Plugin. jQuery - LinkedSelect Auto-populate multiple select boxes. Choose Plugin (Select [...]

  7. How do I update this to use a different database structure?

    I wish to add these select boxes:
    - Product Name
    - Size
    - Material
    - Color
    - Collar

    I get a problem when I try to populate the Material options as follows:

    If the user selected PRODUCT: AA1, SIZE: large then it should show MATERIAL options of: silk, cotton. However, this database structure forces me to input all possible options for SIZE: large, meaning that it shows all SIZE: large material options even for products that do not actually have that material available. (AA1 may have silk available in large, but BB1 does not have silk available in large).

    In other words: the options in box3 should be determined by the selection in box 1+2. However with this database structure the options in box3 are determined by box2, ignoring the selection in box1.

    1) How should we update the code to use a relational database structure instead of this 'one table' approach?
    2) Also I cannot get it to populate box4 (color).

  8. I'm having the same problem as mameha. I can't seem to figure out the solution at all.

  9. I found a clumsy way to do it:

    key | value
    ----------------
    AA1 | small
    AA1 | large
    AA1 small | silk
    AA1 small | cotton
    AA1 large | silk
    AA1 small silk | red
    AA1 small silk | blue
    AA1 small cotton | red
    etc...

    Its not ideal but I can live with it.

    I am now trying to change it so that box1 remains a select list, but box2 is a list of checkboxes. No idea where to start though...

  10. Hi!

    How can I pre-select an option in the second select box? Example is when the page loads, The element category pre-selected option is Scripts then the element category pre-selected option is Noscript

  11. Thanks for the great plugin! It was a real timesaver, and the best I found for what it does. And mameha, I think I had the same problem as you, that the script only sends the last changed select's value to the ajax script, so I solved the problem by tinkering a little in the script by doing this (and I'm not a professional jscript programmer.. so it might not be the best way to do it, but at least it works! Look at about line 15 to see what I changed, this should give the ajax script the values of all the selects on the form...):

    $$.change(function () {
      var data = null;
    
      $(this).parent().children("SELECT").each(function(i) {
        if (typeof settings.data == 'string') {
          data = settings.data + '&' + this.name + '=' + $(this).val();
        } else if (typeof settings.data == 'object') {
          data = settings.data;
          data[this.name] = $(this).val();
        }
      });
    });
  12. There's an error in your code on change function / default data argument. The select data aren't sent if I don't define data setting. Cause settings.data is null and don't enter the conditionals on change event.

    In my code I solve this just by putting void data on default settings:
    var defaults = {
    key: "id",
    value: "label",
    data: ""
    };

    Sorry my bad english and thanks for your code. This saves my time.

  13. [...] Select List. Multiple Selects. Select box manipulation. Select Combo Plugin. jQuery - LinkedSelect Auto-populate multiple select boxes. Choose Plugin (Select [...]

  14. Hi All!
    For pre-selected second select: http://jsbin.com/ujopi (edited by blog author avoid dumping JS inline with comments).

  15. anybody have the classic ASP equivalent to this PHP ?

  16. I'm trying to implement the eBay categories example and am having trouble with utf-8 characters (I'm using eBay Spain). The category names have accented characters that appear fine when I print them in the HTML (I have charset set to utf-8) but using your script the select boxes don't print them correctly. I'm guessing the info is screwing up in the JSON POST response, but I'm not sure how to fix it.
    Thanks! (by the way, great plugin)

  17. Hi Remy, i've got a little problem with your excellent plug-in, but only on IE, here's my code.

    profil.php (my 3 select) : http://panpan.pastebin.com/m27ca2627
    ajax.php : http://panpan.pastebin.com/m669e97d0

    I use jQuery 1.3.1 and of course your select-chain.js. Everything works perfectly on FF but on IE the select#ville is not populate but the request seems to be good and the select#departement IS populate.

    a screen of the IE debug bar :

    http://www.bandofbranleurs.com/upload/1/1234018171_2009_02_07_154912.png

    So can you watch the problem ? Thx !

  18. Thank you very much. Your article has taught me a lot.
    Actually I am planing to read and try to grasp "Auto-populating Select Boxes using jQuery & AJAX"

  19. I have found the bug, it seems that ie doesn't want to populate a select#id but works on a div#id.

    Everything is good !

    Thx again for your plugin.

  20. Hi anyone know if this it's possible to implement this without a database? I have PHP but not a db back-end.

  21. Hi,

    First of all, thanks for taking the time to write this :)

    Now, I've almost got this working how I want.

    I've got 4 boxes (continent,country,city and state).

    I'm doing the selection process a bit different, with:

    $results = mysql_query('select * from glinks_Category where Full_Name LIKE "' . $_REQUEST['category'] . '/%" and CatDepth=' . $_REQUEST['CatDepth']);

    Now, this works fine at the moment - but the problem is, I need the value="FULL_NAME", and what the user sees in that box to just show the last part of NAME.

    For example, we have:

    Europe
    Europe/United Kingdom
    Europe/United Kingdom/Surrey
    Europe/United Kingdom/Surrey/Guildford

    ..and those would in theory, generate to:

    Europe
    United Kingdom
    Surrey
    Guildford

    Is there any way of doing this?

    Thanks again!

    Andy

  22. Hi,

    Great work, Any way to make this code static javascript (non-AJAX)

  23. Michael Gamble May 15th, 2009 at 7:22 pm

    I need help with setting this up on a website, with a Year > Make > Model > Trim selections. Can someone help me please, I am knew at the whole database and scripting thing. I am a simply HTML, FLASH, Graphics guy, don't do much jQuery or Ajax or JSON. I am willing to pay someone $50.00 paypal to help me. I need it asap though. Thanks! email me at: mike at mikonmedia.com

  24. Hey! Great plugin.

    One question: have anyone tried it together with MultiSelect plugin?

    Thanks!

  25. Thank you, thank you, thank you.
    I'm one of those people who's just starting out with AJAX and jquery and of course, I'm biting off more than I can chew.
    Thanks to you, I finely have "what I had in my head for my next project" working in a real life example.

  26. how can we select multiple items at a time?

  27. ok answering my own question. I noticed some other asked as well.

    In order to select multiple items change the request method to post, change the select element name from category to category[]. This is create a sub array in $_POST of all your selected items.

  28. Only to say thank you Remy.

    Besides. I had the typical problem about JSON, but with your answer @HJ:

    [ { id: 1, text: "Cat" }, { id: 2, text: "Dog" }, { id: 3, text: "Worm"} ]

    && without forget:

                key: "id",
                value: "text",
    

    all goes OK. Excellent start for jQuery and JSON.

    $json[] = "{ id : {$row['id']}, text : \"{$row['text']}\" };
    echo '[' . implode(',', $json) . ']';

    -- && this editing system for comments is fantastic!!! --

  29. Thanks for this wonderful plugin ! it helps me save a lot of time!

  30. Awsome plugin!!
    You just saved my ass !!!
    God bless you...

  31. Hi, how do I apply 'selected="selected" attribute to one of my options?

  32. ok i posted this under the old topic by mistake, reposting here. Hopefully someone will respond. :)

    Ok i've extented this to a wonderful solution that uses 5 select boxes that allow you to select mutiple items at a time. for each list and also integrated a search box for the final list.

    but of course my end user wants more! .... so for my lists are a simple chain. so one selection affect the list immediatly next to it and so on.

    well i want to have it where say my first selection affects the 2nd and also the third and maybe 4th. However u cant figure out how to pass selected items from the first list to another.

    here is a snipplet of what i have
    customer.selectChain({

    target: market,
    url: callback_url,
    type: "POST",
    data: { ajax: true, multsel: market_selects, cust_val: customer.val().join(",") }
    }).trigger('change');

    So this customer selector triggers a changes in a market selector box. This all works fine. But look at the data line...i assume ajax:true tells it to pass the selected values from the current list.

    multisel : market_selects is a list im getting from PHP to save state when the page is refreshed... this works well.

    this very last one cust_val: customer.val().join(",") is where i was hoping that the selected values from the customer list would be passed to the server via ajax. ....

    However it passes the enrtire list not just selected values. I know this is sorta right because an alert function shows only the selected values

    Any help fwill be greatly appreciated

  33. Remy, I'm not sure if someone commented this before, but I guess a good "what's next" is "caching selections", like whenever a user makes selections in a child, then changes the parent, and changes back again, the child will still remember the selection.

  34. Is there anyway to send dynamic data?

  35. In case of an error, is there anyway to clear all dependent select boxes?

  36. Thank you for this great code. It works perfect!

    Please allow me one question. I would like to make the trigger only on select. How could I do this? The way it is right now, it pulls the data for argument AND element at once. I would like to only pull data if the user selects a field.

    Kind regards, Merlin

  37. Hi, Thanks for the gr8 plug-in..
    I have a situation where I need to chain two select boxes - both of them are created at runtime.. how can I use selectChain on runtime elements ?

    In the same function where I create two select boxes - I do the following but doesnt work - Any suggestions !!

    $('#newID > #Select1').selectChain({
    target: $('#newID > #Select2'),
    ....
    }).trigger.('change');

  38. Can someone please help me??? I have two selects on my form. I want to update the second select using an ID from the first select. When I make a selection from the first select I get the javascript pop-up "an error occurred".

    The following is the relevant code from my PHP page:

    
    
          <script type="text/javascript">
          <!--
          // chained selects - see: http://remysharp.com/2007/09/18/auto-populate-multiple-select-boxes/
          $(function () {
             var select1 = $('#frmAssignedUserID');
             var select2 = $('#frmAssignedAssetID');
    
             // note that we're assigning in reverse order
             // to allow the chaining change trigger to work
             select1.selectChain({
                target: select2,
                url: '/support/iss-100.php',
                type: 'post',
             }).trigger('change');
    
          });
          //-->
          </script>
    
          <!-- assigned user id -->
          <div style="display: block; height: 2.5em;">
             <label for="frmAssignedUserID" class="txtlabel">Reported By:</label>
             <span><select id="frmAssignedUserID" Name="frmAssignedUserID" size="1">
                <?php
                // get active users
                $query = 'select `userid`, `UserFullName` from `dbMain`.`view_users`';
    
                $result = mysql_query($query) or die (mysql_error());         // query executed
                $totalrows = mysql_num_rows($result);
                $i = 0;
                while ( $i < $totalrows ) {
                   $id = mysql_result($result,$i,"userid");
                   $name = mysql_result($result,$i,"UserFullName");
                   // output select option
                   echo '<option style="padding: .15em .5em;" value="'.$id.'">'.$name.'</option>';
                   // increment row counter
                   $i  ;
                }
                ?>
             </select></span>
          </div>
          <!-- /assigned user id -->
    
          <!-- assigned asset id -->
          <div style="display: block; height: 2.5em;">
             <label for="frmAssignedAssetID" class="txtlabel">Asset:</label>
             <span><select id="frmAssignedAssetID" name="frmAssignedAssetID" size="1">
                <option></option>
             </select></span>
          </div>
          <!-- assigned asset id -->
    

    This is the JSON data supplied by ISS-100.PHP:

    
    [{"id" : "20", "label" : "Verizon AirCard"},{"id" : "247", "label" : "USB Media card reader"},{"id" : "85", "label" : "Blackberry"},{"id" : "140", "label" : "AP01-063-505"},{"id" : "165", "label" : "AP01-023-A08"},{"id" : "211", "label" : "AP01-063-609"},{"id" : "910", "label" : "Brother Intellifax 750 fax machine"},{"id" : "306", "label" : "USB Bluetooth Adapter"},{"id" : "310", "label" : "Aten USB to DB9 Serial Adapter"},{"id" : "357", "label" : "Tripp Lite Power Inverter"},{"id" : "387", "label" : "Linksys WRT54G Wireless Router"},{"id" : "319", "label" : "AP01-063-408"},{"id" : "695", "label" : "Medeco Key"},{"id" : "166", "label" : "AP01-TEMP-109"},{"id" : "986", "label" : "Kingston USB flash drive - 4 GB"}]
    

    I don't know where to start and really appreciate any help I can get and the work put into this plugin!

    Thanks,
    Charles

  39. Note the extra comma on "type: 'post'," in the example above has been deleted and the error still occurs.

    Thanks,
    Charles

  40. Hi Remy, thanks for the scipt is works great. Maybe a simple one for you here.
    My site http://www.onlyprojectorlamps.com/website/, all i want to do is echo the Price as a string. The Price is the 3rd chained box which will only echo 1 result, so i dont need it as a SELECT. Can this be echoed into a DIV?
    Your help most appreciated!
    Thanks

  41. I had a small issue in my php page.

    debug indicates me that it exists an undefined index on a line. (line_number)

    In the sql query i Defined an index with Index field(field_reference); and it does not work.

  42. Select value is not sent when "data" isn't setted (at least with jQuery 1.4).
    fix :
    var defaults = {
    key: "id",
    value: "label",
    data: {}
    };

  43. I think I love you! Thanks for the help :)

  44. Ok, I figured out how to attribute different names, and I think I know how to move on further.

    But while this script works in FF and IE-6 (compatibility view) it does not in IE-8. When I select the first box, it says "Error on page". I speak about the demo on this site. What to do?

    And Happy New Year!

  45. Hi there,

    I was just wondering if someone could help me- its great thank you! Althoguh I am trying to do it so that each box has its own db table - not sure the best way to go around this?

    I have got it working so that there are 5 select boxes - thats all fine. But I would like to structure my database in different tables. I have done this- I'm just not quite sure how it all together.

    I hope someone doesnt mind helping.

    Thank you

  46. is there a way to allow text fields to be a part of the select chain? for example.. a user would select something from a list on the left and then on the right instead of a new populated list, there would be a textfield instead for them to type in an entry

  47. Thank you very much for the plugin. I made it work in jquery 1.5.1 just by adding data object in the defaults. But I am having a problem with your plugin when I combine it with the validation plugin.

    I am getting an error: parsererrorjQuery15108477964274968729_1300332796852 was not called

    For some reason it doesn't like the send parameters that were send on the ajax call. The json response from the server is totally identical

  48. It turned out that the latest validate plugin was not compatible with json calls on the latest jquery. So your script was not related at all. I fixed it by using jQuery.ajaxSettings and not window.ajaxSettings

  49. Mike Nicewarner March 24th, 2011 at 2:37 pm

    I'm trying to incorporate your excellent plug-in into my code, and I'm having troubles. I hope you can take a minute or two to help.
    My situation should be fairly simple, only 2 levels, Products and Programs under each Product. I have the back-end working great. It returns the JSON fine when the Product ID is passed in. However, the plug-in keeps failing in the .ajax() function, tripping the error(). It reports a "parsererror", so I know I've messed up something.
    One wrinkle, I have multiples of the Product/Program pairs on my page, identified as "prod_x"/"prog_x", so I need to dynamically call them. Here is my code:

    $('select[id^="prod_"]').selectChain({
    target: $($(this).attr('ID') + ' + select'),
    url: "edit_ajax.php",
    data: { ajax: true }
    });

    I'm not sure if I'm getting the next element correctly. "$(this).attr('ID') + ' + select'" should get the immediate next select element under the current parent, right?

    Anyway, HELP?!?!

    Thanks,
    Mike


  50. var settings = $.extend({}, defaults, options);
    NOT
    var settings = $.extend({}, options, defaults);

    otherwise defaults will override the settings, this code was found in http://plugins.jquery.com/files/jquery.selectchain.js.txt

    code on this site is golden though! Excellent plugin, thank you!

Leave a Reply
Not required

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