By
Arrow Key Support
In the last article Search String Highlighting and Drop Shadows, we examined two visual features that could be used to enhance the appearance of the Autocomplete control. This week we'll be delving into the last major functional piece of our Autocomplete Control: key event handlers. The topic of keyboard support is a hot one due to its role in making your Web pages accessible. According to the World Wide Web Consortium's Web Content Accessibility Guidelines, Web sites should provide device-independent access, meaning: "the user may interact with the user agent or document with a preferred input (or output) device — mouse, keyboard, voice, head wand, or other." While it's unreasonable to expect Web developers to test for every conceivable type of input device, they say: "generally, pages that allow keyboard interaction are also accessible through speech input or a command line interface." Hence, we must provide keyboard-only functionality if we want our site to be accessible to all Internet users.
|
Capturing Key Stroke Events
There are three types of key events. The one you choose depends on what you want to do with the event. We're already using the keyup
event for capturing the search string. It was the obvious choice because it fires after the default action of that key has been performed. For our purposes, it appends the new character to the search string in the textbox. Here's an explanation of each key event:
|
The keyup
event will also work nicely for capturing the arrow and ESCAPE
keys, so we'll add some code to process them in the autoComplete()
function. The ENTER
and TAB
keys will be handled using a different event:
The handleSpecialKeys(Event e)
Function
We can determine which key was pressed by using the keyCode
property, which is available for all key events. Keep in mind that the keyCode
gives us the ASCII decimal code, not the key itself, so the letter 'a' would give us a value of 97. Printable characters would require some translation, but since all our keys are non-printable, all we need to know are the ASCII codes for keys we'll be handling. The easiest way is to look them up on an ASCII code chart.
We'll use a switch
statement to filter all the keyCodes
that we're interested in. At the bottom of the switch
, there's default case that returns false
to inform the autoComplete()
function that the key wasn't handled by the handleSpecialKeys()
function. Any of our filtered cases will cause the function to exit normally with a value of true
. There are also two event properties that need to be set. The returnValue
is used to cancel the event: false
means cancel it. The cancelBubble
property sets whether or not the current event stops bubbling through the document hierarchy. To cancel event bubbling, we have to set it to true
. Here's the skeleton for the handleSpecialKeys()
function:
The ESCAPE
Key
Let's test our new function by starting with an easy key. We'll provide the user with a means of closing the list by hitting the ESCAPE
key. To do that, we can call the clearTable()
function:
Right-click on the AutocompleteSearchCSS.jsp
file in the "Project Explorer" pane and select "Run As => 1 Run on Server" from the popup menu to open the page in a browser. Enter either an 's', 'd' or 'p' in the textbox to bring up the list and then hit the ESCAPE
key. If it disappears, the test was a success! If not, look for an error message in the browser's JavaScript console. (Note that in some browsers, you may have to set an option to see error messages.)
The RowManager
Class
In order to process the arrow and ENTER
keys, we'll have to keep track of the currently selected row. To do that, we'll create a class called the RowManager
and instantiate it using an inline function, which is created by enclosing the function in parentheses and then adding a second set of parentheses for arguments:
The first method that we'll add to the class is resetRowCount()
. It resets all the private class member variables to zero:
To make it public, add it to the JSON object literal that is returned from the class:
In the clearTable()
function, we'll add a call to the resetRowCount()
method after we delete the rows from the table: