Live Search

December 12, 2005

This is my first article in the Dive into AJAX series. I will explain how to make a live search for your site. I will use the Prototype and Scriptaculous Javascript libraries for this tutorial. I believe those are the best libs among all others. For more information about the libraries, check out my previous post, Javascript Libraries Roundup.

Here’s what we’ll need. First create 2 blank files index.html and php.php. Place the prototype.js in the same folder and extract the scriptaculous libs in a folder named ’scriptaculous’ !!

We need to add a formfield and an empty DIV tag. The empty tag is where the results show up. Now we need to make a function called Autocomplete. So add this where the Custom JS functions go.

function autocomplete() {
new Ajax.Autocompleter("autocomplete", "autocomplete_choices", "php.php", {paramName: "autocomplete", minChars: 1});
}

Here’s the final HTML:
autocomplete.txt

Ajax.Autocompleter is a built-in function of the Prototype library. The first param is the id of the formfield, the second is the id of where the suggestions will appear, the third of the php file where to make the request. The paramName is the name by which PHP gets the request and the last parameter is the number of character that needs to be typed before the process starts.

Now the PHP. Here it goes, i’ll explain later:
php.txt

First I created an array full of words. I used names of European countries.

Now note the $_POST … yes, that’s what we’ve put as the paramName in the Javascript.

So here’s the algorithm:

  • Finding out the length of the string that’s entered in the formfield with the strlen function.
  • Use a foreach loop so that each item in the array can be dealt with individually.
  • Chopping off the words to the length that’s entered.
  • If you entered “en” .. the length is 2 and the all the words will be chopped to 2 letters. France will become “fr” and England “en”.
  • Matching the chopped word with the string that’s entered with the preg_match function. *
    “en” matches with “en” not “fr”
  • Return the word that was originally chopped.

* Note: the string $entry is wrapped with / and /i … that’s for making sure that its not case sensitive.

The whole chopping thing is done to make sure that only words that START with “en” are listed. If that wasnt done, Sweden would also be listed. If you want it that way, make necessary changes.

Now its time to test. Open up index.html with your browser or just go http://localhost/whatever

You’ll see a humble text box. Enter something. Try E and you’ll see England and Estonia in a list. Neat!

Doesnt that look lame? Yup. Apply some CSS and make it cooler.

#autocomplete_choices {margin: -15px 0 0 -40px;}
#autocomplete_choices li {list-style: none; background: #fff; border-bottom: 1px solid #eee; padding: 2px;}
#autocomplete_choices li.selected {background: #ffb; }

Here’s what it looks like:
Autocomplete
WordPress.com doesnt allow users to upload files so im using Geocities. Im sorry i couldnt provide a live demo. Give it a try and let me know how it goes.

