JavaScript Object Notation (JSON) is a lightweight data-interchange format. Basically, it is nothing more than a JavaScript hash (see an example in Listing 11-26) used to carry object information. But JSON has two great benefits for Ajax interactions: It is easy to read in JavaScript, and it can reduce the size of a web response.
Listing 11-26 - A Sample JSON Object in JavaScript
var myJsonData = {"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
If an Ajax action needs to return structured data to the caller page for further JavaScript processing, JSON is a good format for the response. This is very useful if, for instance, one Ajax call is to update several elements in the caller page.
For instance, imagine a caller page that looks like Listing 11-27. It has two elements that may need to be updated. One remote helper could update only one of the elements of the page (either the title
or the name
), but not both.
Listing 11-27 - Sample Template for Multiple Ajax Updates
<h1 id="title">Basic letter</h1>
<p>Dear <span id="name">name_here</span>,</p>
<p>Your e-mail was received and will be answered shortly.</p>
<p>Sincerely,</p>
To update both, imagine that the Ajax response can be a JSON data containing the following array:
[["title", "My basic letter"], ["name", "Mr Brown"]]
Then the remote call can easily interpret this response and update several fields in a row, with a little help from JavaScript. The code in Listing 11-28 shows what could be added to the template of Listing 11-27 to achieve this effect.
Listing 11-28 - Updating More Than One Element from a Remote Response
<?php echo link_to_remote('Refresh the letter', array(
'url' => 'publishing/refresh',
'complete' => 'updateJSON(ajax)'
)) ?>
<?php echo javascript_tag("
function updateJSON(ajax)
{
json = ajax.responseJSON;
for (var i = 0; i < json.length; i++)
{
Element.update(json[i][0], json[i][1]);
}
}
") ?>
The complete
callback has access to the Ajax response and can pass it to a third-party function. This custom updateJSON()
function iterates over the JSON obtained from the response via responseJSON
and for each member of the array, updates the element named by the first parameter with the content of the second parameter.
Listing 11-29 shows how the publishing/refresh
action can return a JSON response.
Listing 11-29 - Sample Action Returning JSON data
class publishingActions extends sfActions
{
public function executeRefresh()
{
$this->getResponse()->setHttpHeader('Content-Type','application/json; charset=utf-8');
$output = '[["title", "My basic letter"], ["name", "Mr Brown"]]';
return $this->renderText('('.$output.')');
}
Using the application/json
content type allows Prototype to automatically evaluate the JSON passed as the body of the response, which is preferred to returning it via the header, because the HTTP header is limited in size and some browsers struggle with responses that do not have a body.
By using ->renderText()
the template file is not used, resulting in better performance.
JSON has become a standard among web applications. Web services often propose responses in JSON rather than XML to allow service integration in the client (mashup), rather than on the server. So if you wonder which format to use for communication between your server and a JavaScript function, JSON is probably your best bet.
Tip Since version 5.2, PHP offers two functions, json_encode()
and json_decode()
, that allow you to convert an array between the PHP syntax and the JSON syntax, and vice versa (http://www.php.net/manual/en/ref.json.php). These facilitate the integration of JSON arrays (and Ajax in general) and enable the use of more readable native PHP code:
$output = array("title" => "My basic letter", "name" => "Mr Brown");
return $this->renderText(json_encode($output));