Over on Ajaxian, there were some interesting comments following from the “Ajaxifying the Address Bar” entry here last week. I made a little live search demo to show the kind of idea I had in mind. Please try the Live Search Demo for yourself and let me know how you find it.

The FAQ is over there, but for all the RSS readers, here’s a copy as it stands right now. Jump to the second half for the programming details.

Using the Live Search

How Do I Highlight the Icons?

It's all demo stuff, everything gets processed by the server, but no actual lookups going on. So some crude rules apply here ...

Web
Anything matches.
Phone
Type something resembling a phone number. (e.g. 555-1212)
People
Type an email address or a Simpsons family name.
Calculator
Type a basic calculator (e.g. 10/5)
News
Include a newsworthy term, e.g. "scandal" or "talks".

Huh? It's Supposed to be a Search Demo - How About, Oh I dunno, RESULTS??!!

There are no answers here, only questions.

It Doesn't Work on My Browser

I'm interested in your compatability dillema. If you've got Javascript enabled and it's not working, please tell me what browser you're using.

Oh, So It's All Pretty Lame, Huh?

Yeah, lame. The main point here is that all the terms are sent to the server, which decides on the categories. You could imagine it providing other info too, like an estimate of the result quantity. Or the results themselves.

Do you have any suggestions for a way to make the demo more realistic? Please send pointers to any interesting data repositories which could be held entirely in a memory cache of a few megs. Or any categories which could be calculated algorithmically.

Background

What's This Live Search About?

A demo of AJAX - a new term for a relatively new way to make the web more dynamic. Written by Michael Mahemoff. Please mail any comments to [email protected].

Why do you call "Live Search" a pattern?

It’s a neat way to resolve the conflicting forces of user information needs and bandwidth limitations. In one form or another, several people have discovered this idea, so I’m capturing it as one of the Ajax patterns.

Whatever. Bodacious Icons, Dude!

If only I made them myself. They’re actually the Crystal Icons for KDE, released by Everaldo under LGPL license. Downloaded from LinuxCult.

Underlying Technology

How Does It Work?

You’re perhaps looking for some Ajax tricks. Most of it is apparent by viewing the source. I’ll highlight some of the take-home messages.

Calling the Server

Calls to the server are made by ajax.js, which offers a facade to the XMLHttpRequest object. so you can do this:

callServer(url, 'drawInitialCategories',
                      true, true, null, postvars);

… Which calls the given URL and sends the response to the drawInitialCategories() callback method. The options specify plain-text response (not XML), GET request (not POST), and null calling context object to be passed back to the callback method. Postvars is an array of variables passed as part of the request.

The library builds on some ideas posted by Richard Schwartz. And, more specifically, code posted in a comment there by John Wehr. John’s just started AjaxKit and I’ve been talking to him about contributing.

The library is seriously untested, so right now, use (if at all) with caution. The main benefit is thread safety. Compared to the standard pattern, which uses a global XMLHttpRequest, a new one is created each time. It’s also destroyed after the response returns.

Setting Up the Images

The categories are downloaded using a query to the server upon load. To keep things simple, image names are based on categories. Each image is then added to a fragment, and the whole thing is added to a div on the page in one final operation. categoriesFragment = document.createDocumentFragment(); for (i=0; i<allCategoryNames.length; i++) { categoryName = allCategoryNames[i]; var categoryImg = document.createElement(“img”); categoryImg.id = categoryName + “Category”; categoryImg.src = “http://localhost/ajax/liveSearch/images/”+categoryName+”.gif”; categoryImg.style.backgroundColor=”#cccccc”; categoryImg.title = categoryName; categoriesFragment.appendChild(categoryImg); } document.getElementById(“categories”).appendChild(categoriesFragment);

Acting On Input

Like “Google Suggest”, the search uses Submission Throttling. That is, don’t query upon each keypress. Instead, every 50 milliseconds, it checks the server if the query has changed. This is achieved with a setTimeout() at the end of the request method, which calls itself. A BASIC equivalent would be “10 Do something; Sleep; GOTO 10”.

  function requestValidCategories() {
    ...
    ...(Call the server if the query has changed)...
    ...
    setTimeout('requestValidCategories();',50);
  }

Acting On Responses

The mechanism above shoots off a query to the server whenever the query has recently changed. It’s an asynchronous query, so the response will be sent to a callback method. In this case, updateValidCategories. UpdateValidCategories walks through each category and decides if it’s currently valid. Based on its validity, it updates the background colour, cursor, and onclick action. Note that the images are transparent, so it’s easy to turn them on and off by flicking the background colour.

    if (validCategoryNames[categoryName]) {
      categoryImg.style.backgroundColor="yellow";
      categoryImg.style.cursor="pointer";
      categoryImg.title = "Category '" +
           categoryName + "'" + " probably has results";
      if (categoryImg.setAttribute) {
        categoryImg.setAttribute("onclick",
            "onCategoryClicked('" + categoryName + "')");
      }
      ...
    } else {
      ...
      ... (turn it off) ...
      ...
    }