Easy JavaScript Autocomplete / Intellisense Script

By Joe on April 15, 2005

I occasionally run into situations where it would be really great to add an ‘intellisense’ feature to a text input on a web form. That is, something along the lines of AutoComplete or Google Suggest.

There are a bunch of scripts available on the Internets to handle this for you, but they all do things their own way, and they’re never exactly what yor want. I’m always running into the same problems with them:

So, I finally broke down and wrote my own script. It may not be better than what’s out there, but hopefully it’s easier to understand.

###

Comments

  1. danielcole says:

    Looks Great in Firefox/Linux. Thank You for the code!

  2. Dave says:

    It kinda works in Safari and FireFox in OS X; type in a letter or two and you get a list, but the arrow keys don't do the trick. You either need to keep typing or pick from the list with the mouse.

  3. Alejandro says:

    Just what I needed. Simple and to the point. MANY thanks.

  4. Brian says:

    great work!

  5. That's a nice script. There's a bit of a usability flaw though in the fact that hitting "enter" doesn't select the currently highlighted item (it submits the form instead) - hitting tab isn't nearly as intuitive.

  6. Peter says:

    Wow, I was just about to plunge into this XMLHttpRequest thing and this server as a great example. Thanks!

  7. Next step: Ajax support. :)

  8. Joe says:

    Ajax support would actually a pretty simple addition. This time around, I had a static list of only a few thousand items, so round-tripping the server was overkill. It was the right architecture decision, but not supporting the latest buzzwords means that the cool kids won't let me sit at their table in the lunchroom. :-)

    There's a function called getEligible that gets called to read the user input and build an array of eligible suggestions that will be used to build the div. Right now that function just loops an array to find its suggestions. Replace that with an xmlHttp call, and you can slap an official Ajax®logo on it.

  9. Roger says:

    The script is great, but it has some problem when you're typing capital letter by using Shift. I suggest to add a variable for SHIFT: var SHIFT = 16; and then add a case for keyUp: elem.onkeyup = function(ev) { var key = me.getKeyCode(ev); switch(key) { //The control keys were already handled by onkeydown, so do nothing. case SHIFT: case TAB: case ESC: case KEYUP: case KEYDN: return; default: if (this.value != me.inputText && this.value.length > 0) { me.inputText = this.value; me.getEligible(); me.createDiv(); me.positionDiv(); me.showDiv(); } else { me.hideDiv(); } } };

  10. Theo Larrieu says:

    Thanks for the great example code. Here's an enhancement.

    I have forms where input can contain comma/space separated list and I wanted auto-suggest for each item, not the input as a whole.

    
    // A holder for prior string in cases where multiple values are used
    this.preserveStr = new String();
    
    // Add two new keycode constants
    var COMMA = 188;
    var SPACE = 32;
    
    //Add to switch statement in onkeydown function
    
                case COMMA:
                me.hideDiv();
                break;
    
                case SPACE:
                me.hideDiv();
                break;
    
    // Change the if statement in onkeyup to
    
            if (this.value != me.inputText && me.getMatchStr(this.value).length > 1)
            {
                me.inputText = me.getMatchStr(this.value);
                me.getEligible();
                me.createDiv();
                me.positionDiv();
                me.showDiv();
            }
    
    //Add a new function getMatchStr
        /********************************************************
        Offer Suggestions for each item in a comma/space separated
        list.
        ********************************************************/
        this.getMatchStr = function(inputStr)
        {
            var regex = /[\s,]/;    
            var finalStr = new String();
    
            if (inputStr.match(regex))
            {
                matchArray = inputStr.split(regex);
                finalStr = matchArray[matchArray.length-1];
                this.preserveStr = inputStr.substr(0,inputStr.length - finalStr.length);
                return(finalStr);
            }
            //If no special handling, the original string is good enough
            return(inputStr);
        };
    
    
    //Finally alter the useSuggestion function to
    
    this.elem.value = this.preserveStr + this.eligible[this.highlighted];
    
    
  11. Joe says:

    Thanks for the submissions, guys. A number of people have sent me emails with hacks as well, and I wound up writing an "Ajax" version for a project I worked on. Sometime in the next few weeks I'll try to compile up everyone's suggestions into a new package, and perhaps even a new version of the code.

  12. Joe says:

    Just to update, since I've received quite a few emails: I'll try to get a new version of autosuggest put together by next Monday (6/13). I'd like to incorporate all of the suggestions that have been posted, without making the code too confusing, since the whole idea of this script is 'hackable'. You guys have provided a lot of great submissions.

    This thing is sort of a little project now, so I'm not sure how to best hand it over to the community. A wiki? A Trac site? I'm open to suggestions.

  13. Eric says:

    I'd love to see your changes. I've started adding some performace changes to it as well and would love to return my contributions once I'm sure they are stable.

    How about putting the project up on SourceForge where developpers can access it via CVS (I know - just a couple of files, but still.... ) and make their changes. And you can still maintain control of it.

  14. Paul says:

    What about a field that keeps track of an index in the main array? So you know which item the user selected. (Can't look through the array based on strings because there might be duplicates)

  15. Aaron says:

    This is a great little script. I"m anxious to see the AJAX code because I have run across your site in researching that exact solution.

    Let me know if you need any help.

  16. Paul says:

    There seems to be a bug with the div window not popping up when typing too fast...does anyone else get this?

  17. jigaruu says:

    I am unable to download the proper ZIP file, so if some one emails me the script at jigaruu@indiatimes.com id, i will be thankful to them,

    Regards, jigaruu....

  18. tom drellishak says:

    I am getting an error while tring to unzip the download files. Its telling me the zip file is corrupt. Can someone send me a good copy?

    tom@drellishak.com

  19. Tristan says:

    same error for me :/

  20. Ben says:

    If the download link is still broken, you can grab the javascript source from http://gadgetopia.com/autosuggest/autosuggest.js

  21. David says:

    I have a form for people to enter biological records. The form allows the user to add up to 20 species hence I need an autocomplete 20 times on the same form using the same array of names. Can this code be adapted so that it looks for the array held once in a different javascript?

  22. David says:

    Oops! A silly question and have got it working.

  23. The zip file appears to be corrupted. When I try to open it in FireFox I get comprssed folder is invalid or corrupted. I really would like to look at the source.

  24. Joe says:

    Sorry, guys, I missed the comments about the broken zip file. Fixed now.

  25. Eric says:

    Was a newer version ever made available? Joe's post on 6/7 suggested having one out for 6/13, but I don't see one here... Has a new one ever been compiled?

    Thanks,

    Eric

  26. If you type in "CA" fast in the example no results are returned.

    :D

    I hope "the code is so dense and obtuse" doesn't mean my code. ;)

  27. Rhys says:

    The "CA" problem is because there are two consecutive key ups (you have already pressed "A" before you have released "C"). Because it hides the suggestion list if the text hasn't changed, by the time it receives the second keyup the text is identical.

    Here's how to fix it:

    In the function assigned to elem.onkeyup, change the code:

    if (this.value != me.inputText && this.value.length > 0)
    {
    me.inputText = this.value
    ...

    to

    if (this.value.length > 0)
    {
    me.inputText = this.value
    ...

    This will mean that if you hit the left and right arrows on the keyboard when a suggestion is shown it will not disappear. If you want that behaviour as well you would need to make further adjustments to the code.

    If you want the selection to be accepted by pressing enter, add "var ENTER = 13;" with the rest of the keycodes and add the following code to the switch statement in onkeydown:

    case ENTER:
    me.useSuggestion();
    return false;
    break;

    also add "case ENTER:" to the keylist in the switch for onkeyup.

  28. IpSo says:

    I tried using AutoSuggest, but for some reason the "eligible" items always had: _array() as the last item. It looks like autosuggest is conflicting with my javascript menu system, and I tracked it down to this:

    Around line 298:
    //for (i in this.eligible)
    for (i=0; i < this.eligible.length; i++)

    That fixed the issue. Very strange.

  29. Dan M. says:

    How do you get the script to work on multiple elements. In one of the scripts named "Cleanly binding to form elements" where it asks three questions about fruits the first one works but the other two do not. Why?

    Example: function bindEvents() { //Find all of the INPUT tags var tags = document.getElementsByTagName('INPUT'); for (i in tags) { var tag = tags[i]; //If it's a text tag, attach an AutoSuggest object. if(tag.type.toLowerCase() == "text") { New AutoSuggest(tag,fruits); } } }

    window.onload = bindEvents;
    
  30. I have an alterneate compoent which has Ajax support.

    AutoAssist (http://capxous.com)

    :)

  31. I have a problem. The autosuggest actually works fine but when I select one item off the list using a couple of downarrow presses and one return, the whole form is submitted.

    Is there a way to prevent this?

  32. Noortje says:

    Lovely script. It's just what I was looking for.

    I was wondering if it's possible to transform the dropdown list from this script in the familiar Internet Explorer drop down list. In short to modify the CSS of the drop down list in the IE select tag style. Do you guys have any ideas? Thanks

    Noortje from The Netherlands (NOORTZE@YAHOO.ES)

  33. Joey says:

    Hello guys, I have a problem. The script keeps giving me this error message: elem has no properties. Any idea how to solve this problem? The problem is probably at this level:

    elem.setAttribute("autocomplete","off");// at this level

    if(!elem.id) //and at this level { var id = "autosuggest" + idCounter; idCounter++;

    elem.id = id; }

    Joey (joeuitnijmegen@yahoo.fr)

  34. Renato A.C says:

    Very nice script!

    I have made a small addition which turns the typed text into bold in the eligible list.

    Within the this.createDiv function:

    /* ... */ 
    var word = this.eligible[i];
    
    var li = document.createElement('li');
    var a = document.createElement('a');
    a.href="javascript:false";
    /* ADDED CODE */ 
    //Emphasize input text
    foundword = ''+word.substr(0,this.inputText.length)+'';
    restword = word.substr(this.inputText.length);
    a.innerHTML = foundword + restword;
    /* END OF ADDED CODE */ 
    
    li.appendChild(a);
    /* ... */
    
  35. Craig Laparo says:

    A fix for using Enter to select the item if the list is displayed and submit the form if it's not...

    var ENTER = 13; ... case ENTER: if(me.highlighted > -1) { me.useSuggestion(); return false; } break;

    I also wanted the list to go away if the user clicks outside. Here's my quick solution, although it's sorta ugly. It removes the need for handling clicking on an item, but the item seems to be selected onmousedown, since that's when the textbox loses focus.

    elem.onblur = function(){me.useSuggestion() || me.hideDiv()};

  36. Craig Laparo says:

    I've been noticing an error that occurs when you hover the mouse over the list while you type. Seems it has to do with the way the list items are referenced while the list is destroyed and created while you type. I wanted to fix this, but I'm not quite sure how...

    "li has no properties"

    It's in the "this.changeHighlight = function()" function where you set li.className = "";

    any ideas? it's not a serious error by any means, but errors are annoying.

  37. Sachin Darbarwar says:

    Hi Control is great and works fine, Following is the code i have use to fix the problem with dropdowns in IE 6.0.

    Just a stylesheet change and works fine

    Use this as stylesheet

    autosuggest

    { position:absolute; z-index:10; cursor:move; overflow:hidden;/must have/ width:33em;/must have for any value/; }

    autosuggest iframe

    { display:none;/sorry for IE5/ display/*/:block;/sorry for IE5/ position:absolute;/must have/ top:0;/must have/ left:0;/must have/ z-index:-1;/must have/ filter:mask();/must have/ width:3000px;/must have for any big value/ height:3000px/must have for any big value*/; }

    and for html

    This fixes the problem.

    sachin1778@yahoo.com

  38. dEREK says:

    Cheers! Brilliant, neat script.
    Wonder if it's possible to modify so that the script reacts only after a second letter is typed? So that instead of showing the whole list under letter "A" when typing "A" it will only show suggestion after user inputs a second letter. "Al.." -> "Alabama" I've seen this function on other autocomplete scripts.
    Anyway, thanks again dEREK

  39. Bruce says:

    I like using this script as it is easy to make adjustments even for someone who doesnt know java such as myself. Heres one adjustment I made so the div box wouldnt show if there was no eligible items.

    this.showDiv = function() { if(this.eligible.length > 0){ this.div.style.display = 'block'; } else { this.div.style.display = 'none'; this.highlighted = -1; } };

  40. juan says:

    Only works in IE. Bye.

    puaj !

  41. Tom Nelson says:

    Wonderful code. I made it my own so easily. It's so simple.

    Thanks a bunch.

    Tom

  42. Alvaro says:

    Thanks for this code, before hours and hours looking around the web i find an easy way to autocomplete forms. MY PROBLEM IS I have a script with a calendar on my web, i can't make that the two scripts works in both, only work one. Any Idea? Thank you

  43. your clean_binding.html example had a typo... the 2 latter inputs needed differing names.

  44. Sandra says:

    Is it possible to populate the values in a dropdown menu instead of a textbox? The reason I'm asking is because I'd like the user to select more than one value. Can the user select more than one value using a textbox?

  45. This script is VERY elegant, but there is one major speed related flaw and a couple small suggests I can make. First off, the search code in "this.getEligible" uses a function called indexOf() to discover if the value matches the search, on the condition that the index value returned is zero, indicating the beginning of the string.

    The problem is the elements that don't match index 0 still search for that index or search string inside the entire string, searching for a string match through the entire string before it finds there is none. It does this for EVERY single element. The indexOf function is will be extremely fast in the event that the string starts with the string.

    When indexOf begins, it loads the search string and the match string into memory using internal pointers to point to each index (character) in the array. When the match fails using index 0, it then shifts the pointer on the search string one and compares again, repeating until the index number is equal to the search strings length minus the match strings length.

    That is possibly dozens of searches PER STRING in the array, mostly to waste time to return -1, or possibly find the match string but in the middle of the string. This search should either use a substring search starting a index 0 or regular expressions like this.

    this.getEligible = function()
    {
    this.eligible = new Array();
    var searchExp = new RegExp('^'+inputText,i); //case insensitive
    for (i in this.suggestions)
    {
    //var suggestion = this.suggestions[i]; // dont do this, it requires new memory and boxing the index into a new object. the built in indexer is faster

    if(searchExp.test(this.suggestions[i])
    {
    //this.eligible[this.eligible.length]=suggestion; //unnecessary call to eligle.length, uses time, next index number is automatic
    this.eligible[]=suggestion;
    }
    }
    };

    Also, if you sort() the array, then you can break out of the loop early once your first value is past your match value in alphabetic order.

  46. haha, I know exactly what you mean when you say : Big hairy mass of code. The usual situation is that I want to customize some element of the script’s behavior, but the code is so dense and obtuse that I can’t make changes without breaking things.

    Good work; Somehow the suggest code that wrote wasn't working with IE, (weird enough), but yours is! ...

    Regards Vyas,Anirudh

  47. nice one good script :) its working fine

  48. its working fine on mouse event but now working on after pressing enter can you tell how will this work

  49. Rougy says:

    Nice set of code. Really came in handy. Thank you very much.

  50. phani says:

    Thanks for nice scipt. This is what I was looking for and its so simple. But one thing I want to have in this is the mouseout functionality on the div to hide the suggestions when we do mouseout like ESC keyevent. I tried that but no luck. Can you help me out..

    phani

  51. Javed says:

    great work...just what i needed. trying to modify the code so that ENTER would work as autocomplete in addition to TAB

  52. Martin says:

    thanks dude, your script works A1

    script kiddy Mart

  53. Hi, I've tried to incorporate this script into my stock gallery search form and think it is partially working however the autocompleted text does not display, can anyone see anything wrong with my code?

    http://www.jamespaulphotography.co.uk/stockgallery/search.php

    Thanks for any advice James

  54. ron says:

    Great script - here some suggestions to select option with the return key instead of mouseclick - especially cool in combination with Theo Larrieu's extension

    // add to key-constants var RETURNKEY = 13;

    // add to keydown function case RETURNKEY: me.useSuggestion(); me.hideDiv(); break;

    // extend keyup function case KEYDN: case RETURNKEY: return; default:

  55. David Nunn says:

    Wonderful script, does what I want it to do! Just a very minor point, and not sure if anyone has pointed this out to you already, but there is a slight error in the example code in the .js file (which i copied to use when I was working out how to do it...). It should read "new AutoSuggest(document.getElementById("fruit"),fruits);" the penultimate parenthesis is in the wrong position in the .js file!

  56. adsfas says:

    faasdfasf

  57. muthu kumar says:

    hello sir, i am using three drop down boxes in jsp . the first drop down box fetches the district values from mysql table and the second box fetches the airport value from the another table and the third drop down box fetches the area values from another table .i want all the three drop down boxes will autocomplete and autosuggest .please help me .its urgent.thanks in advance

  58. MUTHU says:

    hELLO SIR, I have three drop down boxes in jsp. The first box fetches the district value from sql database and the second box fetches the area values from the same database and the third box fetches the airport values from the same database. I want the three drop down boxes to autocompletion and autosuggestion.if u gave me the code example or related website it will be helpful for me .its urgent .please help thanks in advance please reply soon .it's urgent

  59. muthu says:

    hello sir, I have three drop down boxes in jsp. The first box fetches the district value from sql database and the second box fetches the area values from the same database and the third box fetches the airport values from the same database. I want the three drop down boxes to autocompletion and autosuggestion.if u gave me code example or related website it's very helpful for me .it's urgent thanks in advance reply soon

  60. Thanks For the script i will try it

  61. amy says:

    I don't understand how this works. I'm typing but I don't get a sense that it's working. By the way how can I test this. What do I type in to see suggestion

    Please email me here mysweetapplepie@yahoo.com. I need to see that this script works. Would be a great tool for me. Thanks.

  62. amy says:

    I mean is this like if I type app, it will suggest apparatus, apply, application, etc. Can the script be modified to handle this. Again this is mysweetapplepie@yahoo.com.

  63. Deniz says:

    Where is the script?

  64. Sisko says:

    Here is the link. i didn't see it anywhere on this page.

    http://gadgetopia.com/autosuggest/autosuggest_0.1.zip

    there is an example in the code. Don't use the previous link posted earlier to the autosuggest.js file. i think there is a bug in that version.

    Nice work man, just what iu was looking for. if someone wants to use array values from a database, ie MySQL, just use echo from php in a while loop to push into the array.

    ie; while($row = mysqlfetcharray($rs)) { echo 'myValues.push(\'' . $row[1] . '\');'; }

  65. Iain says:

    Can someone please tell me how to make it show only the top 10 results for a search then when the next letter is typed it shows the top 10 for those two letters and so on, like google does.

    Thanks

  66. I didn't see the updated comment and had downloaded the file at http://gadgetopia.com/autosuggest/autosuggest.js

    The example

    new AutoSuggest(document.getElementById("fruit",fruits));

    should be:

    new AutoSuggest(document.getElementById("fruit"), fruits);

    Works for me now.

    diff -w shows no difference between the old and new .js files.

    This is much cleaner than a previous implementation I had been using. Well done, thanks.

    I will try to hack it so that [Tab] fills in the current highlighted match, and that the top one is highlighted unless the user moves the arrow keys.

  67. Hi,

    I tried using this code for Firefox, but it doesn't work. I tried out all the options, still couldn't find one. Any help is appreciated.

    Thanks in advance, Akhil

  68. I'm using autosuggest in a facebook application that i'm developing. I needed to match any consecutive input string, not just the begining. i.e funding 'cut' in 'Connecticut'.

    To do so, in getEligible I changed the condition of the if() statement to:

    if(suggestion.toLowerCase().match(this.inputText.toLowerCase()) == this.inputText.toLowerCase())

  69. Peter says:

    Uhh. I replaced the TAB with ENTER, and the choice is now OK (hitting "enter" does now select - better then TAB. : ) Also I added the SHIFT and it works perfectly without problems with using uppercase as before. Unbelivable. I had no experiences with java before...

    Modifiet parts:

    var ENTER = 13;
    var SHIFT = 16;
    var ESC = 27;
    var KEYUP = 38;
    var KEYDN = 40;
    
    elem.onkeydown = function(ev)
    {
        var key = me.getKeyCode(ev);
    
        switch(key)
        {
            case ENTER:
            me.useSuggestion();
            break;
    
            case ESC:
            me.hideDiv();
            break;
    
            case KEYUP:
            if (me.highlighted > 0)
            {
                me.highlighted--;
            }
            me.changeHighlight(key);
            break;
    
            case KEYDN:
            if (me.highlighted < (me.eligible.length - 1))
            {
                me.highlighted++;
            }
            me.changeHighlight(key);
            break;
        }
    };
    
        case SHIFT:
        case ENTER:
        case ESC:
        case KEYUP:
        case KEYDN:
            return;
        default:
    

    Original code: http://gadgetopia.com/autosuggest/autosuggest_0.1.zip

    Many thanks to developer!

  70. Kristian says:

    Nice script! Is there are way to call the list from a database instead of an array?

  71. ate says:

    teest

  72. dolly says:

    hey dcode w is jst awesum...helped me a lot.. can any1 plzz tell how to display only d nearest top 10 results in d drop down n hw do i show suggestion for each word separated by space Thanks in advance!!!

  73. dolly says:

    hey d code ws jst awesum...helped me a lot.. can any1 plzz tell how to display only d nearest top 10 results in d drop down n hw do i show suggestion for each word separated by space Thanks in advance!!!

  74. dolly says:

    hey d is jst awesum..helped me alot.... cn any1 plzz temme hw to display only d top nearest suggestions in dropdown..n hw do i provide drop down suggestion for each word separated by space...

    Thanks in advance!!

  75. Hey very informative article. Thanks for sharing such a use ful information.

    Thanks Dhanesh

  76. slb says:

    I just wanted to thank you. I am a relative new commer to Javascript and PHP, but this piece of this code really worked great for me to load from MS SQL. I also appreciate your setting it up so straight foreward approch, and commenting it so well.

  77. Metads says:

    Implemented the same in http://www.metads.com Thanks

  78. Håkan says:

    Thanks for the clean code :) But i added some functionality:

    • runtime creation of dropdown div
    • added a dropdown button (also runtime created)
    • added ENTER as selection (same as TAB)
    • fix height on dropdown div Not tested for browser compability though... (Get code on my name link)
  79. @Håkan, can you share the updates?

    Thanks Dhanesh Mane

  80. bob says:

    if for some reason you are still using this instead of "Dojo Toolkit" or one of the several better Autocompletes out there, there was an update posted. Not sure if it was from same author but looks VERY similar:

    http://www.brandspankingnew.net/archive/2007/02/ajaxautosuggest_v2.html

  81. bob says:

    For some reason, the previous link didn't post right. Here it is again for the new version of Autocomplete 2.1.3 (google it if it doesn't come up this time)

    http://bit.ly/RaYKx

  82. Brick says:

    Script is awesome...but there is a test case in which its not working properly....suppose u have some data according to letter r...if u press r first time then it works like jam but if u hit back space and then press r again it won't..u will have to type the second letter.....will u please suggest why it is happening?

  83. Mike says:

    If are you searching autocomplete feature for Mootools framework You can use this open source project: http://code.google.com/p/mootools-autocompleter/

    Regards

  84. Kirankumar says:

    Thanks a lot for the code... Searched for it everywhere

  85. f.u says:

    Thanks for the code guy. Cannot locate it

  86. ns says:

    Hi, can't find the code. Can u pls help?

  87. [...] Autosuggest example (could be used to provide the tool tip if the positioning is worked out): http://gadgetopia.com/post/3773 [...]
  88. Deb says:
    Hi can some one plz post the actual code.in the thread I am not seeing the original code..it's all the enhancement part..plz help....

Add a Comment