Tuesday, January 3, 2012

Autocompletion with Scriptaculous and Ajax


This tutorial supercedes my previous turtorial on autocompletion by adding further tips and tricks to make your autocompletion a much better experience for your site users The tutorial is structured in the following way:
  1. Introduction: What is autocompletion and why use it?
  2. How it works.
  3. Getting scriptaculous and building the form.
  4. Building the autocomplete server.
  5. Passing back an id to our form.

1. What is autocompletion and why use it?

I predict that most people will want to skip this section and get straight to the action, so I will keep it brief. Autocompletion is a means of helping your users when filling in forms. The most common application of autocomplete is found in your web browser’s address bar; as you type the bar makes suggestions of URLs based on previous pages visited. In our example we will query a database of musical artists and give our users suggestions as they type in an artist name field.

2. How it works.

As a user types in a specific input field on a form, on each key up event, we use JavaScript to call a script in the background using Ajax (XMLHttpRequest) features built into the Scriptaculous library. Our form will pass the currently typed text to this script and the script will return a list of suggestions which will be dynamically placed in our page. The important thing is that our user can select one of these items by mouse-click or key-stroke to populate the form field instantly.

3. Getting scriptaculous and building the form.

This implementation of autocomplete requires 3 components:
  1. The Scriptculous libraries;
  2. An HTML form with a single field;
  3. An autocomplete server script
I use PHP as my language of choice for the autocomplete server script, but I have tried to keep this tutorial abstract enough to allow you to use your language of choice. The server script is the only thing that changes for different server-side scripting languages. Download the latest version of the Scriptaculous JavaScript Libraries and include them in the head of a new HTML document as below.

Don’t forget to change the paths to match your directory structure:

<script type="text/javascript" src="lib/prototype.js"></script>
<script type="text/javascript" src="src/scriptaculous.js"></script>


Now add a form to your HTML page’s body. In this form we are going to add a field that will take our search term (with both id and name attributes as “searchterm”) and an empty div with an id of “hint”. This empty div acts as a holder for our hints when they are generated. You should have some HTML looking like this:

<input type="text" name="searchterm" id="searchterm" />
<div id="hint"></div>


All we need now is to initiate a new call to Scriptaculous’ built in Ajax.Autocomplete method below our HTML code for the autocompleter – like this:

<script type="text/javascript">
new Ajax.Autocompleter(”searchterm”,”hint”,”server.php”);
</script>


The Ajax.Autocompleter takes 3 arguments: The element supplying the search string, the element to show suggestions in and the server script that will generate our suggestions. With that in place we can write the server script.

4. Building the autocomplete server.

The following server is written in PHP connecting to a MySQL database but you can your language of choice and even a flat text file or XML file for the suggestion database. My database table, “Artists”, is simple – it comprises a unique id field and an artist “name”.
As the Autocompleter sends the value of a form field as a POST variable, we can use this in our server script’s query againstthe database. All we need to do is output an unordered list for the autocompleter. Scriptaculous does the leg work of inserting the latest list into our hint box everytime the user makes a keystroke. Here is my server code in PHP

<?
// don't forget your database connection here.
echo "<ul>";
$sql = "SELECT * FROM artists WHERE name LIKE '%" . $_POST['searchterm'] . "%'";
$rs = mysql_query($sql);
while($data = mysql_fetch_assoc($rs)) {
echo "<li id=\"" . $data['id'] . "\">" . $data['name'] . "</li>";
}
echo "</ul>";
?>


Note that I have given each list item an id that is the same as that of the record. We will use this shortly for a more advanced technique. But for now we have all we need for a basic autocompleter.

5. Passing back an id to our form

Once a user has selected an item from the autocompleter, the string is entered into the textfield. Often, for the sake of efficiency and accuracy it is better to deal with the id of the item than the string name when it is passed on to the next page. To do this we can use some extra functionality of Ajax.Autocompleter along with some JavaScript that will pass the id to a hidden field in our form.

The first thing we need to add to our form is a hidden field with an id that we can reference:

<input type="hidden" id="artist_id" name="artist_id" />

Now we can use an extra piece of functionality built into Ajax.Autocompleter that allows us to pick up the id that we included in our list item from the server script. This is an extra option on our autocompleter call:

new Ajax.Autocompleter(”searchterm”,”hint”,”server.php”, {afterUpdateElement : getSelectedId});

We are telling our autocompleter to run a function called getSelectedId when an item is selected. All we need to do now is write this function to get the id and inject it into our hidden field. Insert the function below the

function getSelectedId(text, li) {
$('searchterm').value=li.id;
}


And that’s all there is to it. Of course you can be as clever as you want with your autocomplete server script. Try using the LIMIT clause in your SQL to make it run faster. Make your queries more advanced to bring back more specific results. And don’t forget the fun you can have with CSS on your hint div and the list of suggestions that it displays. If you have any implementations of autocompletion using this tutorial, please post them in the comments here.

No comments:

Post a Comment