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

Excerpt from Professional Ajax

Creating an Ajax Search Widget

By Jeremy McPeak

The most widely used function of the Web is searching. It's not even an option; if you want to find any information, the search engines of the Web are the places you have to go to.

With the ever-expanding technology of the Web, conventional search engines are opening the doors to more unconventional means to get you to the content you desire. The first to jump onto the scene was Yahoo! with their Y!Q service (http://yq.search.yahoo.com/publisher/index.html). This new service enables you to search from any web page, provided the page's author includes it in their web page. It is a service to provide related search results to the content at hand, giving readers more information at their fingertips without leaving your page.

The Yahoo! Y!Q service is a great idea, but it hasn't surfaced without criticism. The main argument? It requires the use of Yahoo!'s JavaScript and you have to add a <form/> element, meeting the Yahoo! requirements, to perform the search. For many web site authors, it takes too much effort to provide the service. And after all the work, the search results are presented in the Yahoo! style, breaking the look and feel of your web site.

Thankfully, Yahoo! isn't the only search engine breaking into this "provide search results from your web site" service. MSN Search (http://search.msn.com) provides a similar service, except it enables the web developer to control the look, feel, and implementation. This ability comes from MSN Search providing RSS versions of its search results, making it possible to subscribe to a particular search or add the results to your page using Ajax methods.

Google has yet to throw its hat into this new spin on "search from your site" technique, although, at the time of this writing, Google released Google BlogSearch Beta (http://blogsearch.google.com), which provides results returned in either RSS or Atom formats.

The Server-Side Component

Perform a search with MSN Search, and you'll see an orange XML image at the bottom of the results page. Clicking this image takes you to a new page, giving you the URL to subscribe to the search:


With this knowledge, you can write the server-side code to retrieve the remote feed. For the widget, you will use PHP to retrieve the search feed. The URL to request information from the server application looks like this:


There's only one variable in the query string: search. Therefore, the application should look for this query item. On the server, you'll need to create a page to pull this data:

header("Content-Type: text/xml");
header("Cache-Control: no-cache");if ( isset($_GET["search"]) ) 
{    $searchTerm = urlencode( stripslashes($_GET["search"]) );
    $url = "http://search.msn.com/results.aspx?q=$searchTerm&format=rss";
    $xml = file_get_contents($url);
    echo $xml; 

The first two lines set the required headers so that the browser will handle the data correctly (as XML and without caching the results). The next line of code uses the isset() function to determine whether the search key is present in the query string.

The search term should go through a variety of functions in order to send a proper request to the remote host. First, it is passed to the stripslashes() function. If magic quotes are enabled in the PHP configuration (which is the default), any quote that reaches the PHP engine is automatically escaped with a slash: \"search query\". The stripslashes() function removes these escape sequence, leaving only "search query". After the slashes' removal, it then goes to the urlencode() function, which properly encodes characters to be used in a query string. Spaces, quotes, ampersands, and so on are all encoded.

If the search term does not go through these processes, the MSN server will return a code 400: Bad Request.

When the search term is ready for transmission, it is included into the URL and stored in the $url variable. Finally, the file_get_contents() function opens the remote file, reads the contents, and returns it as a string to the $xml variable, which is printed to the page using the echo command.

The Client-Side Component

The client-side code from this widget is based on a static object called msnWebSearch, which is defined as an object literal without any properties (for now):

var msnWebSearch = {};

This object is used in the onclick event of an HTMLElement in order to perform a search:

<a href="#" 
onclick='msnWebSearch.search(event,"Professional Ajax"); return false;'>
    Professional Ajax

The msnWebSearch object exposes several methods to get the search results and to draw and position the HTML to contain the data. The first method is drawResultBox(), which draws the HTML. The HTML this method draws looks like this:

<div class="ajaxWebSearchBox">
    <div class="ajaxWebSearchHeading">MSN Search Results
        <a class="ajaxWebSearchCloseLink" href="#">X</a>
    </div>    <div class="ajaxWebSearchResults">
        <a class="ajaxWebSearchLink" target="_new" />
        <a class="ajaxWebSearchLink" target="_new" />

The result box is divided into two parts: a heading and a results pane (see Figure 1). The heading tells the user that this new box contains results from an MSN search. It also contains an X, which will close the box. The results pane contains block-style links, which opens a new window when clicked.

Figure 1