24 Responses to “Live Search”

  1. falcon Says:

    eDevil,
    I’m surprised to read you are from Dhaka, my friend just returned from Dhaka yesterday! You don’t seem to have a private email address, how does one contact you?

  2. edevil Says:

    youre right mate. I forgot to mention my email address in the About section. I just updated the page. cheers!

  3. Chris Says:

    Do you know how to make the drop down list linkable? The default action now when an item is selected from the drop down list is to put that text in the input box. I would like to link to some action when selecting an item from the drop down list. Any ideas? Thanks

  4. billabh Says:

    what i wanna get results from database. I see if you modify array to add / delete words it will apear in search. but lets i wanna all things from database how can I modify array.

  5. edevil Says:

    @Chris: Sure its possible if you know a little bit of PHP. Read the php code i provided and you’ll see that the results are returned as a list like this:

    echo “$word”;

    if you want to make it linkable then you’ll have to use 2 dimensional array. The code might look something like this:

    echo “$word“;

    Give it a shot yourself and let me know how it turns out.

    @billabh: Learn how to interact with database using PHP. Query the database and load results in an array.
    This might help you out:
    http://www.tizag.com/phpT/

    Cheers!

  6. Gijs.com Says:

    A small example for a mysql query you can use.

    SELECT DISTINCT(naam), Id FROM tblName WHERE naam LIKE ‘”.$_POST[autocomplete].”%’ ORDER BY naam ASC

  7. chris Says:

    first.. greets to dhaka.. was there four years ago.. growded.. but people are perfect !

    Is it possible you put the WHOLE Demo in a ZIP File? downloaded this prototype.js ok.. but in the scriptaculous /lib is also the prototype.js.. did you mean in the /src dir? Maybe you or another use can send me the ZIp to ilovesinai@gmail.com would be very nice
    regards
    chris

  8. Azad Says:

    Hi Chris, I’m glad you liked my city.

    unforunately, it is not possible for me to redistribute the scriptaculous libraries. I forgot to mention that prototype.js is included in the scriptaculous pack. My bad.

    Copy prototype.js from the /lib directory and paste it in the same folder as the test html. Copy all the libraries from the /src directory and place them in a folder named ’scriptaculous’ in the test directory.

    So here’s the file structure:

    /scriptaculous/
    – effects.js
    – scriptaculous.js
    – controls.js
    – other libs
    /index.html
    /prototype.js

    I hope that makes it clear. Cheers!

  9. mosphp Says:

    great!! thx for idea on it. but how to adding more variable post to server php.txt file ?!

    i tried
    function autocomplete(val1,val2) {
    new Ajax.Autocompleter(“autocomplete”, “autocomplete_choices”, “php.php?var1=val1&var2=val2″, {paramName: “autocomplete”, minChars: 1});…

    but it doesn’t work,…pls comment !

    thx

  10. mosphp Says:

    also, if there are an array of input box, how do i setting the id for input box and the function script ?!

    thx

  11. mosphp Says:

    one more question, how can i pass the id field into another input box rather than the text field only.

    thx

  12. Azad Says:

    Hi mosphp,
    You could use a hidden field for the id.

    See documentation of Prototype.js and you’ll find how to send 2 POSTs with AJAX at the same time with the function Ajax.Autocompleter.

    Here’s my asumption:
    function autocomplete() {
    new Ajax.Autocompleter(array(“autocomplete”, “id”), “autocomplete_choices”, “php.php”, {paramName: “autocomplete”, minChars: 1});
    }

    Try it and let me know how it goes.

    - Azad

  13. kevin Says:

    Hi mate,

    You have provided a good example, but in IE suggestion list displayed on top of the text box itself, any idea? but Firefox displays correctly.

  14. aaronvegh Says:

    This script has gotten me closer to autocomplete than anything else out there; thanks!

    However, I’d like users to be able to enter items OTHER than what comes up in the list, and choose list items optionally. However, when you tab out of a field, it returns to a blank state if you don’t choose something from the list! Is this by design, or a bug?

  15. paperogiallo Says:

    “Ajax.Autocompleter is a built-in function of the Prototype library”: not true. Indeed, it’s a built-in function of the Script.aculo.us library ;)

    Nice work, BTW.

    Hi.

  16. KaiserSoze Says:

    Hi,

    i’m trying to get this working with a mySQL DB. i can search my table now but only the last record because i’m using ‘while’. Could anybody explain me how to do it so i can search all the records in the table

    while ($row= mysql_fetch_array ($items)){
    		$itemid = $row['ItemId'];
    	    $item = $row['Item'];
    	    $oplage1 = $row['Oplage1'];
    	    $oplage2 = $row['Oplage2'];
    	    $oplage3 = $row['Oplage3'];
    	    $prijs1 = $row['Prijs1'];
    	    $prijs2 = $row['Prijs2'];
    	    $prijs3 = $row['Prijs3'];
    	    $formaat = $row['Formaat'];
    	    $drukvoor = $row['DrukVoor'];
    	    $drukachter = $row['DrukAchter'];
    	    $papier = $row['Papier'];
    	    $gramsgewicht = $row['GramsGewicht'];
    	    $bijzonderheden = $row['Bijzonderheden'];
    	    $afwerking = $row['Afwerking'];
    	     };
    
      	$words = array($itemid, $item, $oplage1, $oplage2, $oplage3, $prijs1, $prijs2, $prijs3, $formaat, $drukvoor, $drukachter, $papier, $gramsgewicht, $bijzonderheden, $afwerking);

    Thanks in advance!

  17. Nick Says:

    Great concept. However, can it be setup to search a site other than having a preset list of items?

  18. Name Says:

    $query = mysql_query(“SELECT DISTINCT(titel) FROM books WHERE titel LIKE ‘%”.$_POST[autocomplete].”%’ ORDER BY titel ASC”);
    while($row=mysql_fetch_array($query)){
    $words[] = $row['titel'];
    }

    makes a array named $words like the tutorial.

  19. KaiserSoze Says:

    Thanks name! :p

    I’d guess your anser was ment for me …

    Call me a n00ber but i still can’t get it working :(

    Here’s my code:

    $query = mysql_query(“SELECT naam FROM dwf_referenties WHERE naam LIKE ‘%”.$_POST[autocomplete].”%’ ORDER BY naam ASC”);
    while($row=mysql_fetch_array($query)){
    $words[] = $row[ naam ];
    }

    Here’s my form:

    autocomplete();

    I would be very happy if someone would help me fixing this!! Otherwise i’ll always have to make sure that the data in the array (way i do it now) is the same as in the database. Thank you,

    Kaiser Soze

  20. JimJam Says:

    Hi all,
    I was wondering – is there a way so that when a user types presses a key in the text box, a .gif image appears and when the all the results have been displayed, it goes away.

    Any help here would be great!!

    JimJam

  21. Jason Says:

    I love this example.
    If you trying to display info from a database try removing the array completely and just displaying the results using while statement. I deleted the array just post information straight to list.

    while ($output = mysql_fetch_array($sql)){
    $hdqid = $output['hdqid'];
    $hdqquestion = stripslashes($output['hdqquestion']);

    echo “$hdqquestion“;

    }

    It works perfectly, just make sure when you write the sql that the $entry variable is above the sql statement.

    The only problem I came across was I wanted to pass a variable to the php file, but couldnt work out how to do it, I used a hidden field but I couldnt get the function to pass it, infact everytime I tried it stopped the whole script working

  22. Peter Says:

    You saved my life. Thank you for the very neat, concise and precise tutorial. Actually it is the first one I come across which is really helpful!

  23. walo Says:

    hi!
    that is a very good and simple script, i like that a lot.
    i want to remove that fade effect, i think that spend user’s time, so do u know how to remove that fade effect on the list div?
    thanks!

  24. walo Says:

    FOR THIS ONE MOSPHP

    function autocomplete(val1,val2) {
    new Ajax.Autocompleter(”autocomplete”, “autocomplete_choices”, “php.php?var1=val1&var2=val2″, {paramName: “autocomplete”, minChars: 1});…

    YOU HAVE TO ADD AN \ BEFORES THE ? SYMBOL

    “php.php\?var1=val1&var2=val2″


Leave a Reply