Xajax 0.5: Tips and Tricks: New Features






Xajax 0.5: Tips and Tricks: New Features

Contents

[edit] Synchronous Requests

Beginning with xajax 0.5 beta 2, you can now initiate synchronous requests. This means that you can call a xajax enabled function and the browser will wait for the response before executing the remaining Javascript.

In addition, you can return a value from your PHP function and use it in the Javascript code following your xajax function call.

[edit] Usage

(Javascript)
xajax.call('myFunction', {mode:'synchronous', parameters['myDiv', 'some new content']});

(PHP)
function myFunction($sDivId, $sInnerHTML) {
    $objResponse = new xajaxResponse();
    $objResponse->assign($sDivId, 'innerHTML', $sInnerHTML);
    return $objResponse;
}

To return a value from the xajax enabled function, use:

(Javascript)
var myValue = xajax.call('myFunction', {mode:'synchronous'});
alert(myValue);

(PHP)
function myFunction() {
    $objResponse = new xajaxResponse();
    $objResponse->setReturnValue('Hello World!');
    return $objResponse;
}

[edit] Advantages

Sometimes the Javascript engine has to wait for data from the server before continuing the script. For example in doing multiple requests which depend on each other.

[edit] Disadvantages

Certain xajax response commands will enter a wait-state while waiting for an action to complete. This will interfere with the processing of a synchronous request, in that the synchronous request will appear to complete, returning the specified return value, at the point the wait-state is entered; this differs from the normal processing, which will only return from the synchronous call once all xajax response commands are processed. Currently, only the waitForCSS response command will cause this behavior. For this reason, it is advised to avoid using the waitForCSS response command in a xajax enabled function which is called synchronously.

By nature, synchronous calls cause the browser to block execution of Javascript code until the call is complete, or the browser call timeout expires. Therefore it is not possible for xajax to abort the request at an earlier point. (see Abort Request on Timeout below)


[edit] Server Redirect

Beginning with xajax 0.5 beta 2, the default xajax response processor will handle a server initiated redirect automatically. This is useful when you are accessing a secure page, for instance, and the user's login expires; the server should return a browser redirect (code 3XX) to the login page. If you wish to initiate a redirect from PHP, you can continue to use the xajax response:

$objResponse->redirect('http://myURL');

or begin using:

header('location: http://myURL');


[edit] Custom Response Processing

Custom response procssing was added in xajax 0.5 beta 1; with this, you can now specify a function that will be called once the response has been received from the server. The function will be called even in the event of a server error or redirect, regardless of the content-type of the response, so it will have complete control.

Note, care must be taken to restore xajax to the default state; please call xajax.completeResponse as shown in the example code below. Otherwise, the wait cursor state and status bar messages, amoung other things, will be incorrect.

To use this feature, first you must provide a PHP function to call which will provide the appropriate response.

function testXmlResponse()
{
	// Return xml data directly to the custom response handler function
	header('Content-type: text/xml; charset="utf-8"');
	return '<?xml version="1.0" encoding="utf-8" ?'.'><root><data>text</data></root>';
}

function testTextResponse()
{
	// return text data directly to the custom response handler function
	return 'text data';
}

$xajax = new xajax();
$xajax->setFlag("debug", true);

// Tell xajax to permit registered functions to return data other than xajaxResponse objects
$xajax->setFlag('allowAllResponseTypes', true);

$xajax->registerFunction("testXmlResponse");
$xajax->registerFunction("testTextResponse");

$xajax->processRequest();

Next, provide a Javascript 'responseProcessor' function. This function will need to extract the response text and process its content.

<script type='text/javascript'>

// function to handle ajax response text data
function textResponse(objResponse, objOptions)
{
	xajax.$('DataDiv').innerHTML = objResponse.responseText;
	xajax.completeResponse(objOptions);
}
// function to handle ajax response data XML
function xmlResponse(objResponse, objOptions)
{
	alert(objResponse.responseXML.documentElement.nodeName);
	xajax.$('DataDiv').innerHTML = 'non xajax: XML response';
	xajax.completeResponse(objOptions);
}
</script>

Last, specify your responseProcessor in the xajax.call

<input type="button" value="xml" 
onclick="xajax.call('testXmlResponse', {responseProcessor: xmlResponse}); return false;" />

<input type="button" value="text" 
onclick="xajax.call('testTextResponse', {responseProcessor: textResponse}); return false;" />


[edit] Abort Request on Timeout

In previous versions, xajax request calls would remain open until either the xajax response was received or the browser timed-out and aborted the call. Now, you can have xajax abort the request at an earlier time by setting a global abort timeout duration, or by creating a local callback event object and setting it's abort timeout duration. By setting the global abort timeout duration, you instruct xajax to abort all requests that exceed the specified duration. By using a local callback event, you can instruct xajax to abort specific requests at the specified duration.

[edit] Usage

// set delay event timeout to 400ms (.4 seconds)
// set delay abort timeout to 10000ms (10 seconds)
var myLocalCallback = xajax.callback.create(400, 10000);

