spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / javascript / ncz / column2 / 1 To page 1To page 2current pageTo page 4
[previous] [next]

Web Project Manager
Aquent
US-PA-Collegeville

Justtechjobs.com Post A Job | Post A Resume
Developer News
Mandrake Linux Founder Back, Virtually
Amazon: We're a Technology Company
Sun Expands MySQL With Closed Source

Creating an Autosuggest Textbox with JavaScript, Part 2

Updating the Autosuggest Functionality

Remember the autosuggest() method from the last article? To implement the dropdown list of suggestions it's necessary to update this method.

The first update is the addition of a second argument which indicates whether or not the type ahead functionality should be used (the reason why will be explained shortly). Naturally, the typeAhead() method should only be called if this argument is true. If there's at least one suggestion, type ahead should be used and the dropdown list of suggestion should be displayed by calling showSuggestions() and passing in the array of suggestions; if there's no suggestions, the dropdown list should be hidden by calling hideSuggestions():

AutoSuggestControl.prototype.autosuggest = function (aSuggestions,
bTypeAhead
) {

    if (aSuggestions.length > 0) {
        if (bTypeAhead) {
            this.typeAhead(aSuggestions[0]);
        }
        this.showSuggestions(aSuggestions);
    } else {
        this.hideSuggestions();

    }
};

You will also remember that this method is called from the suggestion provider's requestionSuggestions() method, which means it too must be updated. This is a fairly easy update; you need only add a second argument and then pass it back into the autosuggest() method when it's called:

StateSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl,
bTypeAhead
) {
    var aSuggestions = [];
    var sTextboxValue = oAutoSuggestControl.textbox.value;

    if (sTextboxValue.length > 0){

        for (var i=0; i < this.states.length; i++) {
            if (this.states[i].indexOf(sTextboxValue) == 0) {
                aSuggestions.push(this.states[i]);
            }
        }
    }

    oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
};

With both of these methods updated, it's now necessary to update the handleKeyUp() method. First, just add the second argument (true) when calling requestSuggestions():

AutoSuggestControl.prototype.handleKeyUp = function (oEvent) {

    var iKeyCode = oEvent.keyCode;

    if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
        //ignore
    } else {
        this.provider.requestSuggestions(this, true);
    }
};

This functionality now works exactly as it did previously, but there are a couple of other keys that require special attention: Backspace and Delete. When either of these keys are pressed, you don't want to activate the type ahead functionality because it will disrupt the process of removing characters from the textbox, but there's no reason not to show the dropdown list of suggestions. For the Backspace (key code of 8) and Delete (key code of 46) keys, you can also call requestSuggestions(), but this time, pass in false to indicate that type ahead should not occur:

AutoSuggestControl.prototype.handleKeyUp = function (oEvent) {

    var iKeyCode = oEvent.keyCode;

    if (iKeyCode == 8 || iKeyCode == 46) {
        this.provider.requestSuggestions(this, false);

    } else
if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
        //ignore
    } else {
        this.provider.requestSuggestions(this, true);
    }
};

Now when the user is removing characters, suggestions will still be provided and the user can click on one of them to select the value for the textbox. This is acceptable, but to really be usable the autosuggest control needs to respond to keyboard controls.

Adding Key Support

The desired keyboard functionality revolves around three keys: the up arrow, the down arrow and Enter (or Return). When the dropdown suggestion list is displayed, you should be able to press the down arrow to highlight to the first suggestion, then press it again to move to the second, and so on. The up arrow should then be used to move back up the list of suggestions. As each suggestion is highlighted, the value must be placed in the textbox. When the Enter key is pressed, the suggestions should be hidden, leaving the last suggestion to be highlighted in the textbox.

When the user scrolls through the suggestions in the list, you must know which suggestion is current. To do this, a property must be added to the AutoSuggestControl definition as follows:

