Inviting JSON to the Table

I’m doing some preliminary work on a project for which it’s been suggested that I consider using JSON rather than XML as a data transport. “JSON?” you ask. “What’s that?” It stands for JavaScript Object Notation, and for those of us who’ve spent a lot of time writing javascript, it’ll look very familiar. It’s a subset of the javascript language and can be described as the convention whereby one represents object members as name/value pairs. In short, it’s a form of serialization native to javascript and is therefore understood by all modern browsers out of the box and by many other programming languages either natively or by simple extension. A javascript function can eval a JSON text string with no additional parsing needed and can then use the decoded values directly. This can be beneficial to web applications in at least two potentially notable ways:

  • It eliminates the need to parse a verbose XML document into an object and then perform operations on the object.
  • The format can be (though isn’t necessarily) less verbose than XML.

Transfer time and processing overhead can therefore be optimized when using JSON in some circumstances. Furthermore, for some uses, JSON might actually save programming effort required on the server side to generate XML from objects or on the client side going in the other direction.

Those advantages notwithstanding, I was originally hesitant to give JSON more than a passing glance. For most web applications that feature the sort of functionality I had in mind (including, as far as I was aware at the time, the one I’m doing R&D for), existing AJAX toolkits fit the bill, and I was inclined to use an existing AJAX toolkit rather than to implement JSON for the sheer novelty of doing so. Consider an editable grid table, for example. You have a text field with an onchange event. On change, you send a small piece of data to the server and you get a small piece of data back that tells the client how to provide UI feedback. None of the three benefits of JSON I mentioned above really apply here, as the data in both directions is small, requires almost no processing, and need not be an otherwise usable object. It’s text out, text in, and minor DOM manipulation. In such a case, JSON provides no real advantage, and you might as well go with a standard AJAX toolkit.

A colleague working on the project with me pointed out some other possible use cases, however, that might render JSON worth further investigation. For example, if the data comes down as an object, it can be sorted and have calculations performed on it more readily on the client side without a round-trip to the server and back per operation. There’s something very appealing to me about this. So I’ll be doing more diligence on JSON.

As my first foray into coding with JSON, I wanted to test the example my colleague brought up. Doing so required me to grab a few libraries, and I haven’t packaged it all up nicely, but it’d be reasonably easy to assemble these things and test this out for yourself if you’re interested. Here’s what you need to grab:

So, in a web sandbox, save the PEAR class as JSON.php and create a file named “process.php” with the following contents:

<?php

include("JSON.php");

$rows = array();
$cols = array();

$colcount=20;

for($i=0; $i<$colcount; $i++){
array_push($cols, "col $i");
}

for($i=0; $i<100; $i++){
$row=array("count"      => $i);
for($j=0; $j<$colcount; $j++){
$row[$cols[$j] ] = substr(md5(microtime() . $cols[$colcount]),0,8);
}
array_push($rows, $row);
}

$response=array(
"error"         => "0",
"message"       => "success",
"payload"       => $rows
);

$json = new Services_JSON();
$output = $json->encode($response);
print($output);

?>

This script generates 100 rows of 20 columns of junk data and returns it as a JSON object. In a real-world application, this would presumably be a data set returned from a database. The XMLHttpRequest issued from your client calls this script and handles the data. Now on to that part of the code. Create a file named index.html and populate it as follows:

<html>
<head>
<title>JSON Demo</title>
<script type="text/javascript" xsrc="sortable.js" mce_src="sortable.js"   ></script>
<script type="text/javascript" xsrc="json.js" mce_src="json.js"   ></script>
<script type="text/javascript" xsrc="xmlrpc.js" mce_src="xmlrpc.js"   ></script>
<style type="text/css">
/* Sortable tables */
table.sortable a.sortheader {
background-color:#eee;
color:#666666;
font-weight: bold;
text-decoration: none;
display: block;
}
table.sortable span.sortarrow {
color: black;
text-decoration: none;
}
</style>
</head>
<body>
<div id="container">
<input type="text" id="thefield" name="thefield" value="" />
<input type="button" id="thebutton" name="thebutton" value="The Button" onclick="json_request(document.getElementById('thefield').value)" />
</div>
</body>
</html>

Note the javascript includes at the top, and be sure to name the downloaded libraries appropriately or to change the file. Now create json.js and populate it as follows:

function json_request(txt){

var myOnComplete = function(responseText, responseXML){
var obj = eval('(' + responseText + ')');
var container=document.getElementById('container');
container.appendChild(make_table(obj.payload));
sortables_init();
}

var myOnLog = function(msg){
alert(msg);
}

var provider = new oyXMLRPCProvider();
provider.onComplete = myOnComplete;
provider.onError = myOnLog;

provider.submit("process.php?txt=" + escape(txt));
}

function make_table(data){
var table = document.createElement('table');
table.className='sortable';
var tbody = document.createElement('tbody');
for(var i=0; i<data.length; i++ ){
var tr = document.createElement('tr');
//Create headers on first iteration.
if(i==0){
for(var field in data[i]){
var th = document.createElement('th');
th.innerHTML=field;
tr.appendChild(th);
}
tbody.appendChild(tr);
//Be sure to start a new row.
var tr = document.createElement('tr');
}
for(var field in data[i]){
var td = document.createElement('td');
td.innerHTML=data[i][field];
td.className=field;
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
table.id="table_" + Math.floor ( Math.random ( ) * 100 );
return table;
}

If you get everything linked up correctly, the result should be that when you press the button on the main page, a JSON object is pulled down asynchronously from the server and appended to the page as a table of data. Each such table is independently sortable without round trips to the server and back (and without your having to write sorting validation code to prevent SQL injection attacks, etc.). Of course, this does degrade poorly for browsers in which javascript is disabled. In any case, I’ve modeled one bit of functionality that’s pretty painless to implement using JSON, and I suspect that further work in this direction will turn up even more interesting results.

For more information on JSON, be sure to hit the JSON site.

technorati tags: , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s