Oli Warner About Contact Oli on Twitter Subscribe

AJAX search with MS Live and mootools

Saturday, 13 January 2007 ajax microsoft programming search

If you currently own a web site with a search box, chances are you push it off on Google or you search your own database. There are problems with both these systems though.

Outsourcing degrades the look and feel of your website because you’re forcing the user to leave your site for their results.

Searching your own database might seem like a plan but when you have static pages like “About Me” posts, your results will never encompass all of them.

Therefore you can send your server off to the Microsoft Live Search API and have it get the results your users would see through a normal site search. Outsourcing the searching and indexing but keeping it totally within your site and design.

Why aren’t we using Google? Google decided to stop handing out their API keys, making it a little difficut to use their search data.

What if I’m not indexed by MS Live? Then that’s a stopping point. you’ll be limited to database searching until they have you. You can skip to step 2 if you want to use AJAX searching still.

You just want to build a standard search for now. Worry about the AJAX side of things later! You want this to work for people that don’t have JavaScript enabled, so we’re going to start here.

Now you’re going to need to hook into the MSN API. How you do this changes slightly with each language. If you’re using PHP I recommend this article from fiftyfoureleven. If you use Ruby/RoR you could do a lot worse than look at Bogle’s entry on wrapping up the web service and use that to query MSN and generate your output.

Once you have the basic queries being sent, you might want to tune them up so they only work for content on your site which can be done by adding:

site:www.yoursite.com

to the beginning of the query. Additionally you may wish to cut out certain pages so they never feature in your results. You can cut them out the equation by limiting the URLs it will return:

site:www.yoursite.com -inurl:/ex/ -inurl:/ex2/ user-query

The actual query turning up at Microsoft’s end should look like this:

site:www.yoursite.com -inurl:/ex/ -inurl:/ex2/ user-query

Step 2. Strip-down Step 1’s output

By now you should have a script that will output things in full for non-AJAX requests. What you want to do now is the same again but without the rest of your page loading alongside it, just the results’ HTML.

This is such a simple step that I’ll leave you to it =)

Step 3. Build the AJAX UI

By this I mean you want to make the form to go on your pages which post to your existing form or load the results if the user has JavaScript enabled.

I use a simple form and nest it at the top of one of my columns using this HTML:

<form id="barSearchForm" action="/search" method="get">
<div id="barSearch">
<div id="barSearchBox">
<input id="barSearchQ" name="q" type="text" value="" />
</div>
</div>
</form>

There is a separate location (at the top of another column) where the results come out defined by this HTML:

Step 4. AJAXify

With this we take text value from the form built in Step 3, the output from Step 2, using AJAX and load it into designated output location also defined in Step 3. Sounds quite complicated but using mootools, it couldn’t be easier. You’ll need to head there and download the library, upload it to your server and instal it by putting this in your documents’ header (changing “/moo.js” to your path):

<div id="searchCont">
<div id="searchAJResults"></div>
</div>

I’ve gone further, adding effects (also provided by mootools) to enhance the experience. You will want to play around with effects to see what suits your site but my full code is:

var sBar;
var sTimeout;
var sFX;
var sFX2;

function searchInit() {
sBar = $('searchAJResults');
if (!sBar) return;
sFX = new Fx.Height(sBar, {duration:200});
sFX2 = new fx.Style(sBar, 'padding', {duration:50});
sFX.set(0);

$("barSearchQ").addEvent('keyup',function(){
if ($("barSearchQ").value.replace(/^\s*|\s*$/g,"")=="") {
sFX2.goTo(0);
return sFX.goTo(0);
}
window.clearTimeout(sTimeout);
sTimeout = window.setTimeout(SearchProcess, 2000);
});
}

function SearchProcess() {
sFX.goTo(0); /* reset the output zone */
sFX2.goTo(0); /* and some more */

var wowJAX = new Ajax("/ajax/search", {
method: 'post',
postBody:$('barSearchForm').toQueryString(),
update:sBar,
/* when done, open up the output */
onComplete:function(){
sFX2.goTo(8);
sFX.goTo(sBar.scrollHeight);
}
}).request();
}

You then want to call searchInit() when your DOM is ready. If you have another window.onLoad method, whack it in there, if not use mootools to add the function:

Window.onDomReady(searchInit);

You will probably want to revisit Step 2 and tidy up your output and add some CSS classes in there to neaten things up. But apart from that, you’re done. Congratulations!