Ajaxifying Pivot: How did I do it? part II
In the previous part I explained how I created the nice instant preview functionality in my comment forms. Some people have asked me why I did this with Ajax and a server side PHP script. The reason for this is Textile. There's a javascript Textile implementation out there on the net but it doesn't quite support everything Textile offers. Since a preview is nonsense if it shows something that isn't exactly like it's going to be before posting a comment I figured it had to be 'all or nothing' and I implemented an Ajax preview. Theoretically it could be made to be 'real-time' by updating it every couple of seconds. I'm not sure about that yet because it can cause quite some stress on the server when someone's writing a long posting.
Now that we have that out of the way, let's move on to something even more exciting: implementing a real 'live search' for Pivot with Ajax and PHP.
What is live search?
A demonstration often reveals more than a thousand words can tell you. Therefore if you haven't seen the live search in action yet I invite you to try it out. Try to type something in the search box on the top right of this website. Don't hit enter but just wait. You get a good example by typing something I write about quite often on this site. Type 'php' for example. After one or two seconds you'll see the magic. A dropdown box appears showing the first ten search hits on 'php' and an additional link to more hits. It looks very similar to Google Suggest, a beta service by Google which suggest search terms you might want to use without ever submitting the form. The live search saves time. Users get instant feedback on actions they perform. This is what makes Ajax so great. It can seriously improve the user experience on any website or web application!
What do most Ajax applications consist of?
If one wants to implement some Ajax functionality it always contains the same components:
- A server-side backend to process user input
- Javascript functions to interact with the server-side backend
- Some (d)html, css for the user interface
The server-side backend is often no different from any other server-side code used in non-Ajax web applications. For the live search in Pivot I took two files that come with Pivot and modified them. The modifications weren't very hard to do. All I did was make some simple changes to alter the output. The javascript and (d)html part is always custom. It usually differs from site to site which is why you can't really copy/paste anything from here directly into your own site. You'll need to do some thinking and coding yourself!
The backend
Pivot's stock search.php performs a search on a Pivot weblog and outputs results using one of the templates defined in the CMS that comes with Pivot. In this case we don't want that! We don't want to get a full xhtml page but just a basic unordered list to use in our live search. Therefore I changed the scripts to return output looking like this:
<ul id="searchlist">
<li><a href="/some/result/page1">Some result page title 1</a></li>
<li><a href="/some/result/page2">Some result page title 2</a></li>
<li><a href="/some/result/page3">Some result page title 3</a></li>
<li><a href="/some/result/page4">Some result page title 4</a></li>
<li><a href="/some/result/page5">Some result page title 5</a></li>
<li><a href="/some/result/page6">Some result page title 6</a></li>
<li><a href="/some/result/page7">Some result page title 7</a></li>
<li><a href="/some/result/page8">Some result page title 8</a></li>
<li><a href="/some/result/page9">Some result page title 9</a></li>
<li><a href="/some/result/page10">Some result page title 10</a></li>
<li><a href="javascript:doSubmit();">n more ...</a></li>
</ul>
There you go, a simple list of search hits, limited to 10 results in order to not make the list really long and ensure fast response by a short loading time. Since I didn't want this article to be a 'How to hack Pivot' class I'm not discussing my hacks here but just offer them here for anyone who wants them. Other people may even want different output than the kind I needed here so additional hacking in Pivot's php source may be necessary.
The front-end html
On the front-end I made some alterations to my page templates. After the alterations the HTML surrounding my search box looks like this:
<form id="thesearch" name="thesearch" action="/weblog/pivot/search.php"
method="post">
<div id="searchform">
<input name="search" type="text" id="searchbox"
value="" onkeyup="doSearch();" onblur="doWipe();"/>
</div>
</form>
<div id="sresults"></div>
As you can see there are two events that call javascript: keyup and onblur. The first one is triggered whenever the user typed something, the second one when the search box loses focus. This means that searches are performed 'as you type'. The function called at the onblur event removes the result box again.
The javascript
Like in the previous example, I'm using the excellent prototype.js library. In addition to the library I wrote a script to enable the search functionality for this site. Here's the javascript:
function doSearch() {
$('sresults').style.display = 'block';
$('sresults').innerHTML = '<span style="color:#fff; padding:5px;">livesearch, just type and wait...</span>';
new Ajax.Updater('sresults', 'http://www.i-marco.nl/weblog/pivot/search2.php', {method: 'post', parameters:'search=' + $F('searchbox')});
}
function doWipe() {
setTimeout('wipeIt()', 1000);
}
function wipeIt() {
$('sresults').innerHTML = '';
$('sresults').style.display = 'none';
}
function submitIt() {
document.forms[0].submit();
}
That's not very much now isn't it? The doSearch() function first makes the div with id sresults visible. It's set to display:none; in my CSS because Internet Explorer shows a box even though there's nothing in the div when it has padding set in the CSS. You might not need this if your search results box is different. Heck, I guess I don't even need it if I make some changes but I'm a lazy guy! After setting the display for the results div it prints a notice in it to show the user something is happening. After that we use the Ajax.Updater object from the prototype.js library to POST whatever is typed in the search box to the backend script described earlier in this article. The Ajax.Updater object takes care of everything. After receiving the server response it automatically fills the div with id 'sresults' with the unordered list you saw earlier, if any results were found.
Of course we don't want to keep the search results displayed forever after performing a search which is why the doWipe() function is called when the search box loses focus. After 1 second (you might want to tweak this timeout value) it empties the div's innerHTML and then sets it's CSS display property to none (that MSIE thing again!).
Finally the submitIt(); function is used when there are more than 10 search results. A link to activate it is added to the unordered list returned by the backend if more than 10 hits were found. The function simply submits the form as if we were hitting the enter key.
Closing notes
The only thing left to do is style the unordered list returned by the backend and the container div (id=sresults) with CSS. I'm not discussing this part here because it's completely different for every website anyway. We're done, we now have a real fancy schmancy Ajax live search! Hopefully this article has shown that Ajax isn't as hard as some people or websites may want you to believe. This is mostly thanks to the excellent work done for us by those who created javascript libraries such as prototype.js. Thanks Steve, I can't thank you enough! It completely hides the underlying XmlHtttpRequest functionality (the core of all Ajax) and it's difficulties from the programmer that wants to create Ajax functionality and leaves the programmer with very litttle javascript code to write.
I hope this article was useful for you. Happy Ajax-ing!
This article is a sequal to Ajaxifying Pivot: How did I do it? part I
Filed under: programming
Number of comments:
Number of trackbacks:
Tagged with: 







At 17 January '09 - 20:34 john wrote: