Christian Heilmann

Unobtrusive connected select boxes – yet another solution approach

Saturday, March 17th, 2007 at 12:54 am

Update#2: the third demo allows for preselect states and unlimited levels by using a nested UL and radiobuttons enjoy.

Update: the second demo now allows for preselect states and shows the first dropdown enjoy.

The interface element of connected select boxes (one select box changing the options in the other one) is one of the most used and also most annoying elements of web application design. While it works nicely for anyone having JavaScript enabled and using a mouse it can be a nightmare to use with a keyboard (unless you know that you can expand the whole list with alt+cursor down first).

The other problem is that you make yourself dependent on JavaScript with them and I don’t even want to know what the implementations for screen readers are.

That said, it simply does not die out, people love it. The scary thing is that there are dozens of JavaScript solutions to the problem and almost all of them make you dependent on JavaScript. I’ve tried in the past to come up with solutions for it using for example nested HTML lists in this Alistapart article. What scares me most is that the demo code for a bad solution seems to have ended up on several “Script Library” sites and I get emails coming in thanking me for the great solution!

My personal favourite is keeping the functionality independent of a mouse and JavaScript and using Ajax to populate the second drop down as explained in my book, but that is too complex for a lot of owners of web interfaces.

So today, once again the request for connected select boxes reared its ugly head and my esteemed colleague Bradley Wright took it onto himself to solve the issue (working with this guy does rock – believe me). His approach was to create a massive dropdown with all the information and then use JavaScript to chunk it up. Originally he tried class names on the different options to connect them until he asked me to take a peek and I liked the idea but advocated for optgroups instead (the lesser known select child element).

So, the markup for the non-JavaScript version is the following:

All we need now to turn this into connected select boxes is the folllowing:

  • Create a new select element
  • Loop through all optgroups and create a new select box for each and hide them
  • Loop through the options collection of each optgroup
  • Take the first option and add it to the new main select element
  • Move the other options to the select box connected with this optgroup
  • Apply an onchange handler that reads the selectedIndex value of the main select element and shows the select box with the same number, hiding the previous one
  • Apply the correct secondary name to the currently shown select box
  • Remove the original select box
  • Apply the name and ID of the original to the new main select box

Another option is of course to store the data in an object and re-populate the secondary select box every time the first is changed. However, I wanted to avoid that to speed things up.

Check out the example of this technique and tell me what you think.

Share on Mastodon (needs instance)

Share on Twitter

My other work: