Part AJAX Handlers



Overview


AJAX Handlers are methods that can be placed within your part code that are intended to be called by an AJAX javascript code in your page. This allows your part to generate content are return more information to the part without requiring a page refresh. To create an AJAX handler in your code, simply create a method named "ajaxName" in your part.

AJAX Handlers in parts work nearly the exact same as AJAX Handlers in Code Behind Pages. Please check out the CodeBehind AJAX Handler documentation first to get a good understanding of how they work.

The only difference for Part AJAX handlers is that they are accessed by placing aID in the GET or POST of AJAX request. (Where ID is the name of your part). This will cause the AJAX handler for your part to be called. Anything that your part echos will be sent back. After your AJAX handler exists, the script immediately exists. Nothing other than what you echo in your handler is returned in your AJAX Response.

The only major gotcha when working with AJAX for parts is that your AJAX parts MUST know your parts ID in order for the request to work. You can get around this by having your template call a javascript function with the part ID, making use of the template variable <?=$id?>, which contains the id of your part.

A Javascript Method is also provided that your scripts can call to cause an AJAX Request: Util.AjaxPartRequest(HandlerName, PartId, data, OnSuccessCallback, OnFailureCallback). An example of using this method is provided below:

Exmaple




Directory Structure:
================================
partTime.php
|--bin/
   |--templates/
   |  |--time.tmpl.php
   |--js/
      |--AjaxTest.js


partTime.php (Time Part)
================================
<?php
class partTime extends part {
    var 
$defaultView "Time"
    
/* View Handler */
    
function viewTime(){
        
$this->addJavascriptHeader($this->binDirectory."js/AjaxTest.js");
        return 
$this->fetch("time.tmpl.php");    
    }
    
/* AJAX - Returns the current time */
    
function ajaxGetTime(){
        
$today date("F j, Y, g:i a");
        echo(
"$today");
    }
}
?>


time.tmpl.php (Template)
================================
<input type="button" value="Get Time!" onclick="GetTime(<?=$id?>)">
<div id="TimeDiv"></div>


AjaxTest.js (Javascript)
================================
function GetTime(partid){
    Util.AjaxPartRequest("GetTime",partid,"",GetTimeCallback);
}

function GetTimeCallback(transport){
    $("TimeDiv").innerHTML = transport.responseText;
}


This part shows a button with the text "Get Time" on it.

timea1.jpg

After a user clicks the button, the current time is fetched via an AJAX Request.

timea2.jpg

Making an AJAX Request


In the above example an AJAX request was submitted by using the built in Util.AjaxPartRequest() method. This is a built in Utility method that will automatically Invoke an Ajax Handler on your part and returns its result. You can, however, skip this and manually invoke the AJAX request using Prototype's library. Below covers 3 common ways you can make your AJAX requests from Javascript:

Util.AjaxRequest()


This is a built in Utility method provided by TextSide that will submit an Ajax request to your current page. It accepts 4 parameters:


AjaxHandlerName -       The name of the Ajax Handler to Trigger. Example: "GetTime"
PartId -         The id of your part. This is used to direct the AJAX request. You can get this id through <?=$id?> in your template.
data -                  Any extra data to pass to the Ajax Handler. For example: "timezone=5&region=south"
OnSuccess -             A callback method that will be invoked when the ajax request completes
OnFailure -            (optional) A callback method that will be invoked if the ajax request fails. 

function Util.AjaxPartRequest(AjaxHandlerName, PartId, data, OnSuccess, OnFailure);

An example use:
Util.AjaxRequest("GetTime",12,"",GetTimeCallback);

Prototype's Ajax.Request Method


You can also directly use Prototypes Ajax.Request method to get more control over your AJAX request. For examples on using this class, please see the Prototype Ajax Tutorial

If you wish to submit your AJAX request to your current page, two helpful global variables are Site.SiteRoot and Site.Url. The first gives the absolute url to your sites root (http://www.yoursite.com/") while the second gives the path to your current page relative to the root ("tests/ajaxtest"). Together they can be used to create a request to your current page using Prototype's Ajax.Request method.

Here's an example:


var partId = 12;
new Ajax.Request(Site.SiteRoot + Site.Url, {
  method:'post',
  parameters:'a'+partId+'=GetTime',
  onSuccess: GetTimeCallback
});
Note how ajax=GetTime is set in the parameters field to direct the request to your desired AJAX Handler.

Prototype's Form.Request Method


Another common case when working with AJAX is submitting an entire form without a page refresh. You can do this with Prototypes .request() method that it automatically appends to form elements accessed in Javascript.

Here's an example:

HTML
==========
<form action="<?=$PHP_SELF?>" method="post" id="MyFormName">
<input type="hidden" name="a<?=$id?>" value="AjaxHandlerName">
Email: <input type="text" name="email">
<input type="button" value="Signup!" onclick="SubmitMyForm()">

Javascript
==========
function SubmitMyForm()
{
    $("MyFormName").request({
        onComplete: SubmitMyFormCallback()
    });
}
function SubmitMyFormCallback(transport)
{
    alert("Form Submitted!");
}


Using JSON To Return Results


Often you'll want your AJAX Handlers to return some information to the page that invoked them. A handy way to do this is using JSON. JSON is a lightweight data interchange format that is often used to send information back to Javscript, as it can be easily parsed.

To use JSON in the TextSide Engine, you pass any class, array, or data structure to the method util::json($object);. This will return a string that you can echo. The Callback Method in your Javascript code can then parse the response into a Javascript object using Prototypes evalJSON() function.

Heres a short example:


AJAX Handler:
=============
<?php 
//...
function ajaxGetUser(){
    
$username util::getData("username");
    
$user = & new user();
    
$user->loadFromDatabaseByUser($username);
    echo 
util::json($user);
}
//...
?>

Javascript:
=============
function GetUserDetails(partid, name){
    Util.AjaxPartRequest("GetUser", partid, "username="+name,GetUserDetailsCallback);
}

function GetUserDetailsCallback(transport){
    var user = transport.responseText.evalJSON();
    //user object data is now available in Javascript:
    alert("FirstName: "+user.firstname);
    alert("LastName: "+user.lastname);
}