Basic AJAX starter pack using jQuery and PHP

If you'd like to add the "Web 2.0" feel to your website, one of the first things to do is make your site feel more like an application and less like a website.  The traditional "blog" style websites have many page loads and a very "linear" user experience (meaning visitor go from one page to the next).  An application or tool feels much more interactive and can be a more engaging user experience.  To accomplish this, we'll add some simple AJAX functionality using the "starter pack" here.

Requirements:
- Webserver running PHP 5.3+
- jQuery v1.4.2+ (may work with older versions but not tested)

 


Step 1
Download the attached starter pack then unpack it and copy the files it to your website.

Step 2
Navigate to the website location where you uploaded the starter pack (http://yoursite.com/path/to/starter/pack/index.html).

Step 3
Go through the examples shown on the page.  After you've seen the examples, you are ready to start customizing it to your needs.  We'll go through the files in the starter pack and discuss how they are being used to deliver a simple AJAX experience.  Starter Pack Files

+com
    +example
        +controllers
            -ExampleHandler.php
+com
    +totalapp
        +controllers
            -AjaxController.php
-ajax.js
-ajax.php
-index.html

 

Folder Structure and organization
The folder structure is organized in a java-like manner.  The "com" folder will separate portions of the code into organized libraries.  In this starter pack you will see a com/totalapp folder.  This folder is a library of code that is used to drive the AJAX portion of the starter pack.  The idea behind keeping good folder structure is that it makes it easy to reuse your code in multiple projects.  When using the starter pack, you should not need to modify anything inside the com/totalapp folder.  You should be working with and customizing the com/example folder (although you will eventually want to rename com/example to something else that is more applicable to your project).

Learning about PHP's autoload function using namespaces
PHP 5.3 offers the ability to use namespaces for your code.  This topic is very technical in nature, so I won't go into much detail about what namespaces are.  Another great feature addition is the __autoload() function.  The __autoload() function is called when a class or interface you are trying to use hasn't been defined yet.  The combination of the __autoload() function and the namespace file organization help to develop cleaner and more organized code.Normally when you create classes, you will have one per PHP file.  Then to use that class, you first must include() the file before you can use the class.  The __autoload() function takes care of the file include() code for you.  Here is the __autoload() function from the ajax.php file (included in the starter pack):

ajax.php

  1. // Setup auto load for namespace
  2. function __autoload($class)
  3. {
  4. $file = realpath(dirname(__FILE__)."/".$class.".php");
  5. if(!file_exists($file)) throw new Exception("Class file not found: ".$class." (".$file.")");
  6. require_once $file;
  7. }

The $class argument passed to the __autoload() function is the full name of the class with the namespace. The above code takes the class name and namespace and translates it into a file path to include. In the starter pack, the examples use the com/example/controllers/ExampleHandler.php file to do all the server side processing. The ExampleHandler.php file is in the com\example\controllers namespace. ExampleHandler.php
namespace com\example\controllers;
Notice that the namespace is the same as the folder path to the file. This is what allows the __autoload() function to work. Here we can show the difference in code from the old (non __autoload()) method to the new method.

Old way:

  1. <?php
  2. require_once "com/example/controllers/ExampleHandler.php"; // Include file
  3. ExampleHandler::ex1($info); // Call a static method of the class
  4. ?>

New way:

  1. <?php
  2. \com\example\controllers\ExampleHandler::ex1($info); // Include class file and call a static method at the same time
  3. ?>

As seen here, the __autoload() function combined with proper folder organization and namespaces cuts down on code and also allows you to load and use classes on the fly. Using the starter pack code files to fit your needs
We'll go through the files in the starter pack one by one and describe what each does and how it can be used to help you create a simple AJAX system. com/example/controllers/ExampleHandler.php

  1. <?php
  2. namespace com\example\controllers;
  3. use \com\totalapp\controllers\AjaxController as ajax;
  4.  
  5. // This class will controll the example events
  6. class ExampleHandler
  7. {
  8. 	public function __construct($request)
  9. 	{
  10. 		// Do request operation
  11. 		extract($request);
  12. 		if(!empty($fnc)) self::$fnc();
  13. 	}
  14.  
  15. 	// Example 1
  16. 	public static function ex1()
  17. 	{
  18. 		// Use alert to show value sent
  19. 		ajax::alert("You sent: \"" . $_REQUEST['value'] . "\"");
  20. 		ajax::respond();
  21. 	}
  22.  
  23. 	// Example 2
  24. 	public static function ex2()
  25. 	{
  26. 		// Use alert to show value sent
  27. 		ajax::alert("You sent: \"" . $_REQUEST['value'] . "\"");
  28. 		ajax::respond();
  29. 	}
  30.  
  31. 	// Example 3
  32. 	public static function ex3()
  33. 	{
  34. 		// Respond with a string with a current timestamp
  35. 		ajax::respond($_REQUEST['value'] . " @ " . date("F j, Y, g:i a"));
  36. 	}
  37.  
  38. 	// Example 4
  39. 	public static function ex4()
  40. 	{
  41. 		// Use alert to show form data
  42. 		ajax::alert("form data sent to server:\n\n" . print_r($_REQUEST['form'], true));
  43. 		ajax::respond();
  44. 	}
  45.  
  46. 	// Example 5
  47. 	public static function ex5()
  48. 	{
  49. 		// Use alert to show restructured form data
  50. 		$data = ajax::getKVarray($_REQUEST['form']);
  51. 		ajax::alert("restructured form data:\n\n" . print_r($data, true));
  52. 		ajax::respond();
  53. 	}
  54.  
  55. 	// Example 6
  56. 	public static function ex6()
  57. 	{
  58. 		// Change html value (use json_encode to make sure the new value is in good form
  59. 		$newVal = json_encode("Changed from server @ " . date("F j, Y, g:i:s a"));
  60. 		ajax::respond("$('#ex6text').html(" . $newVal . ");");
  61. 	}
  62.  
  63. 	// Example 7
  64. 	public static function ex7()
  65. 	{
  66. 		// Run javascript
  67. 		ajax::respond("$('#ex7').animate(
  68. 		{
  69. 			width: '70%',
  70. 			opacity: 0.4,
  71. 			marginLeft: '0.6in',
  72. 			fontSize: '3em',
  73. 			borderWidth: '10px'
  74. 		}, 1500, function() { $('body').attr('scrollTop', '100000000'); });
  75.  
  76. 		$('#ex7go').val('Server response finished...');");
  77. 	}
  78.  
  79. }
  80. ?>

This file is used to handle and process all of the data from javascript of the example index.html page. Line 2 defines the namespace for the file. As mentioned in the information above, we keep the namespace the same as the folder structure to make it easier to reference the class.
namespace com\example\controllers;
Line 3 defines an alias to another namespaced class (the alias topic will not be covered in depth here). Basically the alias is a quicker/easier way to refer to the full location of a namespaced class. Here we use it to refer to "\com\totalapp\controllers\AjaxController" simply as "ajax". Then we can use "ajax" to call methods from the \com\totalapp\controllers\AjaxController class.
use \com\totalapp\controllers\AjaxController as ajax;
The rest of the class file defines methods used in all the examples. Each example has a separate static method inside the EventHandler.php class that are defined here. This class is where all the business logic and server side code goes before creating the response. com/totalapp/controllers/AjaxController.php

  1. <?php
  2. namespace com\totalapp\controllers;
  3.  
  4. // Provides general ajax functionality
  5. class AjaxController
  6. {
  7. public static $response = "";
  8.  
  9. // Add response
  10. public static function response($r)
  11. {
  12. self::$response .= $r;
  13. }
  14.  
  15. // Output response
  16. public static function respond($r=NULL)
  17. {
  18. if(!empty($r)) self::response($r);
  19. header("Content-type: application/javascript");
  20. die(self::$response);
  21. }
  22.  
  23. // Get alert for js msg
  24. public static function alert($msg) { self::jsAlert($msg); }
  25. public static function jsAlert($msg)
  26. {
  27. //header("Content-type: application/javascript");
  28. self::$response .= "alert(".json_encode($msg).");";
  29. }
  30.  
  31. // Force a server error with msg
  32. public static function error($msg)
  33. {
  34. header('HTTP/1.1 500 Internal Server Error');
  35. die($msg);
  36. }
  37.  
  38. // Get key/value array from a jquery serializeArray() result
  39. public static function getKVarray($jqArray)
  40. {
  41. foreach($jqArray as $pair)
  42. {
  43. $t = "\$".$pair['name']." = \"".$pair['value']."\";\n";
  44. eval($t);
  45. }
  46. unset($jqArray, $pair, $t);
  47. return get_defined_vars();
  48. }
  49. }
  50.  
  51. ?>

This file creates all the actions need to make the proper responses. You should not need to modify this file. Here’s a basic run-down of the methods defined here:MethodParametersReturnDescriptionExampleresponse$r - stringvoidAdd text to the response.ajax::response(“var status = ‘received’;
alert(‘hello world’););respond$r – string [optional]voidFinish creating the response and send to client after adding passed in text.ajax::responsd(“var status = ‘done’;”);alert$msg – stringvoidCreates and alert from the text passed in.ajax::alert(“hello world”);error$msg – stringvoidTriggers an error in the jQuery ajax request with the text passed in.ajax::error(“there was an error processing your request”);getKVarray$jqArray – Array (jQuery serializeArray())ArrayTakes a jQuery array from serializeArray() and convert it to a “key => value” style array.$newArray = ajax::getKVarray($_REQUEST[‘formData’]); The methods here are used to build and create a response to send back to the client. In order to finish the response and send to the browser, you must end with the respond() or error() command as shown in this example (from ExampleHandler.php):

  1. // Example 1
  2. public static function ex1()
  3. {
  4. // Use alert to show value sent
  5. ajax::alert("You sent: \"".$_REQUEST['value']."\"");
  6. ajax::respond();
  7. }

Without the respond() command in line 20, no response will be sent to the client. ajax.js

  1. // Function used to make an AJAX call
  2. var ajaxServerFile = './ajax.php';
  3. function ajaxCall(info)
  4. {
  5. var success = (typeof(info.success) == 'function') ? info.success : function() { };
  6. var async = (typeof(info.async) == 'undefined') ? true : info.async;
  7. delete info.success;
  8. delete info.async;
  9. $.ajax(
  10. {
  11. 'async': async,
  12. 'url': ajaxServerFile,
  13. 'type': 'POST',
  14. 'data': info,
  15. 'error': function(xhr, textStatus, errorThrown) { alert(xhr.responseText); },
  16. 'success': function(data)
  17. {
  18. if(typeof(success) == 'function') success(data);
  19. }
  20. });
  21. }

This file creates a wrapper function around jQuery’s ajax method. The ajaxCall() is the function used to initiate ajax communication with the server. Here is an example of it’s usage (from index.html):

  1. // Example 2
  2. $('#ex2go').click(function(e)
  3. {
  4. ajaxCall(
  5. {
  6. 'class': 'com\\example\\controllers\\ExampleHandler',
  7. 'fnc': 'ex2',
  8. 'value': $('#ex2send').val(),
  9. 'success': function(data) { alert('ajax successful!'); }
  10. });
  11. });

Function options for ajaxCall():OptionParametersDefaultRequiredDescriptionExampleasyncbooleantrueNoMake the call using asynchronous mode. If false, the call will be run in non-asynchronous mode.async: falseclassstringnullYesPHP class to use as the controller for the AJAX communication. You must supply the full namespace location to the class. *Note: you must escape the “\” namespace separation character.class: 'com\\example\\controllers\\ExampleHandler'fncstringnullYesThe method to use from the “class” defined.fnc: ‘ex2’successfunctionnullNoCallback function that is run after the AJAX response finishes successfully.success: function(data) { alert(‘response: ‘+data); } In addition to the above options, you can also add any additional data you want to the ajaxCall(). Here is an example of adding extra data to the ajaxCall() (from index.html):

  1. // Example 4
  2. $('#ex4form').submit(function(e)
  3. {
  4. ajaxCall(
  5. {
  6. 'class': 'com\\example\\controllers\\ExampleHandler',
  7. 'fnc': 'ex4',
  8. 'form': $(this).serializeArray()
  9. });
  10. });

This adds the “form” data to the ajaxCall(). When PHP receives that request, the “form” value can be accessed by using the $_REQUEST[‘form’] variable. ajax.php

  1. <?php
  2.  
  3. // Setup auto load for namespace
  4. function __autoload($class)
  5. {
  6. $file = realpath(dirname(__FILE__)."/".$class.".php");
  7. if(!file_exists($file)) throw new Exception("Class file not found: ".$class." (".$file.")");
  8. require_once $file;
  9. }
  10.  
  11. // Call class/method requested from JS
  12. $class = urldecode($_REQUEST['class']);
  13. if(isset($class))
  14. {
  15. // Pass to controller
  16. $controller = new $class($_REQUEST);
  17. exit;
  18. }
  19.  
  20. // Not a valid request
  21. header('HTTP/1.1 500 Internal Server Error');
  22. die("Error: Invalid request.");
  23.  
  24. ?>

This file is used to accept the AJAX request from the client and feed it to the proper class/method. You should not need to modify this file. index.html

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html">http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html</a> xmlns="<a href="http://www.w3.org/1999/xhtml"">http://www.w3.org/1999/xhtml"</a> lang="en" xml:lang="en">
  4. <head>
  5. <title>AJAX Starter Pack - Examples</title>
  6. <script src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"">http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"</a> type="text/javascript" charset="utf-8"></script>
  7. <script src="./ajax.js" type="text/javascript" charset="utf-8"></script>
  8.  
  9. <style>
  10. .exampleArea { margin-bottom: 15px; }
  11. .exampleArea .exMain
  12. {
  13. border: 1px solid #000;
  14. padding: 5px;
  15. }
  16. .exampleArea .exMain .description
  17. {
  18. font-size: .75em;
  19. margin-bottom: 5px;
  20. }
  21. </style>
  22.  
  23. <script>
  24.  
  25. // Page load function
  26. $(function()
  27. {
  28. // Example 1
  29. $('#ex1go').click(function(e)
  30. {
  31. ajaxCall(
  32. {
  33. 'class': 'com\\example\\controllers\\ExampleHandler',
  34. 'fnc': 'ex1',
  35. 'value': $('#ex1send').val()
  36. });
  37. });
  38.  
  39. // Example 2
  40. $('#ex2go').click(function(e)
  41. {
  42. ajaxCall(
  43. {
  44. 'class': 'com\\example\\controllers\\ExampleHandler',
  45. 'fnc': 'ex2',
  46. 'value': $('#ex2send').val(),
  47. 'success': function(data) { alert('ajax successful!'); }
  48. });
  49. });
  50.  
  51. // Example 3
  52. $('#ex3go').click(function(e)
  53. {
  54. ajaxCall(
  55. {
  56. 'async': false,
  57. 'class': 'com\\example\\controllers\\ExampleHandler',
  58. 'fnc': 'ex3',
  59. 'value': $('#ex3send').val(),
  60. 'success': function(data) { alert('server sent response: "'+data+'"'); }
  61. });
  62.  
  63. // Note that this alert won't be called until after response from the server
  64. alert('server response finished.');
  65. });
  66.  
  67. // Example 4
  68. $('#ex4form').submit(function(e)
  69. {
  70. ajaxCall(
  71. {
  72. 'class': 'com\\example\\controllers\\ExampleHandler',
  73. 'fnc': 'ex4',
  74. 'form': $(this).serializeArray()
  75. });
  76. });
  77.  
  78. // Example 5
  79. $('#ex5form').submit(function(e)
  80. {
  81. ajaxCall(
  82. {
  83. 'class': 'com\\example\\controllers\\ExampleHandler',
  84. 'fnc': 'ex5',
  85. 'form': $(this).serializeArray()
  86. });
  87. });
  88.  
  89. // Example 6
  90. $('#ex6go').click(function(e)
  91. {
  92. ajaxCall(
  93. {
  94. 'class': 'com\\example\\controllers\\ExampleHandler',
  95. 'fnc': 'ex6'
  96. });
  97. });
  98.  
  99. // Example 7
  100. $('#ex7go').click(function(e)
  101. {
  102. ajaxCall(
  103. {
  104. 'class': 'com\\example\\controllers\\ExampleHandler',
  105. 'fnc': 'ex7'
  106. });
  107. });
  108. });
  109. </script>
  110.  
  111. </head>
  112. <body>
  113.  
  114. <div id="ex1" class="exampleArea">
  115. <div class="exTitle">Example 1 - Send simple text input to server:</div>
  116. <div class="exMain">
  117. <div class="description">Send value of a single textbox to the server.</div>
  118. <input id="ex1send" value="say hello" /> <input id="ex1go" type="button" value="Go" />
  119. </div>
  120. </div>
  121.  
  122. <div id="ex2" class="exampleArea">
  123. <div class="exTitle">Example 2 - Send simple text input with success callback:</div>
  124. <div class="exMain">
  125. <div class="description">Send value of a single textbox to the server and supply a callback function to run when the response is successful.</div>
  126. <input id="ex2send" value="say hello" /> <input id="ex2go" type="button" value="Go" />
  127. </div>
  128. </div>
  129.  
  130. <div id="ex3" class="exampleArea">
  131. <div class="exTitle">Example 3 - Send simple text input non-asynchronously with success callback:</div>
  132. <div class="exMain">
  133. <div class="description">Send value of a single textbox to the server in non-asynchronouse mode. By default AJAX calls are made synchronously and the javascript doesn't not wait for a response from the server to continue. This example illustrates a non-asynchronous call to the server before continuing.</div>
  134. <input id="ex3send" value="say hello" /> <input id="ex3go" type="button" value="Go" />
  135. </div>
  136. </div>
  137.  
  138. <div id="ex4" class="exampleArea">
  139. <div class="exTitle">Example 4 - Submit a form:</div>
  140. <div class="exMain">
  141. <div class="description">Send the values of an entire form using jQuery's serializeArray() function as a value to send to the server. Normally forms are sent to the server in &quot;key => value&quot; pair form. jQuery's serializeArray() function however, sends the data in a different form. The array of form data sent to the server will be display when the form is submitted.</div>
  142. <form id="ex4form" action="javascript: void(0);">
  143. <div>First Name: <input name="fName" value="bob" /></div>
  144. <div>Last Name: <input name="lName" value="smith" /></div>
  145. <div>Age: <input name="age" value="28" /></div>
  146. <input type="submit" value="Go" />
  147. </form>
  148. </div>
  149. </div>
  150.  
  151. <div id="ex5" class="exampleArea">
  152. <div class="exTitle">Example 5 - Submit a form:</div>
  153. <div class="exMain">
  154. <div class="description">The previous example shows the array of data that is sent the the server in non &quot;key => value&quot; form. This example shows how you can use the getKVarray() method of the AjaxController PHP controller class to restructure the sent array data into &quot;key => value&quot; form. See the &quot;Example 5&quot; section of the com/example/controllers/ExampleHandler.php file to see how this method is used to restructure the array.</div>
  155. <form id="ex5form" action="javascript: void(0);">
  156. <div>First Name: <input name="fName" value="bob" /></div>
  157. <div>Last Name: <input name="lName" value="smith" /></div>
  158. <div>Age: <input name="age" value="28" /></div>
  159. <input type="submit" value="Go" />
  160. </form>
  161. </div>
  162. </div>
  163.  
  164. <div id="ex6" class="exampleArea">
  165. <div class="exTitle">Example 6 - Change HTML content:</div>
  166. <div class="exMain">
  167. <div class="description">Response from the server can be used to run js code. This example shows a value being replaced by using the server response.</div>
  168. <strong id="ex6text">Change Me</strong> <input id="ex6go" type="button" value="Go" />
  169. </div>
  170. </div>
  171.  
  172. <div id="ex7" class="exampleArea">
  173. <div class="exTitle">Example 7 - Running javascript commands using server response:</div>
  174. <div class="exMain">
  175. <div class="description">Reponses from the server can be used to run any javascript you wish.</div>
  176. <input id="ex7go" type="button" value="Run Server Generated Response" />
  177. </div>
  178. </div>
  179.  
  180. </body>
  181. </html>

This file demonstrates several ways you can use the AJAX starter pack and should help get you up and running quickly and easily. Grab the starter pack and get up and running with easy AJAX on your own site!

Attached File: