Using AJAX and Server Side Search

I've blogged before (or at least think I have) about how to do client side filtering/searching of data with Spry. An example of this is the search at RIAForge. The concept is simple. Load your dataset. Then simply filter against this dataset. RIAForge lets you filter both on the keyword you enter and the category. While this does require some JavaScript work, it is still pretty darn simply in Spry. (I encourage you to view source on the page.) However, there are a few drawbacks to this approach.

The first problem is that you have to load the entire dataset. This works ok for small sets of data, but once you get to a large dataset, it isn't practical to load everything into the client. RIAForge's search is actually getting a bit close to that now.

The second problem is that your limited to searching with JavaScript functions. While JavaScript lets you do basic comparison, substring, and regex checks, you can't do some of the more fancier searches you could do on the server side. A great example of this is Verity. Verity has some kick butt/super ninja style cool search styles. None of which are available to you in JavaScript, and all of which could be very useful to your users.

So can we use AJAX and search side search together? Sure! Consider this demo:

http://ray.camdenfamily.com/demos/sprysearch/

This demo uses AJAX to call the back end and pass in the search terms to ColdFusion. Now in this simple demo I am just going a simple SQL statement. It could very easily have been handled by JavaScript. But I'm searching against nearly 2000 records. I certainly would not have wanted to load that into the client.

While you can view source and see everything, let me point out a few interestings aspects. First off - this is the code fired when you hit the search button:

function search() {
   var searchvalue = $("searchterms").value;
   if(searchvalue == '') return;
   dsResults.url = "search.cfm?term="+escape(searchvalue);
   dsResults.loadData();
}

I grab the search value from the form field, and if it isn't blank, I update the URL of the dataset and tell Spry to load it. Pretty simple, right?

The only other fancy thing I do isn't even really related to this blog entry, but I'll point it out anyway. I wanted to always show something when you searched, even if your search turned up nothing. (Try searching 'purple monkey blueberry muffins'.) I wrote a simple observer that runs when the data is done loading from the back end.

var myObserver = new Object;
myObserver.onPostLoad = function(dataSet, data) {
   var results = $("resultText");
   var total = dataSet.getRowCount();
   results.innerHTML = "Your search returned "+total+" result(s).";
};
dsResults.addObserver(myObserver);

Pretty simple I think. I basically cut and paste the code from the documentation for observers. Basically I'm telling Spry to run this function when my dataset gets loaded. I call the getRowCount() function and then use that to display the total count of the results.

As a follow up to this article - I think I may actually switch to using Verity and see if I can find a nice way to return the suggestions data!

Comments

Great example. Easy to follow and adapt to my own requirements.
# Posted By Bruce | 4/7/07 10:45 AM
Take a performance hit but to make it search as they type:

Add in an onchange="search();" to the text input form field

then in the javascript change if(searchvalue == '') return;
to if(searchvalue == '' || len(searchvalue) < 3) return;

I added a check so it doesn't fire off the search until there are 3 characters.
# Posted By Scott P | 4/7/07 12:58 PM
I don't know why - but I tend to avoid using automatic behaviour when it has the chance of being slow. Using the min length helps, but I'd still be wary.

Of course, it could just be that I'm an old fogey. ;)
# Posted By Raymond Camden | 4/7/07 1:21 PM
Very slick. An enhancement to blogCFC next version perhaps?
# Posted By Sam Farmer | 4/7/07 6:16 PM
I clicked the Spry Search link above (as well as in part 2 of this article) and tried searching for basic terms ("coldfusion", or "lost") and found nothing. The code ran without errors, but I received no error or success messages, and also received no "found nothing" messages.

Same behaviour in IE and FF. Am I running the right link?
# Posted By Andy Matthews | 4/7/07 8:52 PM
@Sam - I've been unhappy with the search for a while. That's why it changed a bit in the last release. I'd like to use Verity in BlogCFC as well so that may get added.

@Andy - Not sure what to tell you. Is your JS turned off? No one else is reporting this.
# Posted By Raymond Camden | 4/9/07 7:01 AM
Hi Ray - looks nifty, but am getting the same issues as Andy. I'm on FF 2.0.0.3.
# Posted By Aaron Longnion | 4/9/07 8:27 AM
So no JS errors? And JS is turned on? Are using the button and not the ENTER key?
# Posted By Raymond Camden | 4/9/07 9:22 AM
ah-ha. Interesting... Pressing enter returns the empty results (sends me from http://ray.camdenfamily.com/demos/sprysearch/ to http://ray.camdenfamily.com/demos/sprysearch/?), but pressing the button works like a charm. Also, obviously tabbing to the button and pressing enter works fine as well.
# Posted By Aaron Longnion | 4/9/07 10:08 AM
Yep, someone earlier mentioned it. I was too lazy to fix it. ;) I'll try to a bit later since there is no excuse for me being lazy. :)
# Posted By Raymond Camden | 4/9/07 10:13 AM
I fixed the "hit enter no worky" thing.
# Posted By Raymond Camden | 4/9/07 10:28 AM
groovy... it worky in my FF and IE 7 now. ;)
# Posted By Aaron Longnion | 4/9/07 10:41 AM
is it possible to post the source code for the page search.cfm?
# Posted By private | 4/22/07 3:28 PM
All it is a Verity search using cfsearch.
# Posted By Raymond Camden | 4/23/07 9:42 AM