Skip to Content

jQuery Combo Boxes

With web applications, I find that I often need to create a drop down list that contains hundreds or maybe even thousands of possible options. And then I often need to have many rows that contain the same drop down list, resulting in very large amounts of page size (which means slower page loads) going to just populating the list. I've tried using an autocomplete type box in their place with some success, but users don't like them.

For instance, if the drop down list is for contact names at a specific company, they may type in "bob", expecting to find the entry, but the actual entry may be under "Robert" instead and he just goes by "bob". With the drop down list users can peruse the options and select the most appropriate one. With the autocomplete box, we don't need to know EVERY possible person before showing the page. The two options seem at odds with each other.

There is a solution though. Desktop application handle this with a "combo box". A combo box allows the user to type out a value OR select a value from a list. The standard web form tools do not allow this though, instead we only have a select box. There are JavaScript solutions out there though - jQuery's UI allows a select box to be turned into a combo box. Their solution seems overly complex though, when the autocomplete box has a hidden feature that makes life very easy.

The solution I have found and am currently liking muchly is to make use of a autocomplete box as per normal. Then put a jQuery button beside the box. Now when this button is clicked, it triggers the autocomplete without a search term - which means you see everything.

Here's some sample code (not this particular code has not been tested, so use it as a guide only!):

HTML:

  
  

JavaScript:

$(document).ready(function () {
  //setup the button
  $('button.acDropdown').button({
    icons: { 
      primary: 'ui-icon-triangle-1-s',
      text: false
    }
  });

  //Add code to turn the textbox into an autocomplete
  $('input[name="people"]').autocomplete({
    // ... add appropriate settings ...
  });

  $('button.acDropdown').click( function () {
    //get reference to autocomplete box
    var acbox = $(this).siblings('.ui-autocomplete-input');
    //remember the minLength value on the autocomplete box
    var minlength = acbox.autocomplete('option', 'minLength');
    //set the min length to zero
    acbox.autocomplete('option', 'minLength', 0);
    //trigger the search with no search term
    acbox.autocomplete('search', '');
    //restore the minLength value
    acbox.autocomplete('option', 'minLength', minlength);
  });
});

The HTML simple creates an input box, and a button object.

The JavaScript tells jQuery the button object should be a jQuery UI Button. Next it sets up the Autocomplete. And finally, it handles when the button is clicked.

When the button is clicked, we find a reference to the autocomplete box. In my case, the autocomplete and the button are within a table cell and there is only one autocomplete per cell. So I can simply ask for the sibling element with the autocomplete class. To make our drop down list work as expected, we have to be able to search with an empty search term. This will not work if we have a minLength set greater than zero. So, we store the current value temporarily, and then set the minLength to zero. Then the magic takes place - we trigger the search method of the autocomplete, passing an empty string as the search term. If we did not pass that empty string, then the autocomplete will use whatever is in the textbox as the search term. Now that the search has been triggered, we can set the minLength back to it's original setting.

The nice thing about this approach is that we don't need to hide/remove HTML elements, and there are far fewer lines of code involved than the default sample - so less chances of errors. But more importantly, how we setup the autocomplete doesn't matter - it can use local data, a remote URL, or a custom callback. The drop down code will still fire and just use whatever has been set up.

And that is it. All that is left now is to apply a little styling to make the combo box look the way we want. NOW, the user can type in their values AND/OR look up the values on demand. If my autocomplete makes uses of an AJAX call then I don't need to load the data at all when my page loads. Or better yet, if my autocomplete makes use of the callback method, then I can set up an AJAX call that caches it's results, resulting in even fewer database hits and faster responses. A nice happy solution for everybody, it seems.

I'm sure I'm not the first to come up with this, but if so I have not seen any other documentation that describes this (yet). Of course now that I've taken the time to work it out myself and document it, I'll be finding it everywhere else - Murphy's Law is like that. Anyways, I hope this has been helpful.