DHTML ComboBox Widget

With the wife and kid out of town, I didn't have much to do, so I spent the afternoon building a simple DHTML combobox widget. Yes, I'm that much of a geek. I haven't done a lot of testing, but I built it exclusively in FireFox, aiming for compatibility, and IE6 behaved exactly as expected on the first try, so I'm hoping other browsers will behave as well.

It's available for download at widgets.zip, a demo is available at /web/widgets/ (try entering the letter 'a'), and there is a project page as well. The demo is included in the zip file as well.

The architecture will likely seem a bit odd at first, but it's built the way it is for good reason. In a nutshell, you put an INPUT in your document, and pass it's ID and a callback function to the ComboBox constructor, and the rest happens by magic. You'll notice that you don't pass in any options, but that's where the callback function comes in. That function will be called any time the value entered in the field changes and the field has focus, and will be passed the current value. It's responsibility is to return an array of strings that should be displayed.

The demo just uses a simple array of names for the values, but I set it up in the seemingly overflexible way specifically to allow for JS remoting calls to be used for generating the dropdown list. Currently, you only get synchronous processing (since the callback has to return the values), but I might add async capabilities (so your can pass in an array of options at any time).

As always, download and run with it, and give me any feedback you have along the way.

22 responses to “DHTML ComboBox Widget”

  1. Roland Collins

    How about adding "onBlur" selection in addition to the enter key? That way, when you tab to the submit button, your selection is entered :)

  2. Barney

    Yep, I actually just got finished added a listener for the tab key to choose the current selection. Don't want to do it onblur, because you might not want to take the selection if you go click somewhere else or the like. A new zip file will be coming shortly.

  3. Alexei White

    Neat! How about external datasource. Here's another jsp type combo. Thoughts?


  4. Barney


    You can definitely implement that kind of behaviour with the combo box exactly as is. In fact, that's precisely the usage that I designed it for. Inside callback function you just do your JS remoting calls or whatever and update the option list based on the results.

  5. Thilo Haas

    Nice Script, but I have a problem. If the input-field is at the bottom of the window, the div is not displayed. In this case, the div maybe displayed on the top of the field.

    Greetings from Germany


  6. Hartvig

    Excellent work. I've just integrated it into our open source umbraco cms as live search, updating content through Ajax.

    It has been a charm to work with, really excellent. Your wife and child should be more out of town :D

    Niels Hartvig
    Founder, umbraco project

  7. Barney


    Yeah, that'd be a problem. Should be relatively easy to fix, just do a check for how far from the bottom of the browser the field is, and if it's less that the height of the dropdown, put the dropdown on top.

    I'll be revisiting the widget at some point to fix this and various other little issues, but right now we're in the middle of a cross-state move, so it's going to be a bit.

    Glad you like it though, and thanks for the feedback.

  8. Thilo Haas

    Next Problem ;-)

    We have an scollable Div, where the combo-box is insert. If the div is higher than the window and the combobox is at the end of the div-content, the script calculate the wrong position, somewhere out of the window. :-(

    Any idea, how to fix this problem?

    Anyway – it is a excellent script. We use it for dynamic forms with ajax. The ajax-response is an javascript, which fills us the item-array.

    Greetings from Germany


  9. Thilo Haas

    I fixed the problem with prototype.js: http://prototype.conio.net/

    In stead of:
    var offsets = Utilities.getOffsets(this.field);

    I use now:
    var scrolloffset = Position.realOffset(this.field);
    var pos = Position.cumulativeOffset(this.field);

    offsets.x = pos[0]-scrolloffset[0];
    offsets.y = pos[1]-scrolloffset[1];

    And it works fine!

    Greetings from Germany


  10. Barney

    Good catch, Thilo. I'll make sure that mod tweak (or something equivalent) makes it in next time I update the widget. Still decompressing from the move, and I've already got a backlog, so it'll probably be a while.

  11. Stephen M

    Does anybody get a problem using Internet Explorer 6 where, if you've got an actual combo box or list directly underneath this DHTML Combo Box the listing on the DHTML combo box comes out *behind* the native combo box or list in spite of any z-index fiddling that you may do.

    Is this a bug with IE or am I missing something?

  12. Barney


    It's not a bug, per se, but just the way it works. IE uses native Windows UI widgets for certain things, notably SELECT elements, and HTML stuff can't float over the top of them. IE7 is supposed to fix this, but we'll see.

    I haven't implemented it at this point, but the solution is for the ComboBox to detect if it's overlapping any SELECT elements, hide the SELECT elements, and then when the dropdown goes away to make them visible again. If you want to implement that and contribute the mods back, that'd be great. You'd get full attribution, of course.

  13. Julian Halliwell

    I'm not the JS guru I would like to be, but adding the following lines to both the showDropDown and hideDropDown functions right at the bottom of combobox.js (replacing 'none' with 'block' as appropriate) seems to solve the IE under-lapping problem.
    if(this.config["selectToHideInIE"] && (document.all)){
    var IDtoToggle = this.config["selectToHideInIE"];
    document.getElementById(IDtoToggle).style.display = 'none';
    When init'ing the combobox you just pass in a config object (struct) as the third argument containing a key named "selectToHideInIE" with its value being the DOM id of the select you want to get out of the way. E.g.
    var config = new Object();
    config.selectToHideInIE = "mySelectID";
    box = new ComboBox(boxID, getItems, config);
    Barney, feel free to use and improve. Incidentally I did try using your internal getConfigParam method, but I couldn't get it to work with hideDropdown for some reason.

  14. Barney

    Thanks Julian. Next time I've got some free time, I'll make sure these mods (or something like them) get included.

  15. Tradone

    Alexei, that link that you provided was excellent. I did not know those things could be done.

  16. JCH2

    Nice to see and actually 'Combo' box… finally, as most of what's out there using this label are actually 'Select' boxes where one cannot type in an alternate entry.

  17. Luuk Lamers

    To add a dropdown button (click…POOF!!! Dropdown)
    simply add:

    after the first input box…

  18. Luuk Lamers

    okay…again to actually see the code…
    any element with onclick="getElementById('f_name').comboBox.valueChanged()"
    will be changed into a dropdown-show-up (mocking though) button

  19. sriram

    how to float a menu or drop down over the combobox in html

  20. jone

    i didn't find any demo or download on given page please advice …

  21. lokesh

    i have used this one of my current project, fetching value through AJAX.