How to Create an Ajax Autocomplete Text Field - Part 7 [con't]
Converting from Table Layouts to CSS
There are several tools available to help you convert from a table-based layout
to one that uses CSS formatting. One such example is Dreamweaver UltraDev, which includes a command called
"Convert Tables to Layers" that does just that. There are also several
standalone products that generate the
<div> tags and CSS rules from table
Comparing the Table and CSS Version of the Autocomplete Control
By adding a border to the control we can easily compare the two implementations of the Autocomplete control.
The table version is taller because it contains an extra placeholder row for the list. This could be minimized by setting the second row height to a number like "1." Other than that, I would say that the resemblance is striking!
JSP File Includes
Moving the source code to another file and using a JSP include tag is a big step in decoupling the control from the rest of its parent Web page. The goal here is to make its use as trivial as possible; all it should take is uploading some files to the server, including the control in a JSP page.
There are two mechanisms for including another Web resource in a JSP page:
include directive and the
include directive is processed when the JSP page is translated into
a servlet class. The effect of the directive is to insert the text contained
in another file in the including JSP page. The
include directive is ideal
for including banner content, copyright information or any chunk of content
that you might want to reuse in another page. The syntax for the
directive is as follows:
jsp:include element, on the other hand, is processed when a JSP
page is executed. It allows you to include either a static or dynamic resource
in a JSP file, which are both handled differently. If the resource is static,
its content is simply inserted into the calling JSP file, much like the
directive. If the resource is dynamic, the request is sent to the included resource,
the included page is executed, and the result is included in the response
from the calling JSP page. Here's the syntax for the
<form> from the AutocompleteSearch page and add the
include directive for the Autocomplete control:
Here, we rename the
AutocompleteList.js file to
AutocompleteControl.js, indicating that it now contains code for the entire control, not just the Autocomplete list. To rename the file, follow the same process as you did with the CSS file: right-click on the
AutocompleteList.js file in the "Project Explorer" pane to open the popup menu and select the
Rename item. The file will then turn into a textbox for editing. Alternatively, you can press the
F2 function key.
onload Event Handler
One final remnant from our old control is the
onload="init()" event handler in the
<body> tag. We can remove this as well by adding code to the top of the
addEventHandler (string, function) function accepts two parameters: the name of the event and the event handler function. This is a simplified version of the same function that appeared in my URPMs - AJAX Edition article. The reason for needing a function to attach the event is because there are two different implementations. Here's an explanation of each from that article:
"In Internet Explorer, the
attachEvent()function is used, while in DOM 2 compliant browsers, you add a listener to an event by calling
addEventListener(). The World Wide Web Consortium had their hands full when deciding on an event model because the two main standards were diametrically opposed, with Netscape using something called the capturing model, and Internet Explorer endorsing bubbling. Basically, the two camps emerged as a result of answering the questing of what should happen if an element within another element both have handlers for the same event: Should the parent (outer) element fire first, or should the child (inner element)? Netscape concluded that the parent should fire first. That's Event Capturing. Internet Explorer took the opposite stance and decided that the child should be the one to fire first! That's event bubbling. The W3C took the middle road in creating their own W3C Event Model whereby the event is first captured until it reaches the innermost element and then bubbles up again. This allows the developer to select either style of event firing by supplying the
addEventListener()function with a Boolean argument. I used "constants" to show that true means capture and false means bubble. In practice, unless you have a specific reason to use capturing, stick with bubbling, as I did here."
init() method. As I mentioned earlier, we'll now use a different way to create the table and position it. Since there's no
completeTable in the document, we have to create it using the DOM
createElement(string elementName) method. We also set its ID so that the
completeTable CSS rule will apply to it.
The code to set the
left position of the
completeTable has changed because the
completeField's containing element is the AutocompleteControl. Hence, its
left property is calculated from the
left of the AutocompleteControl and not the left side of the page. For this reason, we have to subtract the
left value from the
Without our placeholder auto-row, we have to be a bit more creative when setting the
top property. One easy way to do it is to set it to the bottom of the
AutocompleteContol, because it's just tall enough to contain its elements. We can easily retrieve this value via the
clientHeight property. It retrieves the height of the object including padding, but not including the margin, border or scrollbar:
Go ahead and try it in a browser. Right-click on the
AutocompleteSearchCSS.jsp file in the "Project Explorer" pane and select "Run As => 1 Run on Server" from the popup menu (See Figure 8).
After a few seconds, the
AutocompleteSearch page should appear in the browser or main Eclipse window, depending on how you've configured the "Web Browser" preferences. If all went according to plan, the Autocomplete control should look more or less the same as it did earlier (See Figure 9).
Our final task of the day will be to add some optional parameters to our control that will augment its versatility.