Anything that can be automated should be

I’ve been using a few bits of YUI’s widget library lately and am constantly surprised by the markup requirements they list in the examples. For example, if you want a text field to be autocompletable, you need to use the following markup:

<div id="myAutoComplete">
    <input id="myInput" type="text">
    <div id="myContainer"></div>
</div>

Given their stated commitment to accessibility I’m surprised that they make requirements like this. This code makes precisely zero sense for users with JavaScript disabled; the elements are set up purely for the purposes of supporting JavaScript widgets. As such, they ought to be generated using script rather than hard-coded into your templates wherever you want an autocompleter. Worse, I can see some folks writing template helpers to generate this markup and the associated script, thus tightly coupling the scripting layer to the markup and giving script-disabled users (and search bots) a raw deal.

So, what to do? Well, you need to start out with sensible markup that makes semantic, machine-readable sense.

<input id="myInput" type="text">

Looks good to me. Now, the important point is that we need the same wrapper markup for each autocompleter instance, so the creation of said markup can be automated. Let’s write a little script helper to make it easier to create autocompleters around text fields without assuming any extra pre-existing structure (this example uses Ojay).

var autocomplete = function(inputId, dataSource) {
    var wrapper = $.HTML.div(), list = $.HTML.div();
    var input = $.byId(inputId);
    input.insert(wrapper, 'before');
    $(wrapper).insert(input.node).insert(list);
    return new YAHOO.widget.AutoComplete(input.node,
            list, dataSource);
};

Then all it takes is a quick call to turn your clean semantic markup into an enhanced user interface. Putting the whole thing together:

<input id="myInput" type="text">
<script type="text/javascript">
    autocomplete('myInput', myDataSource);
</script>

Obviously you could add more configuration options in there, this is just meant to get you started. Whenever you see JavaScript documentation telling you to set up your document a certain way, find out whether that setup can be scripted rather than hard-coding it into your markup. Also, look for opportunities to provide sensible defaults if you tend to do something the same way frequently. As long as the developer can override these defaults, they will (one would hope) thank you for making their life that little bit easier.

If you’ve enjoyed this article, you might enjoy my recently published book JavaScript Testing Recipes. It’s full of simple techniques for writing modular, maintainable JavaScript apps in the browser and on the server.