JQuery Autocomplete in php search

JQuery Autocomplete

Use jQuery to make a "Google style" autocomplete function for your forms. Help your visitors find things by searching in a database table for suggestions as they type and showing the results dynamically.

Download Zip
View Demo


I'm going to assume that you have a pretty good knowledge of PHP, MySQL, JavaScript and know a little bit about jQuery too. We'll be using the jQuery Javascript Library in this script. You can always download the latest version here.

Required Files
autocomplete.css - CSS styling
jquery.autocomplete.js - jQuery code for our Autocomplete script
jquery-1.3.2.min.js - The jQuery Javascript library
search.php - PHP script that will grab the results as the visitor types
search-form.php - HTML form

HTML form

In this example we're going to have a simple search form with just a keywords field. Here's our code:


01.<html>
02.<head>
03.<title>Search Matches Exampletitle>
04.<style type="text/css">
05.body { font-family: Arial, Helvetica, sans-sarif; font-size: 12px; }
06.#q { width: 200px; }
07.style>
08.<link href="autocomplete.css" type="text/css" rel="stylesheet" />
09.<script type="text/javascript" src="jquery-1.3.2.min.js">script>
10.<script type="text/javascript" src="jquery.autocomplete.js">script>
11.head>
12.<body>
13. 
14.<form name="search">
15.Search: <div id="matches-container"><div id="matches">div>div><input type="text" name="q" id="q" size="40" autocomplete="off" /> <input type="submit" value="Go" />
16.form>
17.body>
18.html>

Take note of the two
's right before the text field. The #matches-container is the box that will be display our results inside and #matches is the element that will be dynamically updated with our results.

Styling the Autocomplete Box

Here is our CSS code to style our autocomplete box that we put in autocomplete.css.

