Placement of the PagingToolbar on a Grid

This morning I found I was courtesy copied by Ray Camden, on a reply that he was making to a message he had received from his Blog Contact form from Mike Knox. Mike was trying to find out if it was possible to place the PagingToolbar, used in cfgrid, at the top of the grid rather than the bottom. Ray had told Mike that he had Googled it and not found on obvious solution, and that he was CCing me for my feedback.

Like any padawan, it's pretty humbling for me to be asked advice from the Jedi Master. I've been taking Ray's advice on ColdFusion since the 4.x days, so I try to be pretty diligent when he includes me in helping others with their queries.

I've always held that the use of the CF Ajax components are primarily for rapid application prototyping. They are fantastic for putting up some very basic functionality, but when you need more advanced configuration it is then time to dig in, and go straight to Ext JS itself. Mike's question is a prime example of this. We have nearly no control over a cfgrid's configuration prior to render, and the configuration options that we do have (through the cfgrid and cfgridcolumn attributes) barely scratch the surface to what one can do with an Ext Grid. The PagingToolbar is a class object of Ext and, as such, you should be able to add it to any toolbar of a grid: top, bottom, or both. I fired up Eclipse, booted up my CF and Apache, and pulled up the Ext examples from my local copy of the latest 3.0 download. All of the examples that you can see in the Samples & Demos section of the Ext site are given to you in the download of the library, so that you can run them locally and pick them apart. So, my quest was on.

I went to the Paging Grid Example, and examined the source code of the paging.js file. I quickly found the configuration object for the paging toolbar:

view plain print about
1var pagingBar = new Ext.PagingToolbar({
2 pageSize: 25,
3 store: store,
4 displayInfo: true,
5 displayMsg: 'Displaying topics {0} - {1} of {2}',
6 emptyMsg: "No topics to display",
7
8 items:[
9 '-', {
10 pressed: true,
11 enableToggle:true,
12 text: 'Show Preview',
13 cls: 'x-btn-text-icon details',
14 toggleHandler: function(btn, pressed){
15 var view = grid.getView();
16 view.showPreview = pressed;
17 view.refresh();
18 }
19 }]
20 });

The PagingToolbar instance is then applied to the Grid, placing the object in the 'bbar' (bottom bar) attribute:

view plain print about
1// paging bar on the bottom
2 bbar: pagingBar

After seeing this in the online demo, I went to my local (3.0) demo to see if I could change it. The Ext team rewrote the demo for the upcoming 3.0 release, placing the instance initialization directly in the attribute:

view plain print about
1// paging bar on the bottom
2 bbar: new Ext.PagingToolbar({
3 pageSize: 25,
4 store: store,
5 displayInfo: true,
6 displayMsg: 'Displaying topics {0} - {1} of {2}',
7 emptyMsg: "No topics to display",
8 items:[
9 '-', {
10 pressed: true,
11 enableToggle:true,
12 text: 'Show Preview',
13 cls: 'x-btn-text-icon details',
14 toggleHandler: function(btn, pressed){
15 var view = grid.getView();
16 view.showPreview = pressed;
17 view.refresh();
18 }
19 }]
20 })

So, I changed 'bbar' to 'tbar' (top bar) and reloaded the page. Success! The PagingToolbar was now in the top toolbar of the Grid, and fully functional. After reviewing all of this, I decided to go a step further. Could you have two separate PagingToolbar configs on the grid? One at the top and one at the bottom? So, I tried this:

view plain print about
1// paging bar on the bottom
2 bbar: new Ext.PagingToolbar({
3 pageSize: 25,
4 store: store,
5 displayInfo: true,
6 displayMsg: 'Displaying topics {0} - {1} of {2}',
7 emptyMsg: "No topics to display",
8 items:[
9 '-', {
10 pressed: true,
11 enableToggle:true,
12 text: 'Show Preview',
13 cls: 'x-btn-text-icon details',
14 toggleHandler: function(btn, pressed){
15 var view = grid.getView();
16 view.showPreview = pressed;
17 view.refresh();
18 }
19 }]
20 }),
21 // paging bar on the top
22 tbar: new Ext.PagingToolbar({
23 pageSize: 25,
24 store: store,
25 displayInfo: true,
26 displayMsg: 'Displaying topics {0} - {1} of {2}',
27 emptyMsg: "No topics to display",
28 items:[
29 '-', {
30 pressed: true,
31 enableToggle:true,
32 text: 'Show Preview',
33 cls: 'x-btn-text-icon details',
34 toggleHandler: function(btn, pressed){
35 var view = grid.getView();
36 view.showPreview = pressed;
37 view.refresh();
38 }
39 }]
40 })

That's part of what I love about development, I get to play, experiment, have some (geek) fun. After refreshing the page, I now had two toolbars, at both the top and bottom of the page. Both worked perfectly, and stayed in sync during paging. That's what I love about the Jack Slocum and the Ext Team, they think about things like having more than one paging bar and how they would need to stay in sync, and they've already written it in to the library.

And so, on rare occasion, the student has the opportunity to become the master, though I'm sure there's still plenty more I can learn from Master Camden;)

CFQueryReader v1.1

A while back, Justin Carter contacted me about some updates he was making to the ColdExt, a wrapper for the Ext JS library for ColdFusion. He had been looking at my CFQueryReader, as a reader for ColdFusion's JSON data return, and had noticed that there was no support for the 'root' attribute that's associated with most JSON readers in Ext. CFQueryReader is specifically designed for use with Query objects of ColdFusion 8's native JSON return type.

When I first wrote CFQueryReader, I was replacing the CFJsonReader with something better suited to the array structure used in the ColdFusion JSON return of a Query Object, and really did a one-for-one port. So, I took a deeper look at the issue Justin wanted resolved.

I did a deep comparison of Ext's ArrayReader and JsonReader source code, following everything that was being accomplished. What I found was how it used an internal accessor method to pull certain information on demand. I was able to refactor the reader to now support all of the base level meta attributes that are currently available to the ArrayReader: id, root, successProperty, and totalProperty.

In the previous version of CFQueryReader, when defining your fieldsets you were also required to uppercase the entire value of the column names. This is no longer a requirement either, although casing is important in identifying your 'root' and 'totalProperty' attributes.

The download below includes the reader, as well as some sample code showing how to implement it. I also setup these sample in a subdomain to show it working (requires Firefox with Firebug for full effect). There is a fair amount of comment documentation directly within the CFQueryReader.js file. A big shout out to Justin, Adam Bellas, and a few others, for helping me out with the testing.

Ext.Direct: Details on Data Marshalling

One of the core focuses, in the development of Ext JS 3.0, is the marshalling of data services under a centralized location. The intent is to make for a more portable application, where you can have a single touch point for data I/O that could easily be switched from one platform to another.

This is done through the new Ext.Direct package of classes, and many have been waiting on some detailed information on what it is and how to use it. This morning the Ext Blog got an update: Ext JS 3.0 - Remoting for Everyone. This explains Ext.Direct fairly well, even giving you a sample app to learn from, some sample code, links to some pre-constructed routers for several platforms, as well as a link to the Remoting Specification to write your own custom routers. Aaron Conran, Senior Software Architect and Ext Services Team Lead, wrote the ColdFusion Router. That's fitting, as Aaron's a long time ColdFusion guy, having contributed to the ColdBox project back in it's early days.

I'm excited about what Ext.Direct can mean for Ext - ColdFusion based applications, and I'll be deep diving this integration soon. I'll be curious to see how I can integrate CFQueryReader into the mix. I have an update to that which I hope to get out in the next few days.