xajax.call('myFunction', {callback: myLocalCallback});

Additionally, you can specify a Javascript function to call once the request has been aborted by xajax.

myLocalCallback.onExpiration = function() {
    // do something useful here
}
xajax.call('myFunction', {callback: myLocalCallback});


[edit] Improved Debug Output

The xajax debugger now shows some statistics about the request and response. Note in the sample below, the size of the request data is 35 bytes, the server response was code 200 (ok), the response data was 135 bytes and the request took 78 milliseconds total.

The timing will vary greatly, since it includes the time it takes to send the request, process the request, receive the response and process the response. If an alert box is shown during the response processing, this will delay the completion of the request, therefore the timing shown will depend also on the time it takes the user to respond to the alert.

xajax debug output
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Done [78ms]
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Received [status: 200, size: 135 bytes]:
<?xml version="1.0" encoding="utf-8" ?><xjx><cmd n="css">css1.css</cmd>
<cmd n="as" t="outputDIV" p="innerHTML">CSS1 loaded.</cmd></xjx>
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Sent [35 bytes]
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Sending request.
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Initializing Request Object..
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Calling loadCSS1 uri=css.php 
(post: xajax=loadCSS1&xajaxr=1164719655718)
Tue Nov 28 2006 08:14:15 GMT-0500 (Eastern Standard Time)Starting xajax...


[edit] Loading and unloading of CSS files

Minor improvements have been to the CSS handling in xajax 0.5 beta 2. In xajax 0.5 beta 1, the inclusion of CSS files was added. In beta 2, the ability to remove them was implemented. You can now add and remove style sheets at will. In addition, while including new CSS files, it may be desirable to wait for the CSS files to finish loading before concluding the xajax request. This is made possible with the $objResponse->waitForCSS(); response command.

This example shows the various calls:

function loadCSS1() {
	global $objResponse;
	$objResponse->removeCSS('css2.css');
	$objResponse->includeCSS('css1.css');
	$objResponse->waitForCSS();
	return $objResponse;
}


[edit] waitFor response command

A new response command was recently added which allows you to insert a wait state into the response processing. You can specify a javascript expression, which must evaluate to true or false, which will cause the response processing to wait for the expression to evaluate to true (or to timeout).

In the current implementation it is not possible to use this feature to synchronize between two xajax requests (since all response commands are processed in the order they are received). However, this feature can be used to watch for a javascript event to occur. Future versions may allow for request synchronization.

An example of how this feature might be used is shown below:

(test.php)

function test() {
    $objResponse = new xajaxResponse();
    $objResponse->includeScriptOnce('test.js');
    $objResponse->waitFor('testLoaded == true');
    return $objResponse;
}

(test.js)

myFunction = function() {
  // should do something useful here
}

testLoaded = true;

[edit] setFunction Response Command

You can now create functions on the browser side using a xajax response command. The setFunction command helps to automate the construction of javascript functions.

This:

$objResponse->setFunction("myFunction", "foo, bar", "alert(foo * bar);");

produces this:

myFunction = function(foo, bar) {
    alert(foo * bar);
}

[edit] wrapFunction Response Command

In addition to the setFunction command, you can also wrap an existing function inside another NEW function with the same name. Effectively, this wraps new statements around the function, then saves the result as a function with the same name.

Using this:

$objResponse->wrapFunction("myFunction", "foo, bar", 
    "alert('about to multiply ' + foo + ' and ' + bar);", 
    "alert('finished multiplication of ' + foo + ' and ' + bar);");

produces the following:

myFunction = function(foo, bar) {
    alert('about to multiply ' + foo + ' and ' + bar);
    original_myFunction(foo, bar);
    alert('finished multiplication of ' + foo + ' and ' + bar);
}

[edit] Script Context

Maintain the context for xajax asynchronous calls as if they were synchronous. You can now pass an object as a parameter to the xajax request and then access that object from the server side using the ->script, ->call, ->waitFor, ->setFunction and ->wrapFunction response commands.

In addition, you can access the context object in the callback event handlers.

In the example below, you can see an example of a xajax call that sets the context (which is a javascript object containing a reference to a button element and a div element. (javascript)

xajax.$('btn_100').onclick = function() {
    xajax.call('enable', { context : { btn: this, panel: xajax.$('div_100') } } );
}

In the example below, you can see how the context (referenced by 'this') can be modified using server commands. (php)

function enable() {
    $objResponse = new xajaxResponse();
    $objResponse->script("this.btn.innerHTML = 'Disable';");
    $objResponse->script("this.panel.visibility = 'visible';");
    $objResponse->script("this.panel.display = 'block';");
    return $objResponse;
}

In the script below, you can see how the context can be accessed from a callback event handler. (javascript)

xajax.callback.global.onComplete = function(oRequest) {
    alert(oRequest.context.btn.innerHTML);
}
  • Author: CtC - Joseph Woolley - 2007/01/01