Blog

Fun with Ext JS and Aptana Jaxer

June 10, 2008 | 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()
   });
}); 
 
Jaxer Grid

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 &raquo;</a>';
                   } else {
                       return val;
                   }
               }
           });
 
   tpl.overwrite('posts-main', vals);
}
 
Jaxer Template

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.

There are 40 responses. Add yours.

Rich Waters » Blog Archive » Ext and A

4 years ago

[...] 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 [...]

Frank

4 years ago

Great fun and this is a nice match, I think.I’ve invested on this topic for long while.

Jarred Nicholls

4 years ago

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.

Web 2.0 Announcer

4 years ago

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…

Behrang

4 years ago

Poohleez! No JPG for screenshots!

mdmadph

4 years ago

Hey, not bad—Jaxer seems neat, and I wouldn’t mind trying it once its development has stabilized.

Rich Waters » Blog Archive » Accepted

4 years ago

[...] after my recent article playing around with Ext on the server side with Jaxer, I figured I would check out Aptana’s [...]

neon22

4 years ago

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:
<code>
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

neon22

4 years ago

thats been hammered by the parser :-(

neon22

4 years ago

Worked it all out - and it works just fine. grin
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)

neon22

4 years ago

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.

Marcus

4 years ago

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?

izmir evden eve

4 years ago

Thank you for sharing…..

davey

4 years ago

@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

raf

4 years ago

thanks..

brülor

4 years ago

thanks..

boya

4 years ago

thanks.

Burun Estetigi

3 years ago

Great fun and this is a nice match, I think.I’ve invested on this topic for long while.

Patrick

3 years ago

Anyone have an example on using the gxt and jaxer with JSON?

otel

3 years ago

Thanks

medyum

3 years ago

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.  Medyum

HD LCD monitor

3 years ago

thanks for this.

aöf

3 years ago

Very good, congratulations article

cinsellik

3 years ago

I am grateful to you for this great content.

siki?

3 years ago

Very good, congratulations article

l

siki?

3 years ago

I am grateful to you for this great content.

aöf

ssk sorgulama

3 years ago

Hey, not bad — Jaxer seems neat, and I wouldn’t mind trying it once its development has stabilized.

zerrin egeliler

3 years ago

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

medyum

3 years ago

Great fun and this is a nice match, I think.I’ve invested on this topic for long while.

komik videolar

3 years ago

thanks for this.

araç sorgulama

2 years ago

Hey, not bad — Jaxer seems neat, and I wouldn’t mind trying it once its development has stabilized.

Söve

2 years ago

Great post.

Charles

1 year ago

Jaxer seems like a really smooth javascript program.

Keylon

12 months ago

Posts like this brhigten up my day. Thanks for taking the time.

Hollie

11 months ago

This makes everything so comepltely painless.

Comments are Gravatar enabled. Your email address will not be shown.

Commenting is not available in this channel entry.