Search

While the hype of AJAX may be a bit overblown, it’s still a useful tool and very fun to program with. One of the issues I’ve had with my two previous examples (AJAX username availability checking and A simple AJAX example) is that most AJAX out there today depends on the XmlHttpRequest JavaScript object. It’s certainly available in IE, FireFox, Opera, etc, but in IE, it has to be called as an ActiveX object, whereas in Opera, FireFox, etc, ActiveX won’t fly. This means you have to have a darn good browser detection algorithm, or else you risk a percentage of users losing functionality.

Alternatively, we could do some AJAX without the XmlHttpRequest object. But how? Some guy at PHPit (Google Cache) has figured out a way.

Like Rasmus’s tutorial, this is a pretty straight-forward approach, and you should be running some AJAX in no time. If you want, you can skip right ahead to three demos that I’ve prepared.

As before, there will be three parts: the PHP page that the user visits, the JavaScript file containing the engine, and a PHP page (or pages) that will be called by the engine. First, the user’s PHP page (demo.php):

 	<h3>Demo from PHPit</h3>

 	<p>This demo simply grabs text from another PHP file.  Nothing much to see here, just
 	demonstrating the basic concept.</p>

 	<div id="contentdiv"></div>

 	<input type="button" onclick="ajax_do ('page1.php');" value="Get content" />
 

Notice the empty div tags. As before, we will be using the DOM and the innerHTML element to update the content. The ajax_do function is the engine, and the one parameter it gets is the PHP page to call (along with any parameters in querystring form).

Next, the engine (engine.js):

 // Get base url
 the_url = document.location.href;
 xend = the_url.lastIndexOf("/") + 1;
 var base_url = the_url.substring(0, xend); 

 function ajax_do (the_url)
 {
 	// this first part is pretty darn hacky, but if we need to make multiple calls with the
 	// same 'the_url', then most browsers will only work one time
 	// so we need to make each call unique as possible.
 	// two random querystring names and values should do the trick
 	// if there were no querystrings, we need to start with a '?'
 	if (the_url.indexOf("?") != -1) {
 		the_url += "&";
 	} else {
 		the_url += "?";
 	}
 	the_url += Math.random(0,1000) + "=" + Math.random(0,1000)
               + "&" + Math.random(0,1000) + "=" + Math.random(0,1000);
 	// note that it is possible to get the same 4 random numbers each time,
 	// but a very slim possibility.  That doesn't make the above part any less hacky :P 

 	// Does URL begin with http?
 	if (the_url.substring(0, 4) != 'http') {
 	        the_url = base_url + the_url;
 	}

 	// Create new JS element
 	var jsel = document.createElement('SCRIPT');
 	jsel.type = 'text/javascript';
 	jsel.src = the_url;

 	// Append JS element (therefore executing the 'AJAX' call)
 	document.body.appendChild (jsel);
 }
 

This simply creates a new SCRIPT element on the current document and loads the filename specified as that script. Once this happens, the loaded script will execute.

Finally, the file being called by the engine (page1.php):

 <?php 

 	// nothing dynamic about this, but it's just for demo purposes
 	$html = "<p><b>This content came from our AJAX Engine</b></p>";

 ?>

 div = document.getElementById('contentdiv');
 div.innerHTML = '<?php echo $html; ?>';
 

The code within the php tags can do anything you like–it can look up a username passed through the querystring, whatever. The output from the PHP should be put into the $html string. The bottom two lines of this page should always be the javascript shown, changing only the name of the ID to be updated (contentdiv, in this case).

Once you have engine.js in place, you can make any number of PHP files for it to interact with. I’ve thought of two examples (for more good examples of appropriate AJAX uses, check out Alex Bosworth’s 10 Places You Must Use AJAX): username availability checking (which I did before), and Digg-style voting.

