I have a Motorola Razr cellular phone, and I was sending some text messages one day, and was really impressed with their "autosuggest" feature. For those that don't know what I'm talking about, the phone will suggest words behind your text as you type. To insert the word, you just push up on the keypad. This makes it much easier to send text messages, and also ensures your spelling is correct. So, with that in mind, I set about to do the same thing, but for a web form. Sure, I've seen a lot of WinForms applications that have AutoSuggest, and I know there are some control sets out there that contain autosuggest drop down lists and textboxes (Anthem.NET Extensions have one that seems to work well, but you have to bind it to a database for the word lookup). I wanted something that required very little configuration, didn't require a database, but could still be customizable.
XMLHTTPRequest object. I've written several articles concerning the use of it in AJAX based applications, and thought it would be well used here. The result is an ASP.NET (2.0) Web User Control that contains a textbox and a
div element that will display suggestions as you are typing text (see screenshot).
Using the Code
I'm going to go over the steps to incorporate this into your project. It's really pretty simple, and I'll add a final checklist at the end, in case you run into any problems.
Setting Up the Project
I've included all the code you'll need to get this running, and a sample dictionary. The word lists are far from complete, so you may want to remove a lot of the stuff in there, but this is just an example after all. The word lists are laid out in the form a.txt, b.txt, etc. Each text file contains words that start with a character from a-z. The reason I did this was to keep the
Also included is an img directory. Be sure this is in your root as well, or, if you have a different folder, just modify the
img elements to point to wherever you decide to put them. There are only two images (up.png and loading.gif).
Using the Control
Once all the files are in place, just add the User Control to your web project. You'll be able to simply drag and drop the control on to your page. If you want to edit sizes and such, just modify the CSS in the control's HTML code-behind. I didn't include any properties since, as I said before, I wanted this to be able to run without any server-side scripting.
You'll see the control on the page, and it should be styled as in the screenshot above. That's it!
How it Works
We use the "
onkeyup" event of the
TextBox input to begin the process. Once the key is pressed, we just do a couple of checks. First, we want to see if the user has switched off AutoSuggest (by unchecking the checkbox). Next, we get the keycode. If it's the "up arrow" (code 38), we'll try to insert the current word into the textbox, as long as we have a word. Since we're going to nest the word inside an anchor tag (I wanted the user to be able to click the hyperlink as well as push the up arrow to insert), we'll get that object's
setTimeout method. What this does is asynchronously fire the
checkSuggest method after 250ms. I did this because without an asynchronous call, the loading of the
XMLHTTPRequest actually paused the user from entering text into the textbox until the
XMLHTTPRequest was loaded, which was unacceptable to me. The
checkSuggest method just makes sure we're entering a "valid" character (a-z), and not a space, number, or punctuation mark.
var keyID = event.keyCode;
if (keyID == 38)
var suggest = document.getElementById('suggest');
if (suggest.innerText == "No suggestions.")
var link = document.getElementById('lnkWord');
var elem = document.getElementById('txtInput');
var timerId = setTimeout(checkSuggest,250);
Once we're sure we have a valid character, the
suggestWord function takes the
checkText argument. We'll get the first character, and load the corresponding library.
var dict = "dictionary/" + checkText.charAt(0) + ".txt";
asynchText = checkText;
xmlhttp.onreadystatechange = MatchWords;
MatchWords callback function handles the response and parses the resulting text, trimming out any words that are shorter than what we input (if I put in "and", I shouldn't get a suggestion for "an"), then checking each word to see if it matches a word in our returned array. So, if I put in "app", I should get "apple" (as long as it's in the word list, if you use mine, you'll get "Appalachia").
var newSuggest = "";
for ( var i=0, len=arLen; i<len; /> checkText.length)
newSuggest += temp[i] + ",";
Now that we have the words list (in an array), we're going to sort them, then start comparing them to our entered text. We just do this by looping through each character of the word until we get a non-match. If the match fails, we just move on to the next word in the list. If we reach the end of our input word, and we still have all matches, that has to be the right word.
function checkMatch(inputText, dictWord)
inputText = inputText.toUpperCase();
dictWord = dictWord.toUpperCase();
for (var x=0; x<inputText.length; x++)
if (inputText.charAt(x) != dictWord.charAt(x))
Also of note, this control will handle multi-word inputs, so you could easy extend this out to a textarea input with the same functionality.
- Start a new ASP.NET Website (2.0)
- Unzip the AutoSuggest source
- Add the user control to your website project
- Add directories called "dictionary" and "img" to the root of wherever the control sits
- Add all files from the dictionary folder of the unzipped source into your dictionary folder (you can do this by adding files in the Solution Explorer)
- Add up.png and loading.gif to your img folder
- Drag the control to your page
- Build and execute
XMLHTTPReuest object in UI programming.
Eventually, I'd also like to make the suggestions into a scrollable list. So, if I typed "app", I might get several suggestions like "apple", "apply", etc. Currently, this control only displays one suggestion at a time.
It is also important to realize that the code posted inside this article is composed of snippets. The full source is included with the download, so things like instantiating the
XMLHTTPRequest have been left out of this article.