Click here to Skip to main content
15,860,859 members
Articles / Web Development / HTML

Auto-suggest Control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (124 votes)
10 Oct 2009Zlib12 min read 784.8K   2.6K   197   507
This article presents code that augments any INPUT box with an auto-suggest feature, AJAX-capable
Autosuggest in action

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
<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
    <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:
    JavaScript
    <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:

    1. Create it in the head of the page:
      JavaScript
      <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>
    2. Pass it as a second parameter to the autosuggest object:
      JavaScript
      <script>
          var obj = new autosuggest("tb", customarray);
      
      </script>
    3. Make sure that the autosuggest_url variable at the very beginning of autosuggest.js is empty ("").
    4. You can change the bound static array at any time with the help of bindArray method:

      JavaScript
      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:

    1. 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:
      JavaScript
      <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.

    2. 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:

      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.

    3. Similarly to static array, you can re-bind the webservice URL at any time with the help of bindURL method:
      JavaScript
      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:

    JavaScript
    // 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 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:

    JavaScript
    <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:

    XML
    <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:

    JavaScript
    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
  • 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
  • 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
  • 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' is null 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 and item_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
  • 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 the actb 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
  • 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 list
    • actb 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 to autosuggest - 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
  • April 20th, 2009 - version 2.1 (contributed by Marco Vervoort)
    • Fixed a Firefox-only issue when restrict_typing was set to true and any suggestion containing the upper-case symbol became unavailable
    • Fixed a bug with all suggestions appearing as selected when no_default was set to false
    • 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 caller autosuggest object
  • 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 and bindURL 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

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Software Developer Freelance software engineer
Russian Federation Russian Federation
Dmitry Khudorozhkov began programming (and gaming) with his ZX Spectrum in 1989. Having seen and used all IBM PCs from early XT to the latest x64 machines, now Dmitry is a freelance programmer, living in Moscow, Russia. He is a graduate of the Moscow State Institute of Electronics and Mathematics (Applied Mathematics).

He is proficient in:

- C/C++ - more that 9 years of experience. Pure Win32 API/MFC desktop programming, networking (BSD/Win sockets), databases (primarily SQLite), OpenGL;

- JavaScript - more that 6 years of experience. Client-side components, AJAX, jQuery installation and customization;

- Firefox extensions (immediatelly ready for addons.mozilla.org reviewing) and Greasemonkey scripts. As an example of extensions Dmitry made you can search for FoxyPrices or WhatBird Winged Toolbar;

- XML and it's applications (last 2 years): XSLT (+ XPath), XSD, SVG, VML;

- ASP.NET/C# (webservices mostly);

Also familiar with (= entry level):

- PHP;

- HTML/CSS slicing.

Trying to learn:

- Ruby/Ruby-on-Rails;

- Czech language.

If you wish to express your opinion, ask a question or report a bug, feel free to e-mail:dmitrykhudorozhkov@yahoo.com. Job offers are warmly welcome.

If you wish to donate - and, by doing so, support further development - you can send Dmitry a bonus through the Rentacoder.com service (registration is free, Paypal is supported). Russian users can donate to the Yandex.Money account 41001132298694.

-

Comments and Discussions

 
QuestionMultidimensional Array or Multiple values in same field? Pin
Member 103137585-Oct-13 8:27
Member 103137585-Oct-13 8:27 
GeneralMy vote of 5 Pin
HARI OM THAPA20-Nov-12 6:24
professionalHARI OM THAPA20-Nov-12 6:24 
ur grt...
QuestionWant to call clear method Pin
ravi1989h10-Oct-12 1:29
ravi1989h10-Oct-12 1:29 
QuestionIssue with dropdown selection for textbox suggestions Pin
hdkulu3-Aug-12 12:12
hdkulu3-Aug-12 12:12 
AnswerRe: Issue with dropdown selection for textbox suggestions Pin
hdkulu7-Aug-12 10:45
hdkulu7-Aug-12 10:45 
AnswerRe: Issue with dropdown selection for textbox suggestions Pin
hdkulu23-Aug-12 8:42
hdkulu23-Aug-12 8:42 
Bugbug in the code Pin
fgsdgsdgfhgh13-Nov-11 0:41
fgsdgsdgfhgh13-Nov-11 0:41 
Bugsolve ajax problem with IE & non english lanaguages querystring Pin
Fawzia Moghazy18-Oct-11 4:44
Fawzia Moghazy18-Oct-11 4:44 
QuestionProblem with IE 6 Pin
Member 797110327-Jun-11 1:32
Member 797110327-Jun-11 1:32 
GeneralHow about db? Pin
masterdemaster31-May-11 9:05
masterdemaster31-May-11 9:05 
GeneralMy vote of 5 Pin
ZeeroC00l16-May-11 19:28
ZeeroC00l16-May-11 19:28 
GeneralMy vote of 5 Pin
HenryUH11-Mar-11 18:05
HenryUH11-Mar-11 18:05 
GeneralAutosuggest now working for me [modified] Pin
HenryUH11-Mar-11 11:50
HenryUH11-Mar-11 11:50 
General[Problem] string value with id returned Pin
gemGreg1-Feb-11 6:47
gemGreg1-Feb-11 6:47 
QuestionHow to parse url in autosuggest Pin
FuNky-FranKy23-Dec-10 21:49
FuNky-FranKy23-Dec-10 21:49 
QuestionHow do I get auto-suggest to work within forms? [modified] Pin
JoanneParker4-Dec-10 5:59
JoanneParker4-Dec-10 5:59 
AnswerRe: How do I get auto-suggest to work within forms? Pin
Dmitry Khudorozhkov5-Dec-10 19:29
Dmitry Khudorozhkov5-Dec-10 19:29 
GeneralRe: How do I get auto-suggest to work within forms? Pin
JoanneParker7-Dec-10 3:21
JoanneParker7-Dec-10 3:21 
GeneralRe: How do I get auto-suggest to work within forms? Pin
Dmitry Khudorozhkov7-Dec-10 3:43
Dmitry Khudorozhkov7-Dec-10 3:43 
QuestionDestination for selected value Pin
pascal_a23-Jun-10 1:58
pascal_a23-Jun-10 1:58 
AnswerRe: Destination for selected value Pin
Dmitry Khudorozhkov23-Jun-10 5:41
Dmitry Khudorozhkov23-Jun-10 5:41 
GeneralRe: Destination for selected value Pin
pascal_a23-Jun-10 5:56
pascal_a23-Jun-10 5:56 
GeneralAJAX Call not working Pin
blenkhn18-Jun-10 9:58
blenkhn18-Jun-10 9:58 
GeneralRe: AJAX Call not working Pin
Member 81396836-Aug-11 5:32
Member 81396836-Aug-11 5:32 
GeneralFails with certain leading characters Pin
cmschick26-Apr-10 10:36
cmschick26-Apr-10 10:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.