Wrox Home  
Search
Professional Ajax
by Nicholas C. Zakas, Jeremy McPeak, Joe Fawcett
March 2007, Paperback


Closing the Results Box

To close the search results box, the msnWebSearch object provides the close() method. If you'll remember from the drawResultsBox() method, the close() method handles the onclick event of the link responsible for closing the box:

msnWebSearch.close = function () {
    var divSearchBox = this.parentNode.parentNode;
    document.body.removeChild(divSearchBox);
	   
    return false;
};

The search box isn't really closed; in fact, it is removed from the document. To do this, retrieve the divSearchBox element. The first line does this by retrieving the parent node of this element's parent. Because close() handles the onclick event, this references the link. The next line removes the divSearchBox element from the document. The last line, return false, forces the browser not to follow the default behavior of a link (going to the location noted in the href attribute).

Building the Search Interface

The last method of the msnWebSearch object is search(), which provides the interface to perform a search. You can call search() with the onclick event of an element. It accepts two methods, an event object and the search term:

msnWebSearch.search = function (e,sSearchTerm) {
    var divSearchBox = this.drawResultBox(e);
    var url = encodeURI("websearch.php?search=" + sSearchTerm);
	var oParser = new XParser(url);
    oParser.onload = function () {
        msnWebSearch.populateResults(divSearchBox.childNodes[1],oParser);
    };
};

The first line calls the drawResultBox() method and passes the event, e, to it. The next line encodes the URL for proper transmission. This URL is passed to the XParser constructor to create a new parser. The parser's onload event handler calls the populateResult() method when the search feed is finished loading to populate the search box with results.

Of course, one of the reasons for building this widget is to make it fit the look of your own site.

Customizing the Web Search Widget

Thanks to CSS, you can easily customize the widget for your existing site and any redesign you may have later down the road.

The first CSS class discussed is ajaxWebSearchBox, the class for the search box. Because the box is positioned, it must have a position of absolute:

.ajaxWebSearchBox
{
    position: absolute;
    background-color: #0d1e4a;
    width: 500px;
    padding: 1px;
}

The absolute position is the only requirement. All other properties are optional according to your tastes. In this example, the box has a darkish-blue background, a width of 500 pixels, and 1 pixel of padding on all four sides. This padding will give the box a 1-pixel border around the box's contents.

The next class is ajaxWebSearchHeading, which contains the box's heading text and the closing link. To position the closing link in the top-right corner, it is absolutely positioned. Because of this, it requires ajaxWebSearchHeading to have a position of relative:

.ajaxWebSearchHeading
{
    position: relative;
    background-color: #1162cc;
    font: bold 14px tahoma;
    height: 21px;
    color: white;
    padding: 3px 0px 0px 2px;
}

Once again, the only required property is the position property. The remaining properties help to give the element a heading look. The background color is a lighter blue with white, bold text 14 pixels high and in the Tahoma font. The element's height is 21 pixels and is padded on the top and left edges.

As stated previously, the closing link's position is absolute:

a.ajaxWebSearchCloseLink
{
    position: absolute;
    right: 5px;
    top: 3px;
    text-decoration: none;
    color: white;
}a:hover.ajaxWebSearchCloseLink
{
    color: red;
}

The element is positioned 5 pixels from the right and 3 pixels from the top, placing the element in the top-right corner. This link does not have any text-decoration and is colored white. When the user hovers over the link, the text color turns red.

Notice that no visited or active pseudo classes are used. This is because the window always ignores the href attribute of this link (it has return false in its event handler). Therefore, the link is never truly active or visited.

Next, the ajaxWebSearchResults class styles the results pane:

.ajaxWebSearchResults
{
    background-color: #d3e5fa;
    padding: 5px;
}

There are no required CSS properties for this element. The existing properties are merely to define the results pane and make it relatively easy to read. The background color is a light blue, and 5 pixels of padding surround the edges. You can also style the loading message:

.ajaxWebSearchResults div
{
    text-align: center;
    font: bold 14px tahoma;
    color: #0a246a;
}

This element does not have a class name, but you can still style it by using the parent child notation shown in the preceding example. This example places the text in the center of the <div/> element and gives it a bold, blue font 14 pixels high.

The last elements you need to style are the result links. These have a class name of ajaxWebSearchLink:

a.ajaxWebSearchLink
{
    font: 12px tahoma;
    padding: 2px;
    display: block;
    color: #0a246a;
}a:hover.ajaxWebSearchLink
{
    color: white;
    background-color: #316ac5;
}a:visited.ajaxWebSearchLink 
{
    color: purple;
}

The only required property is the display property, which is set to block. This gives every link its own line. The padding, two pixels worth, gives a bit of separation between the links, making them easier to read. The font-face is Tahoma and is 12 pixels high. Their color is a dark blue, giving a nice contrast to the light blue background of ajaxWebSearchResults.

When the user hovers over these links, the background color is set to blue, whereas the text color changes to white.

The visited pseudo class is set, in the last rule in the previous code. This is to provide users with user interface cues they are already used to. By having the visited pseudo class set to display a color of purple, users know they've already visited that link, which can save them time by not visiting a page they may not want to.

Now, let's take a look at how to implement the widget.