Foreword
Thanks to those of you who take the time to read through this article. If you feel like dropping off a vote (and particularly if it's a low one), please include a comment that mentions what the problem was. Feedback is what drives improvement.
Introduction
The Auto-complete control article by zichun has gained much publicity in the last several years. The "Auto-complete" feature (also known as "auto-suggest," named after Google Suggest) greatly increases site usability and enriches user experience. Unfortunately, the original author has given up code support and didn't answer my e-mails. Furthermore, requirements for auto-complete controls have risen in the last few years.
In order to address all script issues and to provide ongoing user support, the auto-suggest control was born. What was changed and fixed:
- Script now supports both offline (via client-side array) and online (via AJAX) way of populating the suggestion list
- Script is now 100% compatible with all major browsers (Mozilla/Firefox, Opera, Safari, Chrome, Microsoft Internet Explorer)
- Script was moved to a single file
- All styling info was moved to CSS
- Memory leaks were found and fixed
- Many useful options added
Setup
At first, you should upload autosuggest.js, autosuggest.css, arrow-down.gif, arrow-down-d.gif, arrow-up.gif and arrow-up-d.gif to your server. Next, assume that we have a simple page with a single input
field:
<html>
<body>
<input type="text"
id="tb" value=""
style="font-family:verdana;width:300px;font-size:12px" />
</body>
</html>
- The first thing you should do is add references to autocomplete.js and autocomplete.css files:
<html>
<head>
<link rel="stylesheet" type="text/css" href="autosuggest.css"></link>
<script type="text/javascript" src="autosuggest.js"></script>
</head>
...
- Next, initialize the auto-suggest control with the
id
of the bound INPUT
element:
<input type="text" id="tb" value=""
style="font-family:verdana;width:300px;font-size:12px" />
<script> new autosuggest("tb"); </script>
If you wish to use a static client-side array:
- Create it in the
head
of the page:
<head>
<script type="text/javascript" src="autosuggest.js"></script>
<script>
var customarray =
["apple", "alligator", "banana", "elephant",
"pear", "kingbird", "kingbolt", "kingcraft",
"kingcup', "kingdom", "kingfisher"];
</script>
</head>
- Pass it as a second parameter to the
autosuggest
object:
<script>
var obj = new autosuggest("tb", customarray);
</script>
- Make sure that the
autosuggest_url
variable at the very beginning of autosuggest.js is empty (""). You can change the bound static array at any time with the help of bindArray
method:
var customarray2 = [ ... ];
...
obj.bindArray(customarray2);
This is particularly helpful if you want to create linked autosuggest controls.
Note: To use all advantages of caching, consider moving custom_array
to either autosuggest.js or any other external JavaScript file.
If you wish to retrieve suggestions through AJAX:
- Pass the URL of the server-side script (that will be used to retrieve the suggestion list) as a third parameter to the
autosuggest
object:
<script>
var obj = new autosuggest("tb", "", "http://mysite.org/suggest.asp?");
</script>
Note: Be sure to append the ?
symbol at the end of webservice's URL.
Optionally, you can set the global autosuggest_url
variable (inside autocomplete.js) to the path of the server-side script; then you can avoid the third parameter of autosuggest
(this may be useful when you use several autosuggest controls on a page). However, if you do specify that third parameter, it overrides the global autosuggest_url
.
Note: Script awaits the returned data to be the following XML:
="1.0"="UTF-8"="yes"
<listdata>item1|item2|...</listdata>
(i.e. a set of strings, delimited by a vertical bar character, inside a single listdata
tag.)
Note: The delimiting |
(vertical bar) is the default one; ajax_delimiter
variable controls this.
- Similarly to static array, you can re-bind the webservice URL at any time with the help of
bindURL
method:
obj.bindURL("http://mysite.com/suggest?");
Options
When testing the script locally, the Mozilla/Firefox browser will not allow you to make AJAX queries due to security limitations. Circumvent this by uncommenting the following inside autosuggest.js:
If you wish to use up/down arrows instead of a scrollbar in this control, you can change the use_scroll
variable to false
.
By default, the script populates the suggestion list with all items that start with a string that the user typed. If you wish to change it, thus having all variants that contain the typed string, set the limit_start
variable to false
. Otherwise, it is recommended to keep it true
.
If you choose limit_start
variable to be false
, you have one more option to look at: match_first
. It controls the order of the suggestions' appearance. Set to true
, it first shows all the items that start with a string that the user typed, then all other items that contain the typed string; set to false
it shows all items in the order that they appear in an internal array, regardless of part matching.
If you have several input/combo boxes on a page, and encounter a situation when a suggestion list is rendered behind one of the other controls, you should change the use_IFrame
variable to true
. Otherwise, it is recommended to keep it false
.
By default, the suggestion list is not displayed until a special timeout - response_time
- elapses; this is done to improve usability (and save a bit of traffic for AJAX users). You can change it to fit your needs.
By default, no item is selected when the suggestion list first opens. This can be controlled by changing the no_default
variable of autosuggest
object to false
.
Currently, the script loads suggestion variants only once - when the user enters the first character; then the actual filtering occurs. If you wish to set up a more sophisticated filtering technique, consider changing the full_refresh
option that instructs the script to make an AJAX call on every key pressed.
If you wish to use the autosuggest
object as an ordinary select
element, you can look at the selectedIndex
property that contains the index (zero-based) of the selected suggestion.
You may want to restrict the typing and selection to the predefined set of values. In this case, use the restrict_typing
option (works with client-side array only); it won't allow a user to type the value that isn't in the key array. Please take a note that this option doesn't safeguard the text field from accepting the "wrong" value (by pasting it from the clipboard, for example) - so server-side checks are always a good thing.
One more thing you can do is to turn this auto-suggest control into an AJAX-powered select
is to use the key/value pairs instead of an ordinary strings; together with a selectedIndex
, this can be used to retrieve item's value. The case for a client-side array is:
<head>
<script type="text/javascript" src="autosuggest.js"></script>
<script>
var customarray =
[['apple', 1], ['alligator', 2], ['banana', 3],
['elephant', 4], ['pear', 5], ['kingbird', 6],
['kingbolt', 7], ['kingcraft', 8],
['kingcup', 9], ['kingdom', 10], ['kingfisher', 11]];
</script>
</head>
And the AJAX string must be:
<listdata>key1,value1|key2,value2|...</listdata>
Note: Delimiting character (comma by default), that separates the key and the value, can be controlled with item_delimiter
property.
autosuggest
constructor function can also accept the 4th parameter - reference to a function, that is called when user selects a suggestion:
new autosuggest("tb", customarray, null, function(index, control)
{
alert("You've selected the key: " + control.keywords[index]);
});
Function is given two parameters: the index of a selected item (in the keywords
array) and the reference to a control object that called this callback function.
The End?
No, of course. Feel free to post your questions in the forum below, e-mail me if you have questions, and please vote for this article. :) I'll try to answer all requests and provide user support.
Enjoy!
History