Auto-suggest Control






4.90/5 (117 votes)
This article presents code that augments any INPUT box with an auto-suggest feature, AJAX-capable

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 boundINPUT
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. - Create it in the
-
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 ofautosuggest
(this may be useful when you use several autosuggest controls on a page). However, if you do specify that third parameter, it overrides the globalautosuggest_url
.Note: Script awaits the returned data to be the following XML:
<?xml version="1.0" encoding="UTF-8" standalone="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?");
- Pass the URL of the server-side script (that will be used to retrieve the suggestion list) as a third parameter to the
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:
// try { netscape.security.PrivilegeManager.enablePrivilege // ("UniversalBrowserRead"); } catch (e) { }
-
If you wish to use up/down arrows instead of a scrollbar in this control, you can change the
use_scroll
variable tofalse
. -
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 tofalse
. Otherwise, it is recommended to keep ittrue
. -
If you choose
limit_start
variable to befalse
, you have one more option to look at:match_first
. It controls the order of the suggestions' appearance. Set totrue
, 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 tofalse
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 totrue
. Otherwise, it is recommended to keep itfalse
. -
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 ofautosuggest
object tofalse
. -
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 ordinaryselect
element, you can look at theselectedIndex
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 aselectedIndex
, 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
- August 22nd, 2007 - version 1.0
- Initial release
- August 30th, 2007 - version 1.1
actb
objects are now independent of each other- Scrolling with mouse made possible
- ESC key now closes the suggestion list
- Arrow images now play better with browser caching
- Fixed problem with TAB key switching focus too early
- Fixed problems with INPUT box losing focus (and making auto-suggest control dysfunctional) in some cases
- September 10th, 2007 - version 1.2
- Added the ability to use a standard scrollbar instead of up/down "buttons" (
actb_useScroll
, on by default) - contributed by LTSpeed - Added a workaround for the Microsoft Internet Explorer bug, when suggestion list was rendered behind page controls (
actb_useIFrame
, off by default) - contributed by Jac Steyn - 2 of 4 icons saved with better compression - contributed by Jac Steyn
- Other minor corrections and fixes
- Corrected some misleading statements in the article
- Added the ability to use a standard scrollbar instead of up/down "buttons" (
- September 20th, 2007 - version 1.3
- Fixed faulty
actb_useIFrame
option, now it works OK - Fixed another problem with
actb_useIFrame
option, when the user couldn't select a suggestion with a mouse click - Added the ability to specify a server-side URL for each
actb
object - Added the ability to avoid initial selection of the first suggestion variant (
actb_noDefault
, on by default) - Added the ability to reload a list of suggestions on every key pressed (
actb_fullRefresh
, off by default) - Added the
actb_selectedIndex
property, containing the index (zero-based) of the variant last selected - Various minor fixes and improvements
- Fixed faulty
- October 10th, 2007 - version 1.4
- Added
actb_response
option - Added
actb_firstMatch
option - Added the ability to use key/value pairs (getting close to an AJAX-powered
SELECT
) - Added the ability to use the down arrow key to retrieve the suggestion list (for non-empty
INPUT
box) - Suggestion list is now redrawn only if the user actually changes the text in an
INPUT
box - Fixed the bug when
actb_selectedIndex
wasn't properly assigned when using keyboard to navigate through the suggestion list - Other minor bugfixes
- Added
- January 10th, 2008 - version 1.5
- (Hopefully) solved all problems with suggestion box appearing under the HTML controls ("IFRAME mode")
- Construction of the suggestion box is now significantly faster than before (2x faster for Microsoft Internet Explorer, more than 8x for Firefox)
- Pressing "down arrow" key will now bring all the available suggestions (doesn't work in AJAX mode)
- PageUp and PageDown keys now can be used to scroll the suggestions
- Width of the suggestion box now increases if any suggestion is wider than the suggestion box
- Long suggestions with hyphens do not span multiple lines but increase the width of the suggestion box
- Fixed annoying issue with "'
actb_display
' isnull
or not an object" error - Minor bugfixes
- December 16th, 2008 - version 1.6
- Fixed a bug with incorrect positioning of suggestion list in a scrolling document
- Fixed a Firefox-related issue with lengthy AJAX responses
actb_selectedIndex
now always has the correct value- Building of suggestion list with many (hundreds of) suggestions is now much faster
- You can now easily tune the autosuggest control to use your webservice's output by using
ajax_delimiter
anditem_delimiter
variables. - You can now control the color of current selection's text with
actb_htextColor
- January 30th, 2009 - version 1.7
- Fixed an issue when suggestion list disappeared after user clicked on the scroll bar in Microsoft Internet Explorer and Webkit-based browsers (when using
actb_useScroll
) - Fixed a minor issue with non-canon scrolling behavior when scrolling down (when using
actb_useScroll
) - Fixed a minor display issue when suggestion list was a bit wider than parent input field
- Introduced the
actb_restrict
option, that allows you to restrict typing to the keys of client-side array - Added more comments to the code
- Fixed an issue when suggestion list disappeared after user clicked on the scroll bar in Microsoft Internet Explorer and Webkit-based browsers (when using
- February 2nd, 2009 - version 1.7
- Fixed an issue (introduced in the previous release) that didn't allow focusing other input fields while suggestion box was open (Internet Explorer- and Webkit- related)
- February 8nd, 2009 - version 1.8
- Fixed an issue when, in a scrolling document, suggestion list disappeared after user clicked on the scroll bar in Microsoft Internet Explorer and Webkit-based browsers
(this is an additional patch to an earlier fix) - All global variables (except
suggesturl
) and functions were moved into theactb
object (either as member methods or inner functions), so script now won't interfere with the global namespace - Script was tuned to produce XHTML-compatible output
- Fixed an issue when, in a scrolling document, suggestion list disappeared after user clicked on the scroll bar in Microsoft Internet Explorer and Webkit-based browsers
- April 10th, 2009 - version 1.9
- In scroll mode, suggestion list now appears almost instantly, no matter how long the suggestion list is (+ many performance optimizations)
- Returned the lost (since adoption of zichun's code) ability to retrieve suggestions for the keyword in-between the other keywords
- Fixed an issue with
item_delimiter
not being used correctly in the code - Fixed an issue with
actb_noDefault
option not being respected after input field value changes actb_selectedItem
now contains the index of selected item in the original suggestion list, not in the filtered listactb
constructor can now accept the 4th parameter -onSelect
- reference to a callback function that fires every time user selects a suggestion
- April 16th, 2009 - version 2.0
*** Incompatible with previous releases ***
- Name of main object changed -
actb
changed toautosuggest
- and all member variables, methods and generated ids were given human-readable names - Variables in the code now use underscore_notation (with the exception of
selectedIndex
), while methods now use lowerCamelCase notation - After many optimizations and code size reductions, script is now ~12% smaller than the previous version
- You can now use PageUp and PageDown keys to navigate through suggestions in arrow-mode
- Script now doesn't generate any CSS warnings (as seen by Firefox's error console)
- 2 of 4 GIF images were optimized (the other two were compressed already)
- Fixed some issues with autosuggest box in arrow-mode
- Name of main object changed -
- April 20th, 2009 - version 2.1 (contributed by Marco Vervoort)
- Fixed a Firefox-only issue when
restrict_typing
was set totrue
and any suggestion containing the upper-case symbol became unavailable - Fixed a bug with all suggestions appearing as selected when
no_default
was set tofalse
- Fixed a bug in
insertWord
method that appeared when no delimiters were defined - Fixed a minor issue with
getCaretEnd
method generating a warning in Firefox onSelect
callback now receives the second parameter - reference to the callerautosuggest
object
- Fixed a Firefox-only issue when
- August 4th, 2009 - version 2.2
- Fixed an issue with incorrect sorting of results, caching the results of previous search in some cases
- Fixed an Internet Explorer-only issue when you couldn't use the
onblur
attribute on the target input field (it got re-written by script) - Fixed a bug when scrolling to the end of a long list that is still in the process of loading could cause rendering issues and render the suggestion list disfunctional
- Fixed incorrect behavior of
restrict_typing
option when there are multiple delimited terms in the input field (collaboration with Marco Vervoort) - Fixed a bug when, after typing the keyword that doesn't have a matching suggestion, suggestion list stayed visible with the latest legit suggestion(s)
- You can now dynamically bind the array and/or the URL for the AJAX webservice with
bindArray
andbindURL
methods - After the browser window is resized, suggestion list will now correctly reposition itself under the parent input field
- Behavior with Home/End/PageUp/PageDown keys is now more consistent across browsers
- Version number is now written in autosuggest.js
- August 18th, 2009 - version 2.3
- Fixed a bug that rendered AJAX support disfunctional
- Fixed a bug that caused the
use_iframe
option disfunctional
- October 10th, 2009 - version 2.4
*** Incompatible with previous releases ***
- All styling info moved to CSS (autosuggest.css)
- Fixed a bug with incorrect functioning of scrollbars when using autosuggest controls in lengthy XHTML documents
- Sample page was corrected to validate as XHTML 1.0 Strict