How to Create an Ajax Autocomplete Text Field: Part 10 / Page 3 | WebReference

How to Create an Ajax Autocomplete Text Field: Part 10 / Page 3


How to Create an Ajax Autocomplete Text Field: Part 10 [con't]

Both the up and down arrow key handlers call the scrollList() method to display the newly highlightedRow. Once one iterates through the visible list items, there comes a point where the highlightedRow would be out of sight. After all, the reason a scrollbar is displayed is because there are too many items in the list to view. If the user couldn't see the currently selected item, using the arrow keys could become a frustrating experience!

The highlightedRow is stored in a local variable to avoid successive function calls and tested for validity; basically any non-null value will do. The second if statement uses two DOM properties that we haven't seen yet. The offsetTop is a read-only property that stores the vertical offset position of the current element relative to its offset container. The <body> is the offset container for statically-positioned (default) elements, but positioned elements create their own offset container space. For this reason, the row's offsetTop returns the top of the row's distance from the top of the container. The scrollTop returns the distance between the top edge of the element and its top edge currently in view. The expression highlightedRow.offsetTop evaluates to true if the top of the row has gone past the top of the container. Setting the container's scrollTop value equal to the row's offsetTop has the effect of moving the scrollbar until the highlightedRow is fully in view at the top of the viewport.

To scroll down, we need to calculate the rowOffsetBottom by adding the row's clientHeight to its offsetTop since there's no "offsetBottom" property. To ascertain if we need to scroll the list, we can compare the rowOffsetBottom to the container's scrollTop plus its clientHeight (essentially its "scrollBottom"). A rowOffsetBottom larger than the container's scrollTop plus its clientHeight indicates that the list requires some scrolling to bring the highlightedRow into view. In this case, setting the container's scrollTop to the rowOffsetBottom minus the highlightedRow's clientHeight moves the scrollbar until the highlightedRow is fully in view at the bottom of the viewport:

The getHighlightedRow() function is getter method at its most basic. Here's the code:

Add the above methods to the return object to make them publicly accessible:

Figure 1 illustrates the various HTMLElement properties that can be used to calculate scrollbar positioning.

Update the handleMouseEvent() Function

The handleMouseEvent() function must now be updated to use the new RowManager class because it includes functionality which is independent from the RowManager. It's possible to highlight two rows simultaneously by using the mouse in conjunction with the arrow keys. Who would do such a thing? No one under normal circumstances, but it's possible to leave the mouse in a position where it happens to hover over a list item. In such an instance it would be confusing to the user as to which row is actually selected, as Figure 2 demonstrates.

Here's the handleMouseEvent() function updated to call the RowManager's methods:

The commented last line has been replaced by two calls to the RowManager class. The first call sets the row's style to popupRow followed by the event type, which include over, up, down and out. The next line sets the highlightedRow to null on the mouseout event because it's the only event for which the current row should not be set as the current one.

Here's the file with this week's updates.

Next week, we'll wrap up the Autocomplete Control series by covering the rest of the control keys, including TAB and ENTER. As you'll discover, these keys have to be handled differently than the ones we've covered thus far. We'll also look at how to close the list when the user clicks elsewhere on the page.


Original: July 16, 2008

Digg This Add to