Home arrow JavaScript arrow Javascript AutoComplete
JAVASCRIPT

Javascript AutoComplete


Web designers must always keep usability in mind when designing web sites. A site must allow quick and easy access to information during the very short time that a site first holds a visitor's interest. Any confusion that ensues about where things are, and that person's business is gone. Providing a way to precisely search for what they need is an excellent way to provide that usability. What Chris Root explains in this article is a way for your visitors to find and select items contained in long lists. He will also suggest ways to expand this to searching within HTML or XML documents.

Author Info:
By: Chris Root
Rating: 3 stars3 stars3 stars3 stars3 stars / 94
June 08, 2005

print this article
SEARCH DEVARTICLES

Web designers must always keep usability in mind when designing web sites. A site must allow quick and easy access to information during the very short time that a site first holds a visitor's interest. Any confusion that ensues about where things are, and that person's business is gone. Providing a way to precisely search for what they need is an excellent way to provide that usability. What Chris Root explains in this article is a way for your visitors to find and select items contained in long lists. He will also suggest ways to expand this to searching within HTML or XML documents.

Auto-Complete

Many desktop applications have user interface controls that allow a user to find matches for things as they type. This feature can be very useful for long lists of items such as states, countries, streets or product categories. Many web browsers implement this sort of functionality in their address bars. As you type, web site address matches that are part of a list of recently visited sites appear in a menu below the address bar. This reduces the amount of time it takes to access information.

Another place this is implemented is in HTML select menus. Unfortunately this only works with the first letter typed, it is not implemented in all browsers on all platforms and it doesn't shorten the list of choices to only matches.

The script described in this article will allow a user to begin typing what they are looking for in a text box while a select menu updates itself with matches. In the example the list comes from the contents of the select menu but it can also come from other sources.

The HTML

The HTML for this project is pretty simple. You could however use this script several places in a large form with multiple lists of information with no trouble. This example uses a list of city streets.

<body onLoad="fillit(sel,entry)">
<div>Enter the first three letters of a street and select a match from the menu.</div>
<form><label>
Street
<input type="text" name="Street" id="entry" onKeyUp="findIt(sel,this)"><br>
  <select id="sel">
        <option value="s0001">Adams</option>
        <option value="s0002">Alder</option>
        <option value="s0003">Banner</option>
        <option value="s0004">Birchtree</option>
        <option value="s0005">Brook</option>
        <option value="s0007">Cooper</option>
<!--and so on and so forth-->
  </select></label>
</form>
</body>
</html>

When the text box registers a keyUp event, the find() function calls and passes two parameters, the id of the select menu and a reference to the text field.

For something like state information, allow the user the choice of using the auto-complete script or just selecting something from the menu, especially if they know the item they wish to select is at the top of the list. If someone lives in Alabama for instance, there is no need to have them enter the first three letters of their state when the item they want is at the top of the list of states. Fill the select menu (a list box can be used as well) with all the values and text labels that you want your user to choose from in the HTML code to start with.

Alternatively, depending on the information in the list, the choice may not be as obvious. In this case you could store it in an array only and the user would always need to select a match. If there was only one match, and that match was the correct one, they could leave the menu alone. Otherwise they would need to select from the available matches displayed in the menu.

The longer the list the more useful our script becomes. It has been tested with a list over 1000 city streets and had an acceptable performance, even on a not so modern machine. There is a minimum of two characters before a search will start. this helps reduce the number of matches shown after any given keystroke. This limit can be adjusted easily.

When the page loads, a function called fillit() is called.

//initialize some global variables
var list = null;;
function fillit(sel,fld)
{
        var field = document.getElementByid(fld);
        var selobj = document.getElementById(sel);
        if(!list)
        {
                ar len = selobj.options.length;
                field.value = "";
                list = new Array();
                for(var i = 0;i < len;i++)
                {
                        list[i] = new Object();
                        list[i]["text"] = selobj.options[i].text;
                        list[i]["value"] = selobj.options[i].value;
                }
        }
        else
        {
            var op = document.createElement("option");
            var tmp = null;
            for(var i = 0;i < list.length;i++)
           {
                tmp = op.cloneNode(true);
                tmp.appendChild(document.createTextNode(list[i]["text"]));
                tmp.setAttribute("value",list[i]["value"]);
                selobj.appendChild(tmp)/*;*/
           }
        }
}

A global variable is initialized to null. This will hold an array that in turn holds two custom objects to hold our data. We then get a reference to our select menu and text field objects. If our array does not exist yet (the page has just loaded so it’s still null), then we get the number of options in our select menu, set the contents of the text field to empty and begin looping through the menu contents.

As we run through each menu option, an object is created that will hold both what is in the value attribute and the text of the option tag.

If however our list array already exists, we are calling the function in order to refill the menu with all the original data. An option element is created and a temporary container is initialized.

In the loop the select menu is reconstructed using DOM methods.

Finding a Match

The findIt() function does the searching. It accepts two arguments. The first is the name of the select menu, the second is the name of the text field.

function findit(sel,field)
{
        var selobj = document.getElementById(sel);
        var d = document.getElementById("display");
        var len = list.length;
        if(field.value.length > 2)
        {
                if(!list)
                {
                        fillit(sel,field);
                }
                var op = document.createElement("option");
                selobj.options.length = 1
                var reg = new RegExp(field.value,"i");
                var tmp = null;
                var count = 0;
                var msg = "";
                for(var i = 0;i < len;i++)
                {
                        if(reg.test(list[i].text))
                        {
                                d.childNodes[0].nodeValue = msg;
                                tmp = op.cloneNode(true);
                                tmp.setAttribute("value",list[i].value);
                                tmp.appendChild(document.createTextNode(list[i].text));
                                selobj.appendChild(tmp);
                        }
                } 
        }
        else if(list && len > selobj.options.length)
        {
                selobj.selectedIndex = 0;
                fillit(sel,field);
        }
}

The first step is to get references to the select menu and the text field. We also need the length of the list array.

If the number of characters in the text field is greater than 2 and the list array exists. Then the menu is cleared of it's content to prepare it for display of any matches. The number of options is set to one rather than 0 to allow for an option that is always there such as a “Select a Street” option.

A regular expression object is then created that will be used to look for a match at the beginning of a given string. Using this object to create a regular expression allows the use of a string from whatever source we wish to be used along with any regular expression characters. The first parameter in the object constructor is the regular expression the second is any flags such as "i" for making the search case insensitive. If you were searching something other than one or two word street names, state names or country names you would want to match the beginning of word boundaries using "\b" instead of "^".

A few utility variables are initialized and we then loop through each of the list items contained in the arrays. If there is a match, the values are used to fill a new copy of the option element we created before the loop started. One thing to note about setting the properties of option elements is that the text label of an option is not an attribute. You must use the optionelement.text syntax rather than setAttribute to set the text label for each option.

If the length of the text in the field is less than 2 characters then we need to determine if the list needs to be refilled with all the values. By doing this, you allow the user to give up on their search before typing more than two characters and manually select something from the menu if they wish. If the user selects the text in the field and clears it to start a new search this will trigger that action. The fillit function is called and the select menu is refilled.

Possible Mods

To make this script and user interface more like the auto-complete widget in a browser address bar, you could use a DHTML menu and provide keyboard control for selecting a match and updating the content in the text box with the selected match.

This script would allow searching in any array of information and with a little modification any HTML collection. Searchable FAQ's, API documentation or help systems could be achieved by searching content contained in a hidden IFrame, the main HTML document itself or an XML document loaded in the background using the HTTPRequest object.

Conclusion

As you can see using auto-complete widgets on a web site can allow a visitor quick access to information. Always be on the lookout for ways to improve the user experience for your visitors and they will continue to come back for more.


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

All JavaScript Tutorials
More By Chris Root


blog comments powered by Disqus
JAVASCRIPT ARTICLES

- Project Nashorn to Make Java, JavaScript Wor...
- JavaScript Virus Attacks Tumblr Blogs
- Google Releases Stable Dart Version, JavaScr...
- Khan Academy Unveils New JavaScript Learning...
- Accessing Nitro? There`s an App for That
- JQuery 2.0 Leaving Older IE Versions Behind
- Fastest JavaScript Engine Might Surprise You
- Microsoft Adjusting Chakra for IE 10
- Brendan Eich: We Don`t Need Google Native Cl...
- An Overview of JavaScript Statements
- An Overview of JavaScript Operators
- Overview of JavaScript Variables
- More of the Top jQuery Social Plugins
- The Top jQuery Social Plugins
- More of the Top jQuery Slider Plugins

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials