Muffinresearch Labs by Stuart Colville

JSON Selects | Comments (5)

Posted in Code on 19th July 2006, 2:13 pm by Stuart

This is a really simple method to populate select boxes dynamically using JSON as the source of the data. This script is really just a basic example so that you can see how easy it is to work with JSON in this way, you could take this and adapt it quite simply to get data over XHR for example.

It’s also a follow on to my previous post (Bug when creating select options using innerHTML in IE) as it demonstrates using pure DOM methods to create the select box options.

Don’t forget that in the real world you would also need to allow for when javascript is not available to the user-agent and provide a means to update the subsequent select on page refresh.

var objSelData = {
  guitars:{
    "GSG":"Gibson SG",
    "GLP":"Gibson Les Paul",
    "FSC":"Fender Stratocaster",
    "FTC":"Fender Telecaster"
  },
  keyboards:{
    "HRP":"Harpsichord",
    "HOR":"Hammond Organ",
    "FRO":"Fender Rhodes",
    "WEP":"Wurlitzer EP200"
  }
};   

var jsel = {
  // config for first option text e.g '-' or 'Please Select'
  blankOption: '-',
  // Removes the children of the target element
  removeChildren: function(elm) {
     while(elm.hasChildNodes()){
        elm.removeChild(elm.firstChild);
     }
  },
  // Gets current selected value
  getSelVal: function(objSrcSelect) {
    if (objSrcSelect.nodeName == 'SELECT'){
      var children = objSrcSelect.childNodes;
      for (var i=0, j=children.length; i<j; i++) {
        if (children[i].selected === true) {
          return children[i].value;
        }
      }
    } else {
      return false;
    }
  },
  // Creates select options
  createOpt: function(strVal,strText,objTargetSelect) {
    var opt = document.createElement(’OPTION’);
    opt.setAttribute(’value’,strVal);
    var text = document.createTextNode(strText);
    opt.appendChild(text);
    objTargetSelect.appendChild(opt);
  },
  // Loads in the data to the select based on the previous selection
  loadData: function(objData, objSrcSelect, objTargetSelect) {
    var val = jsel.getSelVal(objSrcSelect);
    jsel.removeChildren(objTargetSelect);
    jsel.createOpt(”,jsel.blankOption,objTargetSelect);
    for(prop in objData[val]) {
      if (val) {
        jsel.createOpt(prop,objData[val][prop],objTargetSelect);
      }
    }

  }
}  

  // Use your choice of addevent here…
  window.onload = function() {

    var type = document.getElementById(’type’);
    var instr = document.getElementById(’instr’);
    // …and here
    type.onchange = function () {  jsel.loadData(objSelData, type, instr); return false; }
    if (jsel.getSelVal(type) != ”) {
      jsel.loadData(objSelData, type, instr);
    }       

  };

The way it works is quite simple. The when the first select box is changed this triggers an onchange event which then grabs the value of the currently selected option. It then look find the data that corresponds with that value in the JSON object, blows away the current options in the second select and creates and appends new options to the second select based on that data.

The core operation is in the for loop:

    for(prop in objData[val]) {
      if (val) {
        jsel.createOpt(prop,objData[val][prop],objTargetSelect);
      }
    }

objData[val] is the same as saying objData.guitars when the variable val equates to guitars. If you’ve not come across square bracket notation before it’s the only way you can access object properties with a variable, and as such allows you to loop through the data and access your data to populate the select.

For this week’s homework I would suggest you play around with it and try implementing a xhr solution.

Please check out the JSON Selects example page.

Post Tools

Comments: Add yours

1. On July 19th, 2006 at 2:47 pm Chris Heilmann said:

The removeChildren() is a good generic function but could be quite expensive. You could also remove all options by setting the options.length property to 0, or by simply setting innerHTML to an empty string.
Sometimes the old school form stuff is much faster and straight forward. If I were a fetishist I’d do a benchmark, but the weather is too nice.

2. On July 19th, 2006 at 7:55 pm Stuart Colville said:

@Chris: You make some good points there and those are some viable alternatives. I am not so anal that I must use the DOM for everything, and I can see that that setting the innerHTML to an empty string would be much more likely to be faster compared to my loop.

3. On July 23rd, 2006 at 5:25 am Ismael said:

Nice!
But… Shouldn’t this


keyboards:{
"HRP":"Harpsichord",
"HOR":"Hammond Organ",
"FRO":"Fender Rhodes",
"WEP":"Wurlitzer EP200"
}

be like this?


keyboards:{
HRP:"Harpsichord",
HOR:"Hammond Organ",
FRO:"Fender Rhodes",
WEP:"Wurlitzer EP200"
}

I mean, those are attribute names in an object, not keys in a hash, right?

4. On July 23rd, 2006 at 1:00 pm Stuart Colville said:

@Ismael: Thanks for the comment. Re: the quotes: That’s not the case, in valid JSON, property names are always quoted.

5. On July 23rd, 2006 at 10:46 pm Ismael said:

Wow, that’s kinda shocking! I guess I’ll have to go through thousands of lines of code I’ve made :( (it works, though)







XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Standalone mac battery charger|(0)

Got a spare mac battery? I’ve often wondered why up until now no-one’s produced a standalone charger so that you can charge batteries without having to plug them into the mac. Fortunately Fastmac.com have produced a standalone charger that allows you to do just that. and it’s compatible with iBooks, Powerbooks, macbooks and Macbook Pros. It’s also 110/200v. Exactly what I was looking for!

Django Admin Ominigraffle Stencil|(0)

Colleague Alex Lee has created a nice stencil for omingraffle with the Django Admin UI components, perfect for wireframing customised admin screens. For more details and to download the stencil see Alex’s Blog csensedesign.co.uk

Photos on Flickr

© Copyright 2004-08 Stuart Colville, all rights reserved. May contain traces of Muffin. Powered by WordPress. Hosting by 1&1 This page was baked in 0.902s.