Fun with Ext JS and Aptana Jaxer
June 10, 2008 by Rich Waters
Shortly after Aptana released Jaxer, a new server-side JavaScript platform, I was able to spend some time running Ext JS code on the server-side. Jaxer facilitates a tightly knit integration between the client and server by allowing you to include JS code that will be run on the server, client, both, or as a server-proxy. The server-proxy allows Jaxer to wrap client and server-side communications up allowing either synchronous or asynchronous calls between the client and server. Jaxer provides a means for file, database or even socket access as one would expect from a server-side platform. Check out Aptana Jaxer for more details on how you can leverage your JavaScript skills on the server-side.
Jaxer Store and the Ext Grid
Download the complete source for these examples if you would like to setup the code on your own Jaxer server. This first example shows off a very simple wrapper around an Ext.data.Store and the corresponding Jaxer server code.
JaxerStoreServer.js contains a simple server side function that builds and executes a query. It assumes that you have already properly configured Jaxer’s config.js to point to the corresponding database. Notice that no server-side post processing is involved as it natively returns a JSON object.
function ExtJaxerProxy(params) { var fld = [], q = []; var fields = params.fields; for (var i = 0; i < fields.length; i++) { if (typeof fields[i] == 'string') { fld.push(fields[i]); q.push('?'); } else if (typeof fields[i] == 'object') { fld.push(fields[i].name); q.push('?'); } } var qp = fld; var query = 'SELECT ' + fld.join(',') + ' FROM ' + params.table; if (params.sortInfo) { query += ' ORDER BY ' + params.sortInfo.sort + ' ' + params.sortInfo.dir; qp.push(params.sortInfo.sort); qp.push(params.sortInfo.dir); } if (params.start && params.limit) { query += ' START ' + params.start + ' LIMIT ' + params.limit; qp.push(params.start); qp.push(params.limit); } return Jaxer.DB.execute(query); }
JaxerStore.js contains a very simple Ext data store to deal with connecting to Jaxer. This utilizes the built in ‘Async’ function that Jaxer wraps around all functions contained in a ’server-proxy’ include.
Ext.data.JaxerStore = function(config) { var params = Ext.apply({ fields : config.fields, table : config.table }, config.baseParams || {}); Ext.data.JaxerStore.superclass.constructor.call(this, Ext.applyIf(config, { reader : new Ext.data.JsonReader(Ext.apply({ root : 'rows' }, config.readerConfig), config.fields) })); ExtJaxerProxyAsync(this.loadData.createDelegate(this), params); }; Ext.extend(Ext.data.JaxerStore, Ext.data.Store);
Make sure both files are being included on your page, along with Ext.JaxerStore should be running in the client and JaxerStoreServer should be running as a ’server-proxy’. With the Jaxer store and server proxy in place, it’s only a matter of creating an instance of the store and hooking it up to a component that can use the data. Here we create the Jaxer store (notice that it now requires an additional table parameter), then we create a simple GridPanel and pass along our new-fangled JaxerStore.
Ext.onReady(function() { var store = new Ext.data.JaxerStore({ table : 'demo', fields : [ {name : 'name'}, {name : 'phone'}, {name : 'email'} ], readerConfig : { sortInfo : { sort : 'name', dir : 'asc' } } }); // create the Grid var grid = new Ext.grid.GridPanel({ store : store, columns : [ {header : "Name", sortable : true, dataIndex : 'name'}, {header : "Phone #", sortable : true, dataIndex : 'phone'}, {header : "Email", sortable : true, dataIndex : 'email'} ], viewConfig : { forceFit : true }, stripeRows : true, height : 350, width : 680, title : 'Jaxer Demo Grid', renderTo : Ext.getBody() }); });

Server-side Ext.(X)Template
This second example shows off actually running some Ext code on the server-side to take advantage of Ext’s template system. For this example I changed the JS includes for ext-base and ext-all to include a runat=”both” attribute so that the Ext library is available on the client and the server side. The html page includes a simple empty div with an id of ‘posts-main’ and a call to window.onserverload = loadPosts(). The loadPosts function simply selects some data from the ‘posts’ table in the database, then runs that data through the Ext.XTemplate. The XTemplate then loops through the rows array that Jaxer queries provide and will create the div/h2/p structure for each row. A quick formatting function lets us add a nice little ‘more’ link for those posts that are too long.
function loadPosts() { var vals = Jaxer.DB.execute('select id, title, body, perm from posts'); var tpl = new Ext.XTemplate('<tpl for="rows">', '<div id="post-{id}" class="post">', '<h2><a href="/jxtest/post/{perm}">{title}</a></h2>', '<p class="post-body">{body:this.formatBody}</p>', '</div>', '</tpl>', { formatBody : function(val, all) { if (val.length > 300) { return Ext.util.Format.ellipsis(val, 300) + '<a href="/jxtest/post/' + all.perm + '">Read More »</a>'; } else { return val; } } }); tpl.overwrite('posts-main', vals); }

In Conclusion
We can see that Jaxer lets developers leverage the hard work which has already been spent building client-side libraries on the server-side. These simple examples show off some of the true potential of utilizing the Ext JS framework on the server-side.
Download the source code for the examples in this post.

Posted on June 10th, 2008 at 2:08 am
[...] an Ext Data Store with Jaxer, and a nice example of using Ext.XTemplate on the server. Check out the post for a lot more detail and a bunch of code. Share and Enjoy: These icons link to social [...]
Posted on June 10th, 2008 at 3:18 am
Great fun and this is a nice match, I think.I’ve invested on this topic for long while.
Posted on June 10th, 2008 at 8:21 am
Very exciting. I’m always a skeptic about these platforms because of their potentially horrible performance, so I’m curious if anyone’s benchmarked Jaxer yet. Running Mozilla on the server kind of scares me a little…Webkit actually would have been a better choice if they were starting the project today - so much faster w/ Javascript and DOM manipulation.
Posted on June 11th, 2008 at 5:14 am
Ext JS and Aptana Jaxer
[...]Jaxer allows developers to leverage existing Javascript knowledge to develop server-side code for web applications. This article shows off some slick demos of Aptana Jaxer running the amazing Ext JS Javascript library on the server side. Full exam…
Posted on June 11th, 2008 at 5:23 am
[...] http://extjs.com/blog/2008/06/10/extjs-and-jaxer/ [...]
Posted on June 11th, 2008 at 10:11 am
Poohleez! No JPG for screenshots!
Posted on June 12th, 2008 at 8:08 pm
[...] Источник: ExtJS blog. [...]
Posted on June 18th, 2008 at 11:19 am
Hey, not bad — Jaxer seems neat, and I wouldn’t mind trying it once its development has stabilized.
Posted on June 22nd, 2008 at 1:20 pm
[...] after my recent article playing around with Ext on the server side with Jaxer, I figured I would check out Aptana’s [...]
Posted on July 5th, 2008 at 2:41 am
If I add the following at the head of grid.html, I should be able to populate an initial db also.
But it doesn’t work for me. I am a newbie here
It runs in Jaxer shell (see bottom piece of code).
What - simple - thing am I doing wrong - what have I failed to understand ?
function init(){
var db = new Jaxer.DB.SQLite.createDB({
PATH: Jaxer.Dir.resolvePath('dummy.sqlite')
});
db.execute("CREATE TABLE IF NOT EXISTS demo (name, phone, email)");
var myData = [
['John Smith', '021-451-901', 'js@js.com'],
['Billy Apple', '8200-11-250', 'ba@apple.com'],
['Pidgeon', '2342-414124', 'bpid@greece.biz'],
['Boy Wonder', '12386-34234', 'bw@sentinel.com']
];
if (db.execute(’SELECT count(*) FROM demo’).singleResult
Then I have added init(); to the OnReady function.
This works in the Jaxer Shell:
var myData = [
['John Smith', '021-451-901', 'js@js.com'],
['Billy Apple', '8200-11-250', 'ba@apple.com'],
['Pidgeon', '2342-414124', 'bpid@greece.biz'],
['Boy Wonder', '12386-34234', 'bw@sentinel.com']
];
var db = new Jaxer.DB.SQLite.createDB({
PATH: Jaxer.Dir.resolvePath(’dummy.sqlite’)
});
db.execute(”CREATE TABLE IF NOT EXISTS demo (name, phone, email)”);
for (var i = 0; i
Posted on July 5th, 2008 at 2:43 am
thats been hammered by the parser
Posted on July 8th, 2008 at 4:28 am
Worked it all out - and it works just fine.
But I added Aptana Cloud and moved up to a newer version of Jaxer.
No longer works.
Specifically gets jammed up and does not return when calling:
ExtJaxerProxyAsync(this.loadData.createDelegate(this), params);
Any ideas ? ( using Ext 2.1)
Posted on July 8th, 2008 at 4:42 am
Should anyone else be looking for the answer to this its:
ExtJaxerProxy.async(this.loadData.createDelegate(this), params);
change of syntax to avoid polluting namespace.
Posted on July 29th, 2008 at 5:25 am
Jaxer sounds very interessting. Do you think it’s possible to run ExtJS on IE5 (or other old browsers) using Jaxer? If so, how could that be done theoratically?
Posted on August 5th, 2008 at 8:50 am
Thank you for sharing…..
Posted on October 11th, 2008 at 11:15 pm
@neon22
The Jaxer Async functions are no longer injected into the client namespace, change the reference in JaxerStore.js to ExtJaxerProxy.async(…) and it will work again. the DB needs to be created and populated also.
cheers
Posted on October 21st, 2008 at 5:11 am
thanks..
Posted on November 3rd, 2008 at 3:56 am
thanks..
Posted on November 11th, 2008 at 4:45 am
thanks.
Posted on November 13th, 2008 at 4:34 am
thanks.
Posted on November 13th, 2008 at 5:29 am
thanks.