Ajax AutoSuggest AutoComplete in Php
By PakCoders
Ajax AutoSuggest using php is really a simple task. I will first outlines the main steps involved in the process and then follow with the code:
- Whenever a keyup event on a textbox occur, a function in javascript is called which uses ajax to send the input in the textbox to the server
- The server receives the input and check for any matches in the database
- The matched result is sent back to the client side javascipt code, ajax, and then the result is shown in an absolute positioned div just under the input box.
This is how it will look like:
Now we move how will we make the script. It consists of following files along with their description in brief. These are the client side file:
- script.html - This is the main file in which there is input box and the result to be shown as shown in the image above
- ajax.js - This file holds the ajax code used to send and receive ajax requests to/from the server.
- tools.js - It contains some useful functions used in the script like trim(string) which is used to trim/remove leading and lagging spaces from a string.
- autosuggest.js - This contains the functions used to carry out the operations of ajax autosuggest. It contains code to get the input from the input box, send request via ajax and show the result received in the absolute positioned div.
Now on the server side, you can use any scripting language you want, but I have used php which is most widely used. These are the server side file:
- autosuggest.php - This files receices the request sent by the ajax from the autosuggest.js file. It searches the database for the possible matche(s) of the input and then send back the result to the autosuggest.js file.
- dbconfig.php - It holds the MySQL database settings, since this is the type of the database I have used.
- headers.php - Headers are sent to the browser to prevent it from caching the results and also the necessary header are sent to make the output in xml format.
You can also download all the files as zip from here:
http://rapidshare.com/files/184321469/ajax_autosuggest_using_php.zip
Create a new file ajax.js and copy the following code into it:
function getAjaxObject()
{
// initially set the object to false
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest)
{
// check for Safari, Mozilla, Opera...
XMLHttpRequestObject = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
// check for Internet Explorer
XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!XMLHttpRequestObject)
{
alert("Your browser does not support Ajax.");
// return false in case of failure
return false;
}
// return the object in case of success
return XMLHttpRequestObject;
}
function sendRequest(xmlHTTPObject, url, parameters, handleResponse, id)
{
if(xmlHTTPObject)
{
// continue if the object is idle
if (xmlHTTPObject.readyState == 4 || xmlHTTPObject.readyState == 0)
{
// open connection and send "GET" request to server
xmlHTTPObject.open("POST", url, true);
// send the appropriate headers
xmlHTTPObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// set the function to be called on a change in ajaxObj state
xmlHTTPObject.onreadystatechange = function () {handleResponse(id)};
// set additional parameters (to be sent to server) to null
xmlHTTPObject.send(parameters);
}
}
}
Then create a file tools.js and copy the following in it:
// get element by ID
function getElemId(id)
{
if (document && document.getElementById(id))
{
return document.getElementById(id);
}
else
{
alert("Invalid ID: " + id);
return false;
}
}
// function that will remove all spaces from a string used primarily to check
function trim(s)
{
return s.replace(/(^\s+)|(\s+$)/g, "");
}
Now create a new file autosuggest.js and put the following code in it:
var ajaxObj = getAjaxObject();
var targetID = new Array() ;
var searchID = new Array() ;
var inputID = new Array() ;
function autoSuggest(id, targetid, searchid, inputid, e)
{
var keyCode = getKeyCode(e, 'keyup');
if (keyCode == 40 || keyCode == 38)
{
return false;
}
autoSugPointer[id] = 0;
targetID[id] = targetid;
searchID[id] = searchid;
inputID[id] = inputid;
countSuggestions[id] = 0;
var searchInput = getElemId(id).value;
var url = "autosuggest.php";
var params = "input=" + searchInput;
if (trim(searchInput) !== "")
{
sendRequest(ajaxObj, url, params, handleSuggestResponse, id);
}
else
{
hideSuggestions();
}
}
function handleSuggestResponse(id)
{
if (ajaxObj.readyState == 4)
{
if (ajaxObj.status == 200)
{
try
{
var XMLResponse = ajaxObj.responseXML.documentElement;
// work with the xml response
var keywordsTag = XMLResponse.getElementsByTagName('keywords');
var suggestions = new Array();
for (var i = 0; i < keywordsTag.length; i++)
{
var keywords = keywordsTag.item(i).firstChild.data.toString();
suggestions.push(keywords);
}
showSuggestions(suggestions, id);
}
catch(e)
{
hideSuggestions(id);
if (trim(ajaxObj.responseText) !== "")
alert(ajaxObj.responseText);
}
}
}
}
var countSuggestions = new Array();
function showSuggestions(suggestions, id)
{
var listWrapID = getElemId(targetID[id]);
listWrapID.style.visibility = "visible";
var listID = getElemId(searchID[id]);
listID.innerHTML = "";
for(var i = 0; i < suggestions.length; i++)
{
listID.innerHTML += "<li><a id='"+id + "-" +(i+1)+"' href=\"javascript:void(0);\" onclick=\"insertKeyword(this.innerHTML, '"+id+"');\">" + suggestions[i] + "</a></li>";
}
countSuggestions[id] = i;
}
var autoSugPointer = new Array();
function keyBoardNav(e, id)
{
var keyCode = getKeyCode(e, 'keydown');
if (keyCode == 40)
{
if (autoSugPointer[id] >= 0 && autoSugPointer[id] < countSuggestions[id])
{
if (autoSugPointer[id] != 0 && autoSugPointer[id] != countSuggestions[id])
{
revertAutoSuggestKeyNav(autoSugPointer[id], id);
}
autoSugPointer[id] ++;
changeAutoSuggestKeyNav(autoSugPointer[id], id);
if (autoSugPointer[id] > 6)
{
getElemId(searchID[id]).scrollTop = 30;
}
}
}
else if (keyCode == 38)
{
if (autoSugPointer[id] > 1)
{
revertAutoSuggestKeyNav(autoSugPointer[id], id);
autoSugPointer[id] --;
changeAutoSuggestKeyNav(autoSugPointer[id], id);
if (autoSugPointer[id] <= 2)
{
getElemId(searchID[id]).scrollTop = 0;
}
}
}
else if (keyCode == 13 && autoSugPointer[id])
{
var str = getElemId(id + "-" + autoSugPointer[id]).innerHTML;
insertKeyword(str, id);
}
}
function changeAutoSuggestKeyNav(id, ID)
{
getElemId(ID + "-" + id).style.backgroundColor = "#555";
getElemId(ID + "-" + id).style.color = "#FFF";
}
function revertAutoSuggestKeyNav(id, ID)
{
getElemId(ID + "-" + id).style.backgroundColor = "#F9F9F9";
getElemId(ID + "-" + id).style.color = "#006";
}
function hideSuggestions(id)
{
try
{
var listWrapID = getElemId(targetID[id]);
listWrapID.style.visibility = "hidden";
}catch(e){}
}
function insertKeyword(str, id)
{
hideSuggestions(id);
getElemId(inputID[id]).value = str;
getElemId(inputID[id]).focus();
}
Now let us move to the design, so copy these lines of code into the head section of the page in which you want the autosuggest.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax AutoSuggest Script</title>
<script type="text/javascript" language="javascript" src="ajax.js"></script>
<script type="text/javascript" language="javascript" src="tools.js"></script>
<script type="text/javascript" language="javascript" src="autosuggest.js"></script>
<script type="text/javascript" language="javascript">
</script>
<style type="text/css">
<!--
.searchList {
margin: 0px;
padding: 0px;
list-style-type: none;
position: absolute;
width: 206px;
height: 160px;
overflow-y:auto;
overflow:-moz-auto-vertical
}
.wrapSearch {
}
#input {
width: 220px;
padding: 2px;
font-family: Tahoma, Geneva, sans-serif;
font-size: 11px;
}
html, body {
font-family: Tahoma, Geneva, sans-serif;
font-size: 11px;
}
.searchList li {
display: block;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #D6D6D6;
width: 98%;
}
.searchList li a{
display: block;
color: #006;
text-decoration: none;
background-color: #F9F9F9;
padding-top: 5px;
padding-right: 5px;
padding-bottom: 5px;
padding-left: 8px;
}
.searchList li a:hover{
color: #FFF;
background-color: #555;
}
.listWrap {
visibility: hidden;
}
-->
</style>
</head>
<body>
<div class="wrapSearch">
<div>
<input name="input" type="text" id="input1" size="30" maxlength="1000" onkeyup="autoSuggest(this.id, 'listWrap1', 'searchList1', 'input1', event);" onkeydown="keyBoardNav(event, this.id);" /> <input type="submit" name="search" id="search1" value="Search" />
</div>
<div class="listWrap" id="listWrap1">
<ul class="searchList" id="searchList1">
</ul>
</div>
</div>
<div class="wrapSearch" style="margin-top:250px">
<div>
<input name="input" type="text" id="input2" size="30" maxlength="1000" onkeyup="autoSuggest(this.id, 'listWrap2', 'searchList2', 'input2', event);" onkeydown="keyBoardNav(event, this.id);" /> <input type="submit" name="search" id="search2" value="Search" />
</div>
<div class="listWrap" id="listWrap2">
<ul class="searchList" id="searchList2">
</ul>
</div>
</div>
</body>
</html>
The request from the ajax will be sent to this file, autosuggest.php, so create a new file autosuggest.php and copy these lines of code into it:
<?php
$limit = 10;
if (!isset($_POST['input']))
exit;
$input = trim($_POST['input']);
require_once "dbconfig.php";
mysql_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD) or die("Could not connect to host");
mysql_select_db(DB_DATABASE) or die("Could not connect to database");
// Select the data from the mysql
// change below according to your own needs.
$sql = "SELECT `keywords` FROM `data` WHERE `keywords` LIKE '$input%' LIMIT $limit";
$result = mysql_query($sql);
if (!$result || !mysql_num_rows($result))
exit;
include_once "headers.php"
echo "<response>"
while ($row = mysql_fetch_array($result))
{
$keywords = $row['keywords'];
echo "<keywords>". $keywords ."</keywords>";
}
echo "</response>";
?>
The autosuggest.php file fetches data from a table named ‘data’ and from the field ‘keywords’, you may need to change it to your own requirements in order to run the script. Otherwise you may get a syntax error in case the query does not execute.
Create a new file dbconfig.php which will hold the mysql connection settings:
<?php
// database connection settings
define("DB_HOSTNAME", "your_mysql_hostname");
define("DB_USERNAME", "your_mysql_host_username");
define("DB_PASSWORD", "your_mysql_username_password");
define("DB_DATABASE", "your_mysql_database");
?>
Change the mysql connection settings to your own.
Finally create a file headers.php which will hold the headers to prevent the browser from caching the results and to send xml headers.
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header("Content-type: text/xml");
?>
For your convenience, I have put all the files in a zip file for you to download free:
http://rapidshare.com/files/231051277/ajax-auto-suggest.zip
If you need any help, please comment on this post, I will definitely reply to relevant queries, thanks.
Comments
Hi, i tried this but when i integrated it into worpdress plugin, ajaxObj.responseXML.documentElement gives null value always.
Please help me for this.
Hi Shilpi, the error indicates that the XML response from the server is not valid. Please verify if you indeed receiving a response from server in valid XML format.
Secondly, may you give the code here you are having problem, I will be then in a better position to help you.
Thanks.
How do I get rid of the plus signs (+) in all the data that was fetched? Some reason all the spaces were replaced by the plus signs.
Can you post the autosuggest.php code here, I am not having this problem in this script.
I'm getting a javascript alert with this:
I'm sure my db is connecting properly and the browser can make an ajax connection, what can this be?
Oops. The tags were removed when I posted: these are all wrapped in greater than / less than tags...
response keywords /keywords keywords /keywords keywords /keywords /response
What can this be?
Dang. My mistake. I didn't rename the $ row [ ' name ' ] to my column name at the end of autosuggest . php. It works fine now. Sorry to load up your comments. Great script.
No Problem.
thanks PakCoders - I agree great script I like the way it connect to php/mysql database rather than flat file.
Thank you
Gr8 material. I salute u.... Was very helpful for me. But now I am stuck with one issue at hand. How to get the value to the text field's VALUE section? It will be gr8 if you could help me with this. Thanks in advance....
Hello VJ!
Do you mean to say how to get the value of the text field (the input text box)?
Thanks for the quick response.
I mean I have from the database for example id, name coming to autosuggest.php.
$Id = $row['id'];
$keywords = $row['name'];
echo "";
echo "" . $stockId . "";
echo "" . $keywords . "";
echo "";
And I am creating my XML like you can see above. Now if I want to insert to database the value which is selected through this ajax, how to insert the value of the element and show for the users in the list of dropdown the element??? Thank you.
Sorry in the last message for some reason its not showing the tag with the element those missing in the echo are tags which are in order list,id,keywords,/list
The value selected through ajax is stored in $_POST['input'] so you can get it from it.
Sorry may be I didnt make it clear as I should with this issue. So I have two values coming from the database id and name. So I want to show in the suggestion drop down the name and I want to get the id for further database manupulation. How do i do that?
Hello, this script works great, thank you very much. But I have one problem with Polish characters national. After entering the Polish character, then any suggestion letters disappear. Please help.
Hi Derere!
Well try changing this line,
$input = trim($_POST['input']);
to
$input = htmlspecialchars(trim($_POST['input']));
Hope it works.
The result does not disappear if one result is selected with enter key on the keyboard. It still shows the selected result below the textfield.
I got it. There was the tag missing :-)
But i still have a question: If i select a result with the keyboard,then the form is submitted automatically. How could i stop that ?
Hi Jim, I was busy so could not reply you at the first instance. Here is how you can suppress the form from being submitted with the keyboard return key hit.
Step 1:
Modify the code of your form html like below.
<form action="#" method="get" onsubmit="return voidForm();">
Means to add the event onsubmit="return voidForm(); to your form html opening tag.
Step 2:
Replace the autosuggest.js file with the following modified file.
http://rapidshare.com/files/362413624/autosuggest.
Hope it works for you.
There is a bug in the above autosuggest.js file.
Please use this autosuggest.js file instead:
Hi,unfortunately the code doesn't work for me;I can get my query executed,and after rows are fetched,a valid xml is created(i verified this by enabling the submit button and adding )
But the auto-suggest list doesn't show up below the input text-box...I don't know why.Can you help me?
my email is eklypse@live.it
Hi there!
It is hard to guess what may be the problem since it works in my environment but what I can say do is that if you send me a sample of your code, I can look at it and debug the fault. thanks.
very good
thanks
Impressive code! Although I'm not sure my project will require more than one auto-suggest instance, one thing you might want to consider adding (either to the code or instructions, depending on the complexity) is a way one might incorporate this for implementing autosuggests on more than one form element talking to more than one field, and perhaps in more than one table.
I did, however, run into one browser-specific problem. Using Firefox 3.6.3 for PC, when I select a suggestion containing a comma (and all of mine in this field will...), the comma character is changed to a period when inserted into the text box. This does not happen using MSIE.
Please scratch that last report about the comma/period problem. For some reason the character LOOKS like a period in the Firefox text box typeface, but pasting it into another application reveals that it is indeed a comma. My apologies.
Hi this is great but there is one more thing i need it it to do i need to have three instances of this on one page select different fields fro the same table how would i do ths ?
I used ur script but its of no help nd I even cud not figure out whats going on wrong .kindly help.
Thanks!
I am using different kind of autosuggestion script, but that one doesn't work for FF3.6 (a bug?), while other browsers are fine.
How about this one?
BTW. The code is a bit hidden behind sidebar.
Hi, all works well when using against my database of names (i'm using it to search surnames), how can I get it to only show one instance of a surname, for example I have 200+ Smith's but only want it to show one.
Mike :)
Hello all of you!
I had been very busy in my studies and did not have the time to reply to your comments or update the script.
Mike!
You can change the limit from
$limit = 10;
to:
$limit = 1;
It should work for you.
Sir can you add me up in my email...i want to ask questions from you..im having problems and i have no idea but i want to learn.
Sir can you add me up in my email...i want to ask questions from you..im having problems and i have no idea but i want to learn. game.library@yahoo.com
well it works only fr single entry in each columns what about a sentence
It worked for me in linux machine but when I did the same in Windows machine (XAMPP) I am getting an alert instead of getting the results in the page what could it be
The result does not disappear if one result is selected with enter key on the keyboard. It still shows the selected result below the textfield. i tried the htmlspecialchars tag too, but with no success. Also, could u please tell me how should i redirect the user to a different page with an anchor tag when enter key is pressed like u have done while generating the list. Please, help me with both, i need to solve it urgently.
This post is really helpful. This autosuggest script is very simple and easy to integrate, thank You.
This Post is really Very helpfull and easy.
Thank You.
I tried this, in my linux/php 5.2 environment. but it doesn't work at all to populate the entry.
I modified the sql query in autosuggest.php, and the sql query should work fine because I'm able to run it manually in phpmyadmin, and returns result.
I modified dbconfig.php to map to db.
I wonder what is wrong. I'm using Firefox browser 9.01
I tested in IE8, also same issue.
i searched for many hours for an ajax autosuggest script, and urs has been the most useful.tanx a lot
uzor(from nigeria)
Super really helpfull..... exellenttttt.... really wonderfull workkkkkk
the script works perfect however when you search and then clear the text filed the results stay. how can I make the previous search disappear when text filed is empty.
Thank you.
It works wonderful!
The design also very neat and simple. Exactly what I was looking for. Thanks you for sharing!
not working... isnt is supposed to be a form?
This script works great!!! But have a problem with clear the text filed when empty.
Thank you.
Hi, I already change the code in db.config and autosuggest.php. But, it seems like still don't working for me. Could you please suggest the solution for me?
Thanks a lot.
Amir 2 years ago
Great, it was very helpful