Monday, June 23rd, 2008

Combobox Coolness by Giva Labs

Category: jQuery

The team at Giva Labs were looking for a method to show off a complex hierarchical tree of options within their software applications and while there are many options in terms of UI controls, they needed something that would be intuitive and offer both mouse and keyboard entry. The requirements were challenging:

  • Menus must resize and position themselves to stay in the viewport. Options should not show up off screen where users would need to scroll to select them.
  • Quick keyboard entry. Many users prefer keyboard entry for speed of data entry, so efficient keyboard entry is a must.
  • Must be able to handle very large complex (deep) data trees, but work equally as well with very small sets of data.
  • Easy implementation.

Taking the “homegrown” approach, they came up with a very slick hierarchical combo box which they’ve called mcDropdown. Some of the features of mcDropdown include:

  • Creates a multi-column hierarchical select UI component
  • Binds a text input field or div element to a list element (included nested lists)
  • Menus are automatically split into columns as needed
  • Menus are positioned to always stay on the screen
  • Autocomplete keyboard entry (only valid options are allowed)
  • Menu automatically scrolls into viewport when opened

Although originally designed for internal usage, Giva generously released this jQuery plugin under the Apache License. They’ve also documented the extension clearly and provide excellent examples on how to implement the control.

Posted by Rey Bango at 7:34 am

3.8 rating from 24 votes


Comments feed TrackBack URI

A nice idea for some limited uses. I don’t think it’s terribly portable, however, as the sizing of the root menu must anticipate the depth of all possible paths, which is not an easy problem to solve, as well as opening up the case that the root menu might need to extend across an entire page, for example. This is more a demonstration of why menus are done the way they are, “flying off” to the right… More directly, designers and developers will shy away from menus whose width is dependent on something other than their desires.

Comment by sandro — June 23, 2008


This was designed to be used as a form input control (and not really for a “menu” per se.) A lot of time was spent on the sizing aspects of the drop downs and it’s been tested with a large variety of different data configurations and as you mentioned it was not an easy problem to solve.

As you stated, this isn’t a solution for all use cases. It does work really well for our use case and we thought it would work well for others (which is why we released it as open source.)

Comment by DanSwitzer2 — June 23, 2008

So what’s the difference with mcDropdown and (aside from being on top of a select box) a drop down menu?

Comment by ibolmo — June 23, 2008

HTML drop-down menus don’t have the same tree-like branching. It’s best to click around the demo to get a real sense for it though.

It’s sort of like an expandable tree meets drop-down hybrid.

Comment by shypht — June 23, 2008

@shypht, that’s what I meant.. there’s even CSS implementations:

But thanks, I just noticed what you mean by clicking on it. It’s a sort of a directory/menu hybrid. I noticed, though, that there’s no way to go back/up a selection.

It’s an interesting idea, though.

Comment by ibolmo — June 23, 2008


When you click “inside” the text box, you actually enter the keyboard entry mode (so you can go back a node by hitting delete.) If you click the “dropdown” arrow, you’ll get the columnized suckerfish-style menu.

We have 2 distinct types of users–ones who just use the keyboard and ones that use the mouse for everything. We’re trying to accommodate both groups with a single control.

Comment by DanSwitzer2 — June 23, 2008

That’s a really well-done jQuery plugin IMO, and you will not understand how much effort to be spent on it until you try on your own :). Thanks for sharing your work ;)

@DanSwitzer2: It will be an almost perfect combo-box if you improve it further more with AJAX requests to fetch the sub-trees data on demand (or cache certain top levels 1st), instead of having to build all the unordered-lists at the beginning :). Sometimes the number of records are too many to be displayed all over the screen, so paging on the fly is even greater (a small page selector at the bottom of the list layer)

Comment by NKTPRO — June 23, 2008

No doubt, and thanks for releasing. It is mentioned that this was built for a particular project, and you giving it up is a nice thing to do. Again, for some uses, quite nice.

Comment by sandro — June 24, 2008

Great product!

One issue I have found with it though. If you have the mcdropdown within a div element who’s style.display is set to “none” (i.e. hidden) it does not initialise correctly if you call the code:

$(document).ready(function (){

You will find that when your div block is made visible again (e.g. .style.display = “block”) then the width of the input box is zero – meaning when you come to choose an item from the menu you then cannot see what you’ve chosen.

I found a way around this which was to call the initialisation code when setting the div element’s display to block (or inline). e.g

function setDivToDisplay(divID) {
document.getElementById(divID).style.display = “block”;
// Initialise McDropdown once the div is visible again

Anyone who’s used client side tabbing such as DOMTAB may face a similar issue. We’ve had to put a call in from DOMTAB to our method when setting the Tab to display to call the initialisation method of McDropDown.

Comment by ctidave — July 3, 2008


We’ve just released a patch which should resize the input box correctly regardless if the input is visible at init time. This should remove the need for your fix.

Comment by DanSwitzer2 — July 14, 2008

Thanks for the fixes. I may have found another small bug. In IE7 you cannot seem to select the input box for keyboard input. It will let you tab to it though. Seems fine in Firefox.

Comment by ctidave — August 5, 2008

I have another issue. When an option is picked from the menu and the call-back code is launched for “select” (which I added to the options) then the .getValue() function is returning me the value I picked (stored in the “rel” attribute of the LI) plus the current value of the displayed box. This seems wrong to me as surely you’d want to pass back the text of the selected item and not the previously selected item? As you can see from this example (I made a small change to the “gettingstarted.htm” file to show the problem), pick “Education” for the first time and you get back “9,” from getValue(). Then select “Health” and you get “10, Education” from getValue().

Here’s the example code:

// on DOM ready
$(document).ready(function (){

var options = {
$(“#category”).mcDropdown(“#categorymenu”, options);
function menu_option_chosen() {
var dd = $(“#category”).mcDropdown();


Comment by ctidave — August 5, 2008

I’ve done a fix for this which is in the getValue function change the call return [$hidden.val(), $self[bInput ? “val” : “text”]()] to return [$hidden.val(), displayString($hidden.val())]

Comment by ctidave — August 29, 2008

Leave a comment

You must be logged in to post a comment.