1.#matches-container { position: relative; display: inline; }
2.#matches { display: none; position: absolute; top: 7px; left: 0px; width: 300px; border: 1px solid #999999; background: #EEEEEE; color: #666666; font-size: 11px; padding: 3px; }
3.#matches .match { font-weight: bold; color: #000000; }
4.#matches ul { list-style: none; padding: 0px; margin: 0px; overflow: hidden; white-space: nowrap; }
5..match-hover { background: #DFDFDF; cursor: pointer; }
6..match-highlight { background: #DFDFDF; }

Adjust the colors, padding and widths to your needs. If you use this code, it should line up directly underneath your textbox.

Populate the Database

We're going to keep things simple and just search a table that has a list of US States. Here's the SQL code to create the table and input all the states.

01.CREATE TABLE `us_states` (
02.  `id` int(2) NOT NULL auto_increment,
03.  `state` varchar(25) NOT NULL,
04.  PRIMARY KEY  (`id`)
05.);
06. 
07.INSERT INTO `us_states` VALUES ('1', 'Alabama');
08.INSERT INTO `us_states` VALUES ('2', 'Alaska');
09.INSERT INTO `us_states` VALUES ('3', 'Arizona');
10.INSERT INTO `us_states` VALUES ('4', 'Arkansas');
11.INSERT INTO `us_states` VALUES ('5', 'California');
12.INSERT INTO `us_states` VALUES ('6', 'Colorado');
13.INSERT INTO `us_states` VALUES ('7', 'Connecticut');
14.INSERT INTO `us_states` VALUES ('8', 'Delaware');
15.INSERT INTO `us_states` VALUES ('9', 'District of Columbia');
16.INSERT INTO `us_states` VALUES ('10', 'Florida');
17.INSERT INTO `us_states` VALUES ('11', 'Georgia');
18.INSERT INTO `us_states` VALUES ('12', 'Hawaii');
19.INSERT INTO `us_states` VALUES ('13', 'Idaho');
20.INSERT INTO `us_states` VALUES ('14', 'Illinois');
21.INSERT INTO `us_states` VALUES ('15', 'Indiana');
22.INSERT INTO `us_states` VALUES ('16', 'Iowa');
23.INSERT INTO `us_states` VALUES ('17', 'Kansas');
24.INSERT INTO `us_states` VALUES ('18', 'Kentucky');
25.INSERT INTO `us_states` VALUES ('19', 'Louisiana');
26.INSERT INTO `us_states` VALUES ('20', 'Maine');
27.INSERT INTO `us_states` VALUES ('21', 'Maryland');
28.INSERT INTO `us_states` VALUES ('22', 'Massachusetts');
29.INSERT INTO `us_states` VALUES ('23', 'Michigan');
30.INSERT INTO `us_states` VALUES ('24', 'Minnesota');
31.INSERT INTO `us_states` VALUES ('25', 'Mississippi');
32.INSERT INTO `us_states` VALUES ('26', 'Missouri');
33.INSERT INTO `us_states` VALUES ('27', 'Montana');
34.INSERT INTO `us_states` VALUES ('28', 'Nebraska');
35.INSERT INTO `us_states` VALUES ('29', 'Nevada');
36.INSERT INTO `us_states` VALUES ('30', 'New Hampshire');
37.INSERT INTO `us_states` VALUES ('31', 'New Jersey');
38.INSERT INTO `us_states` VALUES ('32', 'New Mexico');
39.INSERT INTO `us_states` VALUES ('33', 'New York');
40.INSERT INTO `us_states` VALUES ('34', 'North Carolina');
41.INSERT INTO `us_states` VALUES ('35', 'North Dakota');
42.INSERT INTO `us_states` VALUES ('36', 'Ohio');
43.INSERT INTO `us_states` VALUES ('37', 'Oklahoma');
44.INSERT INTO `us_states` VALUES ('38', 'Oregon');
45.INSERT INTO `us_states` VALUES ('39', 'Pennsylvania');
46.INSERT INTO `us_states` VALUES ('40', 'Rhode Island');
47.INSERT INTO `us_states` VALUES ('41', 'South Carolina');
48.INSERT INTO `us_states` VALUES ('42', 'South Dakota');
49.INSERT INTO `us_states` VALUES ('43', 'Tennessee');
50.INSERT INTO `us_states` VALUES ('44', 'Texas');
51.INSERT INTO `us_states` VALUES ('45', 'Utah');
52.INSERT INTO `us_states` VALUES ('46', 'Vermont');
53.INSERT INTO `us_states` VALUES ('47', 'Virginia');
54.INSERT INTO `us_states` VALUES ('48', 'Washington');
55.INSERT INTO `us_states` VALUES ('49', 'West Virginia');
56.INSERT INTO `us_states` VALUES ('50', 'Wisconsin');
57.INSERT INTO `us_states` VALUES ('51', 'Wyoming');


Performing the Search

Now that we've gotten a few things setup, lets work on the beef of the script. In our search.php file what we'll need to do is take a string (sent via post), see if there are any matches in the database, if so, return them in an unordered list. The PHP code is below and I've commented it so you know whats going on where.

01.
02.    //  connect to the database
03.    mysql_connect("localhost", "username", "password") or die(mysql_error());
04.    mysql_select_db("my_database") or die(mysql_error());
05. 
06.    if ($_SERVER["REQUEST_METHOD"] == "POST") {
07.        //  get our post variable, if its not set, exit
08.        if (isset($_POST["q"])) {
09.            $q = $_POST["q"];
10.        } else {
11.            exit;
12.        }
13. 
14.        $threshold = 1; //  minimum length of the string
15. 
16.        //  make sure the length of the string isn't below the threshold
17.        if (strlen($q) >= $threshold) {
18.            $max = 5;   //  max number of results to show
19.            $found = 0; //  placeholder so we know if we've found any matches or not
20. 
21.            //  shows results that start with the string first
22.            $sql = "SELECT * FROM us_states WHERE state LIKE '".mysql_real_escape_string($q)."%' ORDER BY state ASC LIMIT ".$max;
23.            $query = mysql_query($sql) or die(mysql_error());
24.            $rows = mysql_num_rows($query);
25. 
26.            //  did we find any matches?
27.            if ($rows > 0) {
28.                $found = 1; //  sure did!
29. 
30.                //  start the
    and loop through the matches
31.                echo "
    ";
32.                while ($row = mysql_fetch_array($query)) {
33.                    echo "
  • .$row["state"]."\">".str_ireplace($q, "".$q."

  • ", $row["state"])."";
    34.                }
    35.            }
    36. 
    37.            //  shows results that contains the string anywhere except the beginning if we haven't already found the max to display
    38.            if ($rows < $max) {
    39.                $sql = "SELECT * FROM us_states WHERE state LIKE '%".mysql_real_escape_string($q)."%' AND state NOT LIKE '".mysql_real_escape_string($q)."%' ORDER BY state ASC LIMIT ".($max - $rows);
    40.                $query = mysql_query($sql) or die(mysql_error());
    41.                $rows = mysql_num_rows($query);
    42. 
    43.                //  did we find any matches?
    44.                if ($rows > 0) {
    45.                    if ($found == 0) {  //  have we already found matches before? if not, start the
      46.                        $found = 1;
      47.                        echo "
        ";
      48.                    }
      49. 
      50.                    //  loop through the matches
      51.                    while ($row = mysql_fetch_array($query)) {
      52.                        echo "
    • .$row["state"]."\">".str_ireplace($q, "".$q."

    • ", $row["state"])."";
      53.                    }
      54.                }
      55.            }
      56. 
      57.            //  if we found any matches, close our
        58.            if ($found == 1) {
        59.                echo "";
        60.            }
        61.        }
        62.    }
        63.?>

        If you read through the comments in the script, its pretty direct on whats going on. We make sure that our string is at least 1 character long (since we're only searching states), find results that start with the string first and if we didn't already find our max limit then we'll find results that have the string anywhere but the beginning (as to not repeat results). Its all put into a simple unordered list.

        The jQuery/Javascript

        We're just about done! Now we just need to make it so that each time the value of the textbox changes, send an AJAX request to our PHP file to get the new set of results.

        001.var current = 0;    //  the result that is currently highlighted
        002.var threshold = 1;  //  minimum length of the string
        003.var max = 5;    //  maximum results we're displaying
        004.var searchFor = ""; //  placeholder for what we typed in the search box
        005. 
        006.function doSearch(e) {
        007.    var q = $("#q").val();
        008. 
        009.    if (q.length >= threshold) { //  make sure we're above the threshold
        010.        whichKey(e, q);
        011. 
        012.        //  when we're pressing up and down going through the results, 0 means we're back at where we started and no results are highlighted so lets reset the value of the textbox back to what we actually typed in
        013.        if (current == 0) {
        014.            $("#q").val(searchFor);
        015.        }
        016. 
        017.        //  perform the AJAX request to our PHP file to pull the results
        018.        $.ajax({
        019.            type: "POST",
        020.            data: "q="+escape(searchFor),
        021.            url : "search.php",
        022.            success : function (data) {
        023.                //  did we get anything back?
        024.                if (data != "") {
        025.                    $("#matches").show();   //  show the matches div
        026.                    $("#matches").html(data);   //  set the contents of the matches div to the response we got (unordered list)
        027. 
        028.                    //  if we've pressed the up or down keys, highlight the proper div
        029.                    if (current != 0) {
        030.                        if (current == 1) {
        031.                            //  set the class for the first list item
        032.                            var highlight = "#matches ul li:first-child";
        033.                        } else {
        034.                            //  set the class for the [current] list item
        035.                            var highlight = "#matches ul li:first-child";
        036.                            for (i = 1; i < current; i++) {
        037.                                highlight += "+li";
        038.                            }
        039.                        }
        040. 
        041.                        //  highlight the list item
        042.                        $(highlight).addClass("match-highlight");
        043.                        //  set the textbox value to the title attribute of the highlighted list item
        044.                        $("#q").val($(highlight).attr("title"));
        045.                    }
        046.                    //  when we click on a list item, highlight it and set the textbox value
        047.                    $("#matches ul li").click(function() {
        048.                        $("#q").val($(this).attr("title"));
        049.                    });
        050.                    //  when we hover over a list item, highlight it and remove the highlight when we mouse out
        051.                    $("#matches ul li").hover(function() {
        052.                        $(this).addClass("match-hover");
        053.                    }, function() {
        054.                        $(this).removeClass("match-hover");
        055.                    });
        056.                } else {
        057.                    //  we didn't get anything back from our AJAX request so hide the matches div
        058.                    $("#matches").hide();
        059.                }
        060.            }
        061.        });
        062.    } else {
        063.        //  string was too short
        064.        searchFor = "";
        065.        $("#matches").hide();
        066.    }
        067.}
        068. 
        069.//  function to determine keycodes for keys that are pressed
        070.function whichKey(event, q) {
        071.    if (event.keyCode == 38) {  //  up
        072.        if (current == 0) {
        073.            current = max;
        074.        } else {
        075.            current = (current - 1);
        076.        }
        077.    } else if (event.keyCode == 40) {   //  down
        078.        if (current == max) {
        079.            current = 0;
        080.        } else {
        081.            current = (current + 1);
        082.        }
        083.    } else if (event.keyCode == 8) {    //  backspace
        084.        current = 0;
        085.        searchFor = $("#q").val();
        086.    } else if (event.keyCode == 46) {   //  delete
        087.        current = 0;
        088.        searchFor = $("#q").val();
        089.    } else {
        090.        searchFor = q;
        091.    }
        092.}
        093. 
        094.//  bind the keyup and click actions respectively
        095.$(document).ready(function() {
        096.    $("#q").keyup(doSearch);
        097.    $(document).click(function() {
        098.        $("#matches").hide();
        099.    });
        100.    $("#q").click(doSearch);
        101.});

        Again, I've commented all the code so that you can see whats going on where. Pretty much, each time that a key is pressed we send an AJAX request to get the results of what is in the textbox. There's also some more added functionality for when you press the up and down arrow keys. By doing this, it will go through the results and highlight each one (and set the textbox value to that result) until it gets back to the textbox where it will set the value back to what we typed in.

        Conclusion
        That's it! A simple jQuery autocomplete script. You'll want to change a few things to fit your needs and configuration of your server. Using this will make it easier and faster for your visitors to find what they are looking for.

        Download Zip
        View Demo
        View more great tutorials!

        Post a Comment

        0 Comments