Flag This Hub

Ajax AutoSuggest AutoComplete in Php

By


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

Amir 2 years ago

Great, it was very helpful

shilpi 2 years ago

Hi, i tried this but when i integrated it into worpdress plugin, ajaxObj.responseXML.documentElement gives null value always.

Please help me for this.

PakCoders 2 years ago

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.

Nicholas 2 years ago

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.

PakCoders 2 years ago

Can you post the autosuggest.php code here, I am not having this problem in this script.

ssorj 2 years ago

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?

ssorj 2 years ago

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?

ssorj 2 years ago

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.

PakCoders 2 years ago

No Problem.

psychicdog.net 2 years ago

thanks PakCoders - I agree great script I like the way it connect to php/mysql database rather than flat file.

PakCoders 2 years ago

Thank you

vj 2 years ago

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....

PakCoders 2 years ago

Hello VJ!

Do you mean to say how to get the value of the text field (the input text box)?

vj 2 years ago

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.

VJ 2 years ago

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

PakCoders 2 years ago

The value selected through ajax is stored in $_POST['input'] so you can get it from it.

VJ 2 years ago

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?

Derere 2 years ago

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.

PakCoders 2 years ago

Hi Derere!

Well try changing this line,

$input = trim($_POST['input']);

to

$input = htmlspecialchars(trim($_POST['input']));

Hope it works.

jim 2 years ago

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.

jim 2 years ago

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 ?

PakCoders 2 years ago

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.

PakCoders 2 years ago

There is a bug in the above autosuggest.js file.

Please use this autosuggest.js file instead:

http://rapidshare.com/files/362447816/autosuggest.

prot 2 years ago

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

PakCoders 2 years ago

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.

ravi bose 2 years ago

very good

thanks

PaulB 2 years ago

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.

PaulB 2 years ago

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.

PaulB 2 years ago

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.

testing 23 months ago

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 ?

Af 21 months ago

I used ur script but its of no help nd I even cud not figure out whats going on wrong .kindly help.

Japonski 20 months ago

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.

Caldera 19 months ago

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 :)

PakCoders 19 months ago

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.

ALvin Bangayan 16 months ago

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.

ALvin Bangayan 16 months ago

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

abhijeet 15 months ago

well it works only fr single entry in each columns what about a sentence

Hk 10 months ago

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

Nick 9 months ago

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.

Azeem 4 months ago

This post is really helpful. This autosuggest script is very simple and easy to integrate, thank You.

Md Minhaj 4 months ago

This Post is really Very helpfull and easy.

Thank You.

Sky 4 months ago

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.

uzor ohuegbe 3 months ago

i searched for many hours for an ajax autosuggest script, and urs has been the most useful.tanx a lot

uzor(from nigeria)

Aitrich Technologies 2 months ago

Super really helpfull..... exellenttttt.... really wonderfull workkkkkk

tom 2 months ago

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.

Regan Rajan 5 weeks ago

It works wonderful!

The design also very neat and simple. Exactly what I was looking for. Thanks you for sharing!

jeff 3 weeks ago

not working... isnt is supposed to be a form?

Eric 3 weeks ago

This script works great!!! But have a problem with clear the text filed when empty.

Thank you.

rainny 2 weeks ago

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.

Submit a Comment
Members and Guests

Sign in or sign up and post using a hubpages account.



    Like this Hub?
    Please wait working