Ext

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()
   });
});

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.

15 Responses to “Fun with Ext JS and Aptana Jaxer”

  1. Rich Waters » Blog Archive » Ext and Aptana Jaxer

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

  2. Frank

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

  3. Jarred Nicholls

    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.

  4. Web 2.0 Announcer

    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…

  5. Fun with Ext JS and Aptana Jaxer

    […] http://extjs.com/blog/2008/06/10/extjs-and-jaxer/  […]

  6. Behrang

    Poohleez! No JPG for screenshots!

  7. Совместное использование ExtJS и Jaxer | АяксЛайн.ру

    […] Источник: ExtJS blog. […]

  8. mdmadph

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

  9. Rich Waters » Blog Archive » Accepted into Aptana Cloud beta

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

  10. neon22

    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

  11. neon22

    thats been hammered by the parser :-(

  12. neon22

    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)

  13. neon22

    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.

  14. Marcus

    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?

  15. izmir evden eve

    Thank you for sharing…..

Leave a Reply

To prove that you're not a bot, please answer this question:



© 2006-2008 Ext, LLC