Return JSON array using AJAX and Prototype

Well, Prototype is pretty awesome. So is scriptaculous.

However, I was hunting around and I couldn't find a decent tutorial on how to return an array of data using prototype's AJAX functions in JSON notation. There is this one, which was helpful, but it did a lot more than I wanted, and I wanted to use the services_JSON class I used in the ajax dropdown example from an earlier post.

Basic Tutorial on returning JSON formatted data through an AJAX call using Prototype:

First thing I did was download scriptaculous and get it working . Follow the link and you should find a download pretty easy as well as some info on how to use it.

With that all sorted out you want to learn about how to make an AJAX call using prototype - prototype is incroporated into scriptaculous in case you were wondering. Well in fact scriptaculous is an add on to prototype but whatever.

So, make some basic calls using the AJAX object. Its probably easiest to start with the Ajax.Updater function, but in order to get this example up and running I found it easier to use Ajax.Request.

Once you have AJAX running and returning some simple sample data back, updating a test div or what have you, we can move on to the JSON notation array.

Returning JSON array for Prototype

The first thing you want to do is include the JSON class and create a new object of that class:

include_once('Services_JSON.php');
//make json object...
$json = new Services_JSON();

Now you can use this cool class to encode all sorts of information into JSON notation. Encoding data is really straightforward...

//create array...
$data = array("New York", "New Yorkshire", "New Jersey");

//encode and return json data...
echo $json->encode($data);

There are two methods of returning JSON data. One is in the X-JSON header and the other is just in the plain old body of the page just as you would with any other ordinary AJAX request.

I prefer returning the data in the body of the page because there is a limit to how many bytes you can stuff into the X-JSON header, and problems can arise.

Also, it seems that the X_JSON header was not intended for large amounts of data, rather, a way of indicating status of the data of the AJAX request. Which makes sense, adds flexibility and all that.

So, back to it. Adding JSON encoded data to the X_JSON header is like so...

header('X-JSON: ('.$json->encode($data).')');

I used this code to add JSON data to the body of the data returned by the AJAX call...

header('Content-type: application/x-json');
//encode and return json data...
echo $json->encode($data);

Now that the data is being returned in the correct format (check that it is by visiting the page generating the data, without forgetting to add any get variables you need) we can move on to handling the data with the Ajax object.

Using Ajax.Request to process the JSON array:

The Ajax.Request method is pretty comprehensive and easy to use to say the least. There is an excellent example of how to use it which pretty much covers everything. But to complete this tutorial I'll go over what I did.

I used a callback function for the resonse onComplete (there are a number of other responses explained in the link above).

function keywordOutput(currentURL){
    var url = 'ajax-query.php';
    var pars = 'url='+currentURL;
    var myAjax = new Ajax.Request(url, {method: 'get', parameters: pars, onComplete: getResponse});
}

You can see that the above is going to call getResponse() on completion of the AJAX request. All we need to do now is declare getResponse() so that after onComplete is fired the script knows what to do with the data.

function getResponse(oReq, oJSN) {
    var data = eval(oReq.responseText);
    $('test-div').innerHTML = '';
    //populate the list
    for (var i = 0; i < data.length; i++) {
        $('test-div').innerHTML += data[i]+', ';
    }
}

This basically goes through the data returned by the AJAX call, oReq, and outputs it to a test div. If you have also supplied the X-JSON header with JSON data then that will be available in the oJSN variable. Alternatively this function can be declared as a global reposnder so that any AJAX call that fires a particular status code will call this function - you can find out more about global responders on the prototype site.