function AutoSuggestControl(oTextbox, oProvider) {
    this.cur = -1;
    
this.layer = null;

    this.provider = oProvider;
    this.textbox = oTextbox;
    this.init();
}

The cur property stores the index of the current suggestion in the suggestions array. By default, this is set to -1 because this there are no suggestions initially.

When the down arrow key is pressed, the next suggestion in the dropdown list should be highlighted. To encapsulate this functionality, a method named nextSuggestion() will be added. Here's the code:

AutoSuggestControl.prototype.nextSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
        var oNode = cSuggestionNodes[++this.cur];
        this.highlightSuggestion(oNode);
        this.textbox.value = oNode.firstChild.nodeValue;
    }
};

This method obtains the collection of child nodes in the dropdown layer. Since only the <div/> elements containing the suggestions are child nodes of the layer, the number of child nodes accurately matches the number of suggestions. This number can be used to determine if there are any suggestions (in which case it will be greater than 0) and also if there is a next suggestion (which means that it's greater than cur). To ensure that cur never points to an empty node, it must never be allowed to be larger than the number of child nodes minus 1 (because the last element in a collection with n elements is n-1).

If it these two tests are passed, then cur is incremented and the child node in that position is retrieved and stored in oNode. Next, the node is passed in to highlightSuggestion(), which highlights it and unhighlights the previously highlighted suggestion. From there, the value of the textbox is once again set to the text contained inside of the <div/>.

As you may have suspected, another method to highlight the previous suggestion is also necessary. Here it is:

AutoSuggestControl.prototype.previousSuggestion = function () {
    var cSuggestionNodes = this.layer.childNodes;

    if (cSuggestionNodes.length > 0 && this.cur > 0) {
        var oNode = cSuggestionNodes[--this.cur];
        this.highlightSuggestion(oNode);
        this.textbox.value = oNode.firstChild.nodeValue;
    }
};

The previousSuggestion() method is similar to nextSuggestion(). The main differences are that you need to ensure cur is greater than 0 to proceed (you still must make sure that there are suggestions by checking the number of child nodes in the dropdown layer) and that cur must be decremented instead of incremented. Other than these two changes, the algorithm is the same. Now back to the three keys.

home / programming / javascript / ncz / column2 / 1 To page 1To page 2current pageTo page 4
[previous] [next]

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Whitepapers and eBooks

Symantec Whitepaper: Converging System and Data Protection for Complete Disaster Recovery
Intel Whitepaper: Comparing Two- and Four-Socket Platforms for Server Virtualization
IBM Solutions Brief: Go Green With IBM System xTM And Intel
HP eBook: Simplifying SQL Server Management
IBM Contest: Are You the Next Superstar? Join the "Search for the XML Superstar" Contest to Find Out
Intel PDF: Quad-Core Impacts More Than the Data Center
Intel PDF: Virtualization Delivers Data Center Efficiency
Go Parallel Article: PDC 2008 in Review
Avaya Article: Communication-Enabled Mashups: Empowering Both Business Owners and IT
Intel Whitepaper: Building a Real-World Model to Assess Virtualization Platforms
PDF: Intel Centrino Duo Processor Technology with Intel Core2 Duo Processor
Microsoft Article: Build and Run Virtual Machines with Hyper-V Server 2008
  Go Parallel Article: Q&A with a TBB Junkie
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
IBM eBook: The Pros and Cons of Outsourcing
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Symantec Whitepaper: Comprehensive Backup and Recovery of VMware Virtual Infrastructure
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
webref The latest from WebReference.com Browse >
Popular JavaScript Framework Libraries: An Overview - Part 3 · Accessing Your MySQL Database from the Web with PHP · Working with the DOM Stylesheets Collection
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Fixing MySQL Replication · Firewall Guide: First Steps to Securing the Enterprise · VoxOx Tames the Tumultuous Communications Tangle

Created: March 27, 2003
Revised: April 08, 2005

URL: http://webreference.com/programming/javascript/ncz/column2/1