Here’s the code for username availability checking:

 <?php
 	$theusername = $_GET['username'];

 	//error checking on the username

 	// no spaces allowed
 	if(strpos($theusername," ") === true) {
 		$html = "Usernames may not contain a space.";

 	// must be at least 1 character
 	} else if(strlen($theusername) == 0) {
 		$html = "<p>Please enter a username and try again.</p>";

 	// now check to see if it's already in the db
 	} else {

 		// connect to whatever database...(I'm using MySQL)

 		// check to see if that username has been used in my comments
 		$sqlquery = mysql_query("SELECT count(username) AS cnt
 		                         FROM blog_comment
 		                         WHERE username = " . PrepSQL($theusername)
 		                       );
 		$rs = mysql_fetch_assoc($sqlquery);
 		if($rs['cnt'] == 0) {
 			$html = "<p>Congratulations, the name <b>" . $theusername
 							. "</b> is available.</p>";
 		} else {
 			$html = "<p>Sorry, the name <b>" . $theusername
 							. "</b> is not available.</p>";
 		}
 	}

 ?>

 div = document.getElementById('nameavailable');
 div.innerHTML = '<?php echo $html; ?>';
 

And the HTML you should put in demo.php to use it:

 	<h3>Username availability demo</h3>

 	<p>This demo will check to see if a given username is valid and if it's present or not
 	in a database containing existing usernames.  This uses my "comments" database, so try
 	"Sithlet" or "Jonny" for existing names.</p>

 	<p>Enter the name to check for: <input type="text"
 	name="formName" id="formName" /></p>

 	<div id="nameavailable"></div>

 	<input type="button"
 	onclick="ajax_do('namecheck.php?username=' + document.getElementById('formName').value);"
 	value="Check Username Availability" />
 

Here’s the code for Digg style voting:

 <?php 

 	// how did the user vote?
 	if($_GET['awesome'] == "1") {
 		$awesome = 1;
 		$notawesome = 0;
 	} elseif($_GET['notawesome'] == "1") {
 		$awesome = 0;
 		$notawesome = 1;
 	} else {
 		echo("This file is only meant to be used as part of an AJAX application.");
 		exit();
 	}

 	// connect to whatever database (I'm using MySQL)

 	// ...snip...

 	// record the users vote
 	mysql_query("INSERT INTO voting_table (awesome, notawesome)
 					VALUES (" . $awesome . ", " . $notawesome . ")");

 	// count the votes so far
 	// I'm simply storing each vote in a table with two fields, and then just summing
 	// those fields to count votes
 	$sqlquery = mysql_query("SELECT sum(awesome) AS awesome_votes,
 					sum(notawesome) AS notawesome_votes
 					FROM voting_table");
 	$rs = mysql_fetch_assoc($sqlquery);

 	$html = "<p>Awesome votes: " . $rs['awesome_votes'] . "</p>"
 				. "<p>Not awesome votes: " . $rs['notawesome_votes'] . "</p>";

 ?>

 // 'votingresults' is the ID on the div tag that I want to update
 div = document.getElementById('votingresults');
 div.innerHTML = '<?php echo $html; ?>';
 

And the HTML/PHP to put in demo.php:

 <h3>Voting demo</h3>

 <p>Finally, this is something I've not done before in AJAX, but it's still pretty easy.
 This is very much like the AJAX on <a href="http://www.digg.com">Digg</a>.  Below is the
 vote count as of whenever this page was loaded.  Click "awesome" or "not awesome" to cast
 your own vote.  The votes will then be updated from the database, so if someone else voted
 while you were wasting time reading this text, their vote will appear too.</p>

 <input type="button" onclick="ajax_do('vote.php?awesome=1');" value="Awesome" />
 <input type="button" onclick="ajax_do('vote.php?notawesome=1');" value="Not Awesome" />

 <div id="votingresults">
 	<?php
 		// connect to whatever database (I use MySQL)

 		// ... snip ...

 		// count the votes so far
 		// this is an initial tally, as the div we are in will be updated if the user voted
 		$sqlquery = mysql_query("SELECT sum(awesome) AS awesome_votes,
 			sum(notawesome) AS notawesome_votes
 			FROM voting_table");
 		$rs = mysql_fetch_assoc($sqlquery);

 		$html = "<p>Awesome votes: " . $rs['awesome_votes'] . "</p>"
 			. "<p>Not awesome votes: " . $rs['notawesome_votes'] . "</p>";

 		echo($html);
 	?>
 </div>
 

I’ve attached the full source code for you to download, and you can check out
all three demos on the same page.

Digg this article!

Leave a Reply