Loading
Showing posts with label ajax code samples. Show all posts
Showing posts with label ajax code samples. Show all posts

Sunday, February 10, 2008

Auto-Completing Properly

Now that you have a means to connect to a database, you can start replacing and upgrading some of the placeholder code you used in the previous chapter’s examples. Rather than using static arrays to house information on names within the database, you can get an up-to-date listing of all names in the database on the fly by merely including your database connection script (containing the PHP code to connect to the database) and performing a query to scour the user table for all name instances. Two files are in need of some dire code replacement, autocomp.php and validator.php.

<?php
//autocomp.php
//Add in our database connector.
require_once ("dbconnector.php");
//And open a database connection.
$db = opendatabase();
$foundarr = array ();
//Set up the dynamic query string.
$querystr = "SELECT name FROM user WHERE name LIKE ➥
LOWER('%" . mysql_real_escape_string ($_GET['sstring']) . "%') ORDER BY name ASC";
if ($userquery = mysql_query ($querystr)){
while ($userdata = mysql_fetch_array ($userquery)){
if (!get_magic_quotes_gpc()){
$foundarr[] = stripslashes ($userdata['name']);
} else {
$foundarr[] = $userdata['name'];
}
}
} else {
echo mysql_error();
}
//If we have any matches, then we can go through and display them.
if (count ($foundarr) > 0){
?>
<div style="background: #CCCCCC; border-style: solid; border-width: 1px;➥
border-color: #000000;">
<?php
for ($i = 0; $i < count ($foundarr); $i++){
?><div style="padding: 4px; height: 14px;" onmouseover=➥
"this.style.background = '#EEEEEE'" onmouseout=➥
"this.style.background = '#CCCCCC'" onclick=➥
"setvalue ('<?php echo $foundarr[$i]; ?>')"><?php echo $foundarr[$i]; ?></div><?php
}
?>
</div>
<?php
}
?>

Notice how the preceding code affects your autocomp.php file. Now, rather than referencing an array to check for name matches, the system actually checks within the database for any matches, using the LIKE operator. This works far better by allowing the system to check dynamically for any new names that may be in the database.
Similarly, your validator.php file now does much the same validation checking as your autocomp.php file. This time, however, rather than checking for an exact match against an array of names, the system now checks for an actual database match for the name in question. Again, this is far superior, as you now have a means to properly store information on saved names. Note that the code flow is largely the same, but now it is done properly via a real data storage model, and the result is a nicely validated form

<?php
//validator.php
//Add in our database connector.
require_once ("dbconnector.php");
//And open a database connection.
$db = opendatabase();
//Set up the dynamic query string.
$querystr = "SELECT userid FROM user WHERE name = ➥
LOWER('" . mysql_real_escape_string ( $_GET['sstring']) . "')";
if ($userquery = mysql_query ($querystr)){
if (mysql_num_rows ($userquery) == 0){
//Then return with an error.
?><span style="color: #FF0000;">Name not found...</span>>?php
} else {
//At this point we would go to the processing script.
?><span style="color: #FF0000;">Form would now submit...</span><?php
}
} else {
echo mysql_error();
}
?>




Monday, January 14, 2008

Google live search - Connecting to Google Suggest - shows the whole code to help you

<html>
<head>
<title>Google live search</title>
<style>
#targetDiv {
background-color: #FFEEAA;
width: 30%;
}
</style>
<script language = “javascript”>
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest) {
XMLHttpRequestObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
XMLHttpRequestObject = new ActiveXObject(“Microsoft.XMLHttp”);
}
function getData(dataSource)
{
if(XMLHttpRequestObject) {
XMLHttpRequestObject.open(“GET”, dataSource);
XMLHttpRequestObject.onreadystatechange = function()
{
if (XMLHttpRequestObject.readyState == 4 &&
XMLHttpRequestObject.status == 200) {
eval(XMLHttpRequestObject.responseText);
}
}
XMLHttpRequestObject.send(null);
}
}
function getSuggest(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
input = (keyEvent.target) ? keyEvent.target :
keyEvent.srcElement;
if (keyEvent.type == “keyup”) {
if (input.value) {
getData(“google.php?qu=” +
input.value);
}
else {
var targetDiv = document.getElementById(“targetDiv”);
targetDiv.innerHTML = “<div></div>”;
}
}
}
function sendRPCDone(unusedVariable, searchTerm, arrayTerm,
arrayResults, unusedArray)
{
var data = “<table>”;
var loopIndex;
if (arrayResults.length != 0) {
for (var loopIndex = 0; loopIndex < arrayResults.length;
loopIndex++) {
data += “<tr><td>” +
“<a href=’http://www.google.com/search?q=” +
arrayTerm[loopIndex] + “‘>” + arrayTerm[loopIndex] +
‘</a></td><td>’ + arrayResults[loopIndex] + “</td></tr>”;
}
}
data += “</table>”;
var targetDiv = document.getElementById(“targetDiv”);
targetDiv.innerHTML = data;
}
</script>
</head>
<body>
<H1>Google live search</H1>
Search for <input id = “textField” type = “text” name = “textField” onkeyup = “getSuggest(event)”>
<div id = “targetDiv”><div></div></div>
</body>
</html>

Check out the PHP script, google.php, which is the script that actually does the communicating with Google. This one takes a little PHP of the kind that appears in detail in Chapter 10. This script is passed the term the user has entered into the text field, and it should get some suggestions from Google, which it does like this with the PHP fopen (file open) statement:

<?php
$handle = fopen(“http://www.google.com/complete/search?hl=en&js=true&qu=” .
$_GET[“qu”], “r”);

.
.
.


This gives you a PHP file handle, which you can use in PHP to read from the Google URL. Here’s how that looks in PHP, where a while loop keeps reading data from Google as long as the end of the data marker isn’t seen. You can check if you’ve reached the end of the data with the feof function, which returns true if the end of the data has been reached:

<?php
$handle = fopen(“http://www.google.com/complete/search?hl=en&js=true&qu=” .
$_GET[“qu”], “r”);
while (!feof($handle)){
.
.
.
}
?>

To get the data from Google, you can use the fgets (file get string) function, and echo the fetched text, which sends that text back to the browser. Here’s how you can make that happen:

<?php
$handle = fopen(“http://www.google.com/complete/search?hl=en&js=true&qu=” .
$_GET[“qu”], “r”);
while (!feof($handle)){
$text = fgets($handle);
echo $text;

}
fclose($handle);
?>

And that’s all you need. Now this script, google.php, will read the suggestion data from Google and send it back to your script.

Everything works as expected.

Showing Google’s response

When you have the search data, you need to show the response from Google, which will be JavaScript. The response is executed with the JavaScript eval function:

function getData(dataSource)
{
if(XMLHttpRequestObject) {
XMLHttpRequestObject.open(“GET”, dataSource);
XMLHttpRequestObject.onreadystatechange = function()
{
if (XMLHttpRequestObject.readyState == 4 &&
XMLHttpRequestObject.status == 200) {
eval(XMLHttpRequestObject.responseText);
}
}
XMLHttpRequestObject.send(null);
}
}

This calls the sendRPCDone function. All that’s left in google.html is to set up that function in this way:

function sendRPCDone(unusedVariable, searchTerm, arrayTerm,
arrayResults, unusedArray)
{
.
.
.
}

You fill the <div> element, targetDiv, with data you get from Google in the sendRPCDone function, using an HTML table to align the columns. Here’s how to create the table and start looping over the suggestions Google returned:

function sendRPCDone(unusedVariable, searchTerm, arrayTerm,
arrayResults, unusedArray)
{
var data = “<table>”;
var loopIndex;
if (arrayResults.length != 0) {
for (var loopIndex = 0; loopIndex < arrayResults.length;
loopIndex++) {
.
.
.
}
}
data += “</table>”;
var targetDiv = document.getElementById(“targetDiv”);
targetDiv.innerHTML = data;

}

Next, you give each suggestion its own hyperlink which — when clicked — searches Google, redirecting the browser to the Google Web site like this:

function sendRPCDone(unusedVariable, searchTerm, arrayTerm,
arrayResults, unusedArray)
{
var data = “<table>”;
var loopIndex;
if (arrayResults.length != 0) {
for (var loopIndex = 0; loopIndex < arrayResults.length;
loopIndex++) {
data += “<tr><td>” +
“<a href=’http://www.google.com/search?q=” +
arrayTerm[loopIndex] + “‘>” + arrayTerm[loopIndex] +
‘</a></td><td>’ + arrayResults[loopIndex] + “</td></tr>”;

}
}
data += “</table>”;
var targetDiv = document.getElementById(“targetDiv”);
targetDiv.innerHTML = data;
}

The last touch: the targetDiv <div> element is given a light yellow background
in the <style> element in the <head> section

<html>
<head>
<title>Google live search</title>
<style>
#targetDiv {
background-color: #FFEEAA;
width: 30%;
}
</style>
.
.
.

And that’s all it takes.
Because this Google example is a complicated one,

Connecting to Google Suggest

To connect to Google Suggest, you call a function named getData which does exactly that — gets the live search data, like this:

function getSuggest(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
input = (keyEvent.target) ? keyEvent.target :
keyEvent.srcElement;
if (keyEvent.type == “keyup”) {
if (input.value) {
getData(“google.php?qu=” +input.value);

}
.
.
.
}
}

If no text exists in the text field, the user deleted that text, so you can clear the suggestions (which appear in a <div> element named targetDiv) as follows:

function getSuggest(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
input = (keyEvent.target) ? keyEvent.target :
keyEvent.srcElement;
if (keyEvent.type == “keyup”) {
if (input.value) {
getData(“google.php?qu=” +
input.value);
}
else {
var targetDiv = document.getElementById(“targetDiv”);
targetDiv.innerHTML = “<div></div>”;
}

}
}

How does the getData function work? This function calls the PHP script that actually interacts with Google Select, and passes on the current search term on to that script. This function is called with the relative URL to call, which is this (where term holds the search term):

google.php?qu=” + term;

That URL is opened in the getData function this way:

<script language = “javascript”>
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest) {
XMLHttpRequestObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
XMLHttpRequestObject = new ActiveXObject(“Microsoft.XMLHttp”);
}
function getData(dataSource)
{
if(XMLHttpRequestObject) {
XMLHttpRequestObject.open(“GET”, dataSource);
.
.
.
}
}

Detecting keystrokes

The getSuggest function is supposed to be passed an event object that it will refer to as keyEvent, which holds data about the key event that just took place:

function getSuggest(keyEvent)
{
.
.
.
}

However, this method of passing the event object doesn’t work in the Internet Explorer, which means getSuggest won’t be passed anything in that browser.You have to use the window.event object instead in the Internet Explorer.So the first line of getSuggest is a typical line of JavaScript that uses the JavaScript conditional operator to make sure you have an event object to work with. Here’s an example that
shows how to use this operator:

var temperature = condition ? 72 : 55;

If condition is true, the temperature variable will be assigned the value 72; if condition is false, temperature will be assigned 55. In the getSuggest function, you can use the conditional operator to test whether keyEvent has a non-zero value. If it doesn’t, you should use window.event instead:

function getSuggest(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
.
.
.
}

You can also determine which control the user was typing into, but that depends on which browser the user has. In the Internet Explorer, you use the srcElement property of the keyEvent object, but otherwise, you use the target property to get the control the user was typing into:

function getSuggest(keyEvent)
{
function getSuggest(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
input = (keyEvent.target) ? keyEvent.target :
keyEvent.srcElement; .
.
.
}

Excellent. You have all the data you need about the key event. Now you can
use the following code to check whether the event was a key up event:

function getSuggest(keyEvent)
{
keyEvent = (keyEvent) ? keyEvent: window.event;
input = (keyEvent.target) ? keyEvent.target :
keyEvent.srcElement;
if (keyEvent.type == “keyup”) {
.
.
.
}
}

If the event was a key up event, it’s time to read the struck key. If there is
some text in the text field, it’s time to connect to Google Suggest.

Handling the data Google sends you

What does the code look like in google.html? The text field where the user enters text is tied to a function named getSuggest by using the onkeyup event. As a result, getSuggest will be called every time the user types and releases a key. (Note that the event object is passed to getSuggest by this code, because that object holds information about which key was pressed, and also note the <div> element where the suggestions will appear,targetDiv.)

Here’s what the code looks like:

<body>
<H1>Google live search</H1>
Search for <input id = “textField” type = “text” name = “textField” onkeyup = “getSuggest(event)”>

<div id = “targetDiv”><div></div></div>
</body>

Connecting to Google for a Live Search

How can you connect to Google Suggest yourself? Say that you placed the search term you wanted to search for in a variable named term. You could then open this URL:

http://www.google.com/complete/search?hl=en&js=true&qu=” + term;

You get back a line of JavaScript from Google Suggest that calls a function named sendRPCDone. Here are the parameters passed to that function:

sendRPCDone(unusedVariable, searchTerm, arrayTerm, arrayResults, unusedArray)

What does the actual JavaScript you get back from Google Suggest look like?

If you’re searching for “ajax”, this is the JavaScript you’ll get back from Google as of this writing:

sendRPCDone(frameElement, “ajax”, new Array(“ajax”, “ajax amsterdam”,
“ajax fc”, “ajax ontario”, “ajax grips”, “ajax football club”, “ajax public
library”, “ajax football”, “ajax soccer”, “ajax pickering transit”), new
Array(“3,840,000 results”, “502,000 results”, “710,000 results”, “275,000
results”, “8,860 results”, “573,000 results”, “40,500 results”, “454,000
results”, “437,000 results”, “10,700 results”), new Array(“”));


You can handle this by putting together a function named sendRPCDone that will display this data