Introducing JsTable

by Naneau

I stumbled across Jester a little while ago. Jester is a Javascript library built on top of Prototype for working with Ruby on Rails (RoR) ActiveResource. And it made me think. I am not a RoR man, I may turn into one in the future, but for now I’m quite happy using PHP. Since the Zend Framework has become quite stable, I’ve used that for most of what I do. So obviously Jester isn’t for me, but I still like the philosophy behind it. In a web 2.0 world linking server and client side code is very interesting, for numerous reasons.

In applications designed with the Zend Framework most models extend Zend_Db_Table. So on the client side you’d want to be able to work with something similar. I decided to create a set of classes that mimic the behaviour of Zend_Db_Table, Zend_Db_Table_Rowset and Zend_Db_Table_Row in Javascript. This way you can work with the ‘same’ models both on the server and the client side.

Enter jsTable. JsTable is a Prototype class that allows you to work with Zend_Db_Table objects directly from Javascript. It has mechanisms for basic communication with a server that holds the ‘real’ models. It gets it’s information in Json, either synchronously or asynchronously.

Let’s assume we have an application that has both users and posts, like a forum. You want to find a post that has an id of 1, and edit it’s title. But because you are a hip young webdeveloper you want to be able to do this via Ajax, just because you can!

In PHP:

1
2
3
4
5
6
7
$mP = new Post();
//class Post extends Zend_Db_Table
$rowset = $mP->find(1);
//find returns an object of the class Zend_Db_Table_Rowset
$row = $rowset->current();
$row->title = 'This is the new title';
$row->save();

In Javascript, with JsTable:

1
2
3
4
5
6
var mP = new JsTable('Post');
var rowset = mP.find(1);
//find returns an object of the class JsTableRowset
var row = rowset.current();
row.title = 'This is a new title, but set in JavaScript';
row.save();

Now that’s pretty similar! Let’s do another example, creating a new Post:

in PHP:

1
2
3
4
5
$mP = new Post();
$row = $mP->fetchNew();
$row->title = 'A title';
$row->content = 'This is my new post!';
$row->save();

in Javascript:

1
2
3
4
5
var mP = new JsTable('Post');
var row = mP.fetchNew();
row.title = 'Another title';
row.content = 'I don\'t write very interesting posts';
row.save();

Again… Pretty similar, and pretty easy too!

Now before you start using buzzwords. This isn’t ajax. It doesn’t use xml, and it isn’t asynchronous. The find method will accept a second parameter, which, if given, will act as a callback, making the whole thing asynchronous. Depending on the circumstances you may or may not want to use it. Synchronous requests will freeze up the browser, but asynchronous requests will require additional logic. The save method for a single row also has an optional callback parameter, which will get a boolean true on succes, and false on failure.

1
2
3
4
5
mP.find(1, callbackFunction);
function callbackFunction(rowset) {
//will get called when find() has finished
//do something with the rowset
}

Another interesting thing is that JsTableRowset mixes in prototype’s enumerable, so you can do something like this:

1
2
3
4
5
6
7
var mU = new JsTable('User');
var ids = $R(1,50).toArray();
//array of integer 1 to 50, lazy prototype style!
var rowset = mU.find(ids);
rowset.each(function(user){alert(user.name);});
//50 irritating alert boxes, with 50 usernames
//(assuming there are 50 corresponding rows)

The Javascript has documentation, so it should be fairly easy to understand it’s basic functionality, especially since it mimics behaviour you’re probably already familiar with. I have also included a sample controller, for use with JsTable.

I would like to warn you though, there are some serious security issues with the provided controller. Please don’t use it without modification, read up on Zend_Acl if you’re not sure about access restriction. I have also written my own little tutorial about securing JsTable

If this sounds interesting to you, why don’t you give it a try:
JsTable.zip