Autocompletion with Scriptaculous and Ajax.

March 9th, 2008 by Tim Leave a reply »

Demo here | Download sample files

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.

—————————-

Single ply membrane Products

Share it:
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • LinkedIn
  • Reddit
  • Netvibes
  • Twitthis
  • email
Advertisement

71 comments

  1. Nigel PT says:

    @Aaron

    This is an SQL function. In the SQL line, remove the FIRST percentage [%] symbol

    …….LIKE ‘%” . $_POST['search'] . “%’”;

    becomes

    …….LIKE ‘” . $_POST['search'] . “%’”;

    Now the data found = ’search’ + anything

    This means that ‘S’ will find Sanders, Smith, Smyth
    This means that ‘SM’ will find Smith, Smyth
    This means that ‘SMY’ will find Smyth

    HTH

  2. Piet says:

    Is it posible to search for more the one item? See example above

  3. Alexandra says:

    Hi !

    That is marvelous, I have been searching for month for such a script.

    Could you just give me the last little help….

    I’m searching all night long but I cannot pass the ID…

    Here is my code :

    _____________________________

    Type here

    new Ajax.Autocompleter(”search”,”hint”,”server.php”);
    new Ajax.Autocompleter(”artist_id”,”hint”,”server.php”, {afterUpdateElement : getSelectedId});
    function getSelectedId(text, li) {
    $(’artist_id’).value=li.id;
    }

    __________________

    Can you tell me what is wrong ?

    Thanks thanks thanks in advance, I cannot find the solution !

    Alexandra

  4. Alexandra says:

    Hi Tim

    Your script is so great !

    Here is my page :
    http://www.orbifly.com/test/ajax/autocomplete.php

    I cannot pass the ID, can you help ?

    I cannot find why it does not work….

    Well it is now 4:30 in the morning, I’ll go to sleep, and work on that again tomorrow…

    Please heeeelp !

    Alexandra

  5. Alexandra says:

    There was a problem with accents.

    I could correct the bug with accents thanks to that function :

    function safeName($string)
    {
    $patterns = array(’é’,'è’,'ê’,'à’,'â’,'ù’,'ü’,'û’,'ä’,'ë’,'ï’,'ç’,'ô’,'ö’,'ñ’,'ß’,
    ‘É’,'È’,'Ê’,'À’,'Â’,'Ù’,'Ü’,'Û’,'Ä’,'Ë’,'Ï’,'Ç’,'Ô’,'Ö’,'Ñ’);
    $replacements = array(’é’,'è’,'ê’,'à’,'â’,'ù’,'ü’,'û’,'ä’,'ë’,'ï’,'ç’,'ô’,'ö’,'ñ’,'ß’,
    ‘É’,'È’,'Ê’,'À’,'Â’,'Ù’,'Ü’,'Û’,'Ä’,'Ë’,'Ï’,'Ç’,'Ô’,'Ö’,'Ñ’);
    $string=str_replace($patterns, $replacements, $string);
    return $string;
    };

    then you modify the name that appears in LI tags :

    $label = safeName($data['id']) ;

    echo $label ;

    ——————————

    I hope this will help.

    But pleeeasse, can anybody help me on the way to pass the ID ?
    I cannot find an answer, the variable is transmitted empty…

    My code below, thanks for help.

    Alexandra

    ______________________

    in autocomplete.php :

    [input type="text" id="search" name="search" /]
    [input type="text" id="artist_id" name="artist_id" /]

    [div id="hint"][/div]

    [script type="text/javascript"]
    new Ajax.Autocompleter(”search”,”hint”,”server.php”);
    new Ajax.Autocompleter(”artist_id”,”hint”,”server.php”, {afterUpdateElement : getSelectedId});
    function getSelectedId(text, li) {
    $(’artist_id’).value=li.id;
    }
    [/SCRIPT]

  6. Alexandra says:

    Well, I replaced

    [li]

    by

    echo “[li id=\"".$data['id'].”\”]” ;

    which should improve.
    But still not enough to make it work.

    Mayday, folks !

    Alexandra

  7. Alexandra says:

    I SOLVED MY PROBLEM !!!!!!
    YEESSSSS !!!!
    (it took me… more than 10 hours to find the problem !!!)

    In fact, there is a little mistake on the tutorial.

    So for all those struggling to transfer the ID, here is the tip :

    in server.php, modify the [LI] tag, it has to be [LI id="you id..."]

    That gives :

    echo “[li id=\"".$data['id'].”\”]” ;

    in autocomplete.php, here is the deal :

    [script type="text/javascript"]
    new Ajax.Autocompleter(”search”,”hint”,”server.php”);
    new Ajax.Autocompleter(”search”,”hint”,”server.php”, {afterUpdateElement : getSelectedId});
    function getSelectedId(text, li) {
    $(’artist_id’).value=li.id;
    }
    [script]

    Both autocompleter call “search”, and only the function calls artist_id !!!

    I’m HAPPYYYYYYYYYYY !!!!

    Alexandra

  8. Alexandra says:

    Well…. it does not work so well.

    Let’s say it works 100% on Mozilla Firefox, but it works 5% on Internet Explorer !!!

    WHY ?

    Heeeelp !

  9. Alexandra says:

    I solved my problem again !
    Now it works on both Firefox and Explorer.

    In fact, I had to remove the first Autocompleter call.

    So I replaced :

    [script type="text/javascript"]
    new Ajax.Autocompleter(”search”,”hint”,”server.php”);
    new Ajax.Autocompleter(”search”,”hint”,”server.php”, {afterUpdateElement : getSelectedId});
    function getSelectedId(text, li) {
    $(’artist_id’).value=li.id;
    }
    [script]

    by :

    [script type="text/javascript"]
    new Ajax.Autocompleter(”search”,”hint”,”server.php”, {afterUpdateElement : getSelectedId});
    function getSelectedId(text, li) {
    $(’artist_id’).value=li.id;
    }
    [script]

    And now everything is fine on Explorer too !

    Alexandra

  10. rk says:

    The script is great, Thanks for this wonderful script.

  11. Steve says:

    Has anyone had any trouble with up/down arrow keys not working with the hint?

    Really nice writeup, thanks for posting.

  12. ChrisW says:

    I also have the problem of arrow keys not working. (Win, IE8 & FF).

    Otherwise, Thank you for the script, its great!

    PS. showing error messages could help implementing..

  13. joet says:

    Is there any way to clip out what’s absolutely necessary from prototype.js? It’s 138k. That’s a total deal breaker for most web sites. If someone hits your site from a mobile phone or dial-up and everything is kaput.

  14. Jeremy says:

    This script is exactly what I was looking for, however like the others who have commented before me, the arrow keys do not work to select the item. They work in the demo above however. I tried downloading the code and putting it on my web server unmodified (Except for the DB parameters in server.php) and the arrow keys also do not work there.

    Can someone please post the solution to enabling the selection of the item in the ‘hint’ div with arrow keys?

    Thanks,
    -Jeremy

  15. Cinto says:

    In order for the up/down arrow to work, you need to add in this line inside the css style:

    li.selected { background: #FCC;}

  16. freddy says:

    to fix arrow keys not working

    add this line into autocomplete.php

    li.selected { background: #FCC;}

    it is missing in the demo files this is where to place the missing code

    body {font-family: verdana; arial, sans-serif; font-size: 12px; }
    #search, ul { padding: 3px; width: 150px; border: 1px solid #999; font-family: verdana; arial, sans-serif; font-size: 12px;}
    ul { list-style-type: none; font-family: verdana; arial, sans-serif; font-size: 12px; margin: 5px 0 0 0}
    li { margin: 0 0 5px 0; cursor: default; color: red;}
    li:hover { background: #ffc; }
    li.selected { background: #FCC;}

  17. Neenz says:

    Thanks for the code.

    Can someone please tell me how the format of server.php.
    Am using a WebFOCUS program at my back end to get data from the data base and its returning a string – apple,bat,cat,…..
    Will this work, or does it need a specific format????

  18. ad2sound says:

    Is it working with Classic ASP ? If yes can you help me with an example to write correct asp Query ?

    Thanks in Advanced

  19. Jason says:

    What should the response of the server script look like?

Leave a Reply