Ext JS 4.1 Grid: Part1: Basic Config

Many moons ago, I wrote a series on My First Ext JS Data Grid. It was very popular. In fact, it got me the gig co-authoring two books on Ext JS and spawned an open source project targeted at integrating Ext JS with ColdFusion. But, I did that series back in 2007, using Ext JS 1.1 (maybe?), and an update is long overdue.


CFQueryReader 2.0: Site and Demo Updates

Note: I mistakenly posted this under the wrong title. I must get more sleep ;)

I finally got around to a major overhaul of the CFQueryReader site, including all new demos and documentation of the latest build for Ext JS 4.x.

The new demos for Ext JS 2.x and 3.x include links to legacy API's for both versions of the library. The 3.x version includes an example of using Ext Direct, and the new 4.x demo includes paging data grids.

(Big thanks to Loiane's Ext JS 4 First Look, which showed me very quickly how dead simple Ext JS grids and data stores have become.)

I have not yet tested CFQueryReader with Sencha Touch, but it should work. Any feedback just let me know.

2011 In Review, and the View for 2012

My, how time flies when you're having fun! It seems like only yesterday that I was welcoming in 2011, and now we're here a year later. So many things have happened in the last year, and rereading that post I see that I missed some things I should've done, but let's take a look in retrospect.

I wrote 27 blog posts in 2011. This is nothing, compared to guys like Ray Camden or Ben Nadel, but for me it was quite a bit, especially when you consider that between March and August I released only one post. Very early in the year, I began a series on creatingmany sites with one codebase. In the process, the series has evolved to contain a fairly detailed primer in ColdFusion application architecture (because of it's importance to this process), has currently spanned 8 separate posts, and was even referenced by Sean Corfield in his great presentations on the same topic. 2012 will see the completion of that CF app discussion, and gradually move it back to the MSOC topic itself, as there is still a ton to talk about there, and a lot of interest in the topic. I also began a series on the jqGrid JQuery plugin. jqGrid is another Data Grid visualization tool (I have now written about three, including Ext JS and DataTables), and is a clear choice for those who must use JQuery. (To be fair, JQueryUI is working on a grid component, but they are still behind the curve, and way behind Sencha.) Finally, one common thread seen in the majority of my posts, is how much I've embraced cfscript. I wrote a lot of things, on a variety of topics, but most of my code examples were pure scripted examples.

Now let's talk about some other departures from the norm for Cutter.

You did not see a lot of content around Ext JS. In fact, I stopped writing Ext JS books. This is not, in any way, a reflection on my feelings for Ext JS. I still believe that Sencha has built one of the best client-side libraries for web application development. In evaluating the overall ROI, I realized that I was writing more for the community than the money, and that my reach was greater through my blog, while giving me flexibility on when and what I deliver from a content standpoint. That said, I didn't have a single project this year that used Ext JS, so had very little time to experiment and write about it. This year, I'm going to expand on a personal project, and get back to some great Ext JS content for my readers.

You, also, did not see me speak at any conferences this past year. Nor at any user group meetings. This wasn't because I didn't want to, but because of some more personal reasons. I'm not going to go in depth here, other than to say that I've had some long standing health issues that required me to have some surgery done on my mouth. (Mark Drew is making a joke right now...) Aside from the fact that this has been very costly (chewing up any conference/travel budget), it also meant that my speech has been affected for a good part of the year. Thankfully this experience is (mostly) over now, and I hope to get back to presenting sometime this year. Any user group looking for a speaker this year, please contact me through the Contact link on this blog.

One group I am hoping to speak to this year is the Northeast Florida CFUG. I have to call Mike back, but he's looking to get things kicked off again, and I want to help it be successful. If you're in or around the Jacksonville area, make sure to keep an eye on the site for upcoming events.

One other thing I'm looking to do is to migrate all of my projects into GitHub. I've been using Git at work, and I am loving it, and I think combining GitHub with RIAForge is a great way to promote the terrific technologies we work with every day. I will make the time, I promise.

This comes to the final discussion of this post, Adobe. I again had the pleasure of being an Adobe Community Professional this past year. Due to my health issues, I didn't get to do everything I would've wanted to this year, but I've tried to be a good supporter. There are some fabulous things coming in ColdFusion Zeus and, by extension, to ColdFusion Builder as well. There has been a lot of hub-bub over Adobe's communications flubs regarding Flash, mobile, and Flex. I've avoided much of the discussion, other than to say "be patient and watch". Flash isn't going away, and neither is Flex. HTML 5 is a beautiful thing, if you aren't developing desktop browser applications (i.e. You're only writing for mobile/tablet development). There, that is my whole contribution to that discussion. Give it a rest.

2012 will be a fantastic year. Set yourself some clear, definable goals. Break them down, step by step, and write the steps down on paper. Each successive step, print out in large letters and place it somewhere where you will see it each and every day. Set yourself up to succeed, and you will. Have a great year, everyone, and I can't wait to hear what you have planned for 2012.

Ext Conference: Day 1

Day 1 of the Ext JS Conference has been busy. Last night I had dinner and drinks with Jeff, a really nice guy who heads up development for a group writing web based interfaces to hardware appliances. Turns out Jeff is also the guy who introduced JavaScript to Douglas Crockford, who was today's keynote speaker. Douglas made sure to recognize Jeff at the beginning of his keynote, which I thought was a nice nod to the guy who helped give him direction in his career. Douglas ran us through a brief history of hypertext, the evolution of the web, JavaScipt, and the browser wars, before touching on the future of the web, some of the things in the new JavaScript specs being worked on through ECMA, and the fact that none of it would matter for years until the browser manufacturers would implement it. He did give props to Flash, AIR and SilverLight for trying to further the web experience where it has lagged so much over the years. He also spoke about the pitfalls of security in Web 2.0 applications, and the primary culprits of those issues (the browser manufacturers).

Before I go a whole lot further, let me tell you that the conference center, and their service to us, is fantastic. Held at the Ritz-Carlton Orlando, the location is beautiful with it's palm lined drives, a well groomed golf course winding around several 'water traps', and a huge pool with several fountains. The food has been exceptional, with an incredible meal at lunch, complete with salad, brazed chicken, and desert with complete table service (this as part of the conference). No buffet sandwhiches here, though a breakfast buffet would have been nice before that 830 session this morning. My room is about half the size of the one I had at the Hotel Rouge last year for WebManiacs, but it is very comfortable and service keeps it nice. The shower did flood the entire bathroom this morning and the in-room coffee is horribly weak (and small), but everything can't be perfect. I've also carried on my conference tradition of bringing a sinus infection with me, which is keeping me from the after-session activities this evening, but the concierge was able to get me covered with some NyQuil for the evening to try to knock this stuff out of me.

Aaron Conran, fellow ColdFusion developer and one of the original contributors to ColdBox, delivered the session covering what has changed and what's new within the 3.0 release, which is officially released tomorrow by Jack Slocum during his keynote. A great deal of work has been spent to make the upgrade fairly painless, with attention payed to backwards compatability, improvements to overall memory management (always important), and an eye towards keeping the code lean and mean, doing what is necessary to keep code size to a minimum and eliminate any unnecessary bloat. Menus and Toolbars have been converted into true Container objects, and the only significant markup changes appear to be to the Button objects.

There are several new visual components, maintaining the professional feel and consistency that has made Ext JS so compelling. Two that attracted a great deal of attention were the ListView and the Buffered Grid View. Sometimes you want the basic view afforded by a Grid, without having the need for (or the overhead of) things like drag and drop column ordering, sorting, and the like. The ListView gives you a basic grid style layout without all of that overhead, and a very trim DOM footprint as well, providing your view without unnecessary code bloat and browser memory overhead. The Buffered Grid View is a full Grid implementation that allows the browser to only render DOM for records in actual view, plus a few extra to make smooth transitions on scrolling, that automatically adds and removes DOM items when scrolling through your recordsets. The memory management improvements with this, and other changes, are very nice to see. Like the new .mon(), or 'managed on', methods that allow you to bind events in a temporary fashion, getting a proper cleanup from browser memory when that component gets destroyed. This was actually a method of Ext prior to it's 1.0 release, and has been heavily requested for this return.

Being the server-side guy that I've been for the last decade, the important new components came to the Ext.data package, with the addition of the Ext.data.Direct and Ext.data.DataWriter classes. Direct provides the ability to marshall your remote service call definitions into one container, calling your Ajax data requests from a centralized location with the ability to make multiple commands through a single Ajax request as well as call listeners on specific actions performed by Direct. Chris Scott did a presentation on Direct this afternoon, explaining how the developer has to create a server side Router to which Direct can attach it's requests, and showing us all a nice and very simple example (even if it was written in Ruby). The Ext Team provides a Reference for development of Routers in a number of server-side languages, including ColdFusion, PHP, Ruby, and .NET. The DataWriter class, covered in more depth in a future session, does for POST requests what the DataReader does for your GET requests, allowing a developer to define your routing of requests to send data back to the server. The combination of these classes with the existing classes of the Ext.data package really improves upon the power of using Ext with any server-side technology.

I was able to see the presentation on the Direct class because of a snafu with a scheduling change of the presentation of the Ext.air package. Originally these two sessions were the one conflict in my schedule, but they moved the Ext.air presentation session up a time slot (a change I didn't know of until after the fact) which allowed me the opportunity to sit in on Chris's session. Luckily the presentations are being recorded and are supposed to be available online after the conference. I'm glad they're doing this, since I had to leave during my final session of the day, on Ext.Core, due to the sinus issues that progressively worsened through the day. The Ext.air session is one I am very looking forward to watching.

The members of the Ext Team are a great group of guys. Abe, again, congratulated me on the book, and invited me to sit in on the Industry Experts panel tomorrow. I've had several people say they wished they had brought their copies of the book so Shea and I could have signed them for them. One attendee asked why PackT didn't have a booth setup somewhere, which is when I first noticed that their don't appear to be any outside sponsors for the conference. Ext appears to have financed the conference solely through the registration of the 200+ attending, which is pretty impressive considering the facility and it's services. On another note, ColdFusion has been publicly mentioned in several presentations, and with so many different server-side programmers represented here it is refreshing to hear so many comment that they should give ColdFusion a hard look.

And with that, I'm going to pack it in for the evening and pray that the NyQuil does it's job to kick the junk out of my head. Tomorrow looks to be an exciting day, with Jack's keynote releasing Ext 3.0, sessions on User Experience Design, Theming, and Performance Optimization. I'll be posting updates to Twitter and my Facebook profile throughout the day. If you're here, make sure to come up and say hi.

Upcoming Book: Learning ExtJS

I've been rather quiet for quite a while now. I have a rather large side project I've been working on, written entirely with an ExtJS front-end and ColdFusion on the back-end. I'm hoping to get that into a QA phase in the next week or two. I also just celebrated my 39th birthday, my 8th wedding anniversary, my daughter is the rock star of the 1st grade (pulling straight A pluses in every category), and the holiday's are coming.

On top of everything else, I'm putting the final touches on Learning Ext JS, to go to press at the end of the week/beginning of next, and due out in December. I've stayed relatively quiet on this, as I wanted to wait until PackT, my publisher, officially released information on the book. Let me start by saying that a few years ago I never would have thought I'd be doing this much client-side development again. And I definitely wouldn't have imagined me contributing to a book about client-side development.

I began looking at ExtJS quite a while back, while contemplating how to "jazz up" and modernize some dated interfaces I was supporting. I thought that ExtJS was an exceptionally well thought out library of rich, consistant components and functionality. While I use JQuery almost exclusively for DOM queries and manipulation, I really didn't find enough consistency in the visual plugins at the time (this has improved with the latest round of the JQuery UI plugins). I began to learn of the real power of ExtJS, and became an even bigger fan when it was announced that Adobe was including it in Scorpio, the codename for ColdFusion 8, Adobe's first implementation of the ColdFusion web application platform since it's acquisition with the Macromedia merger. Sweet! A total win-win for me.

Back in June, PackT contacted me. It seems they had started to develop a book, but the primary author, Shea Frederick, had gotten bogged down in other commitments before being able to complete the project. Some Googling on their part led them to Colin Ramsay and myself, through Cutter's Crossing. So they contacted me to find out if I was interested. The timing on this was awful. I was just starting the previously mentioned side project, my daughter was on her very first summer vacation, and just a lot of things going on. But it was too good to pass up. Aside from the fame and glory (yeah, right!), I knew that there weren't any other books out there on ExtJS, and it would be an excellent book to get out there for all the people trying to learn this exciting library. After talking the pros and cons with Aaron West, and getting sign off from my family, I finally contacted the Jedi himself, Ray Camden, to get some info on the writing process. We talked about time (a lot), commitment (more), and fame (maybe a little) and fortune (nearly none). I finally went ahead and said I would do it.

So, here it is almost six months later. I took on the final three chapters of the book: working with data stores (think like browser cached data table sets), extending Ext objects to build your own custom components, and the book wrap-up, which covers all the little stuff many people miss because they aren't typically visible. Only one chapter has any server-side code (the data stores). PackT originally wanted to convert my ColdFusion examples to PHP, to conform with the rest of the book. This morning the publisher told me that they want to keep my ColdFusion examples, to show that the ExtJS library can work with any server-side technology.

So, they're taking pre-order now, just in time for the holidays. Let me know what you think.

CF8 Ajax Grid: Showing the TotalRecordCount

This morning, Paul Stewart submitted an interesting question to the CF-Talk List:

"Hi, I have been using the CFgrid tag in CF8 (format HTML, bound to a cfc), and i have got it do almost all that i need it do (see below). Except that i don't know how to get access to the TOTALROWCOUNT figure that i can see in the debugger returned from the CFC , and also be able to display that figure either on the bottom of the grid itself (using ext.toolbar???), or even above it on the page using another ajax method??.

I need to do this show the user amount of records returned from his/her search. i.e 'your search returned x number of records.' From reading Ray Camden's blog I know i have to use the underlying Ext library that the cfgrid tag is based on, and i have used his solution to format some columns in the grid (nice one Ray). But i am not really getting anywhere (hopelessly bamboozled) with the records returned figure...."

This is a great question! And so easy to implement using the underlying ExtJS 1.1.1 component architecture of the ColdFusion 8 Ajax controls. The grid component already knows what the beginning and ending rows are for the page, and the total number of rows, so it's just a matter of getting them to display on the PagingToolbar. Paul had included a little code in his post, the primary piece of which (as far as we're concerned) is his formatgrid() function:

view plain print about
1formatgrid = function() {
2 mygrid = ColdFusion.Grid.getGridObject('ad');
4 cm = mygrid.getColumnModel();
5 cm.setRenderer(3,myf);
6 cm.setRenderer(5,myf);
8 mygrid.reconfigure(mygrid.getDataSource(),cm);

Basically he has most of the pieces that he needs already. He needs a reference to his data.Store object, which we'll add right after he gets his grid instance:

view plain print about
2    mygrid = ColdFusion.Grid.getGridObject('ad');
3    ds = mygrid.getDataSource();
4    ...

Then, after his renderers, but before his reconfigure(), we'll get a reference to his grid's FooterPanel to redefine the PagingToolbar:

view plain print about
2    cm.setRenderer(5,myf);
3    // Get the Footer
5    var gridFoot = mygrid.getView().getFooterPanel(true);
6    // Create a new Paging Toolbar
8    var paging = new Ext.PagingToolbar(gridFoot,ds,{
9        pageSize:25, //number of records displayed in grid
11        displayInfo:true,
12        displayMsg:'Displaying records {0} - {1} of {2}',
13        emptyMsg:"No records to display"
14    });
16    // reconfigure the grid
18    mygrid.reconfigure(ds,cm);
19    ...

Hey! Reload the page and what do you get? An adjusted toolbar, giving Paul exactly what he was looking for, the current record from - to and the total number of records returned. Though I've used this before, I wanted to note that this code is almost an exact copy of the example code included in the ExtJs 1.1.1 API documentation. There is a ton of untapped potential within the underlying Ext framework. With a little research you may be surprised what you can accomplish.

ExtJS 2.0 Grid Gotcha

I recently upgraded all of my former ExtJS code to utilize the updated 2.0 library. There are a lot of fantastic changes and additions here, but I did run into one or two snags. In a previous post I showed how to use Event Handlers and Item Renderers with the ColdFusion 8 Ajax implementation of the ExtJS 1.1.1 data grid. It works very similarly with a straight (non-CF) implementation, whereby I had defined an unbound column, in my ColumnModel, and applied a renderer to it so that an icon would appear with an onclick event attached to the cell click. It's a very straight forward process, that immediately broke with the 2.0 library. It took me a little bit of playing around, but I finally discovered what appears to be either a bug in the library, or a glitch in the documentation.

What made this column previously 'unbound' was the fact that no dataIndex was set to the column. It wasn't required. Acoording to the 2.0 documentation, the attribute is still supposed to be optional. However, when trying this with 2.0, I found that I would continually get an error. Only after duplicating my dataIndex (I applied my ID query column to the dataIndex, the same as my ID column), and then using the renderer to overwrite, did I finally get my working grid. It's a bit of a hack, but it did the job.

It's a small gotcha, but a gotcha none the less, so I wanted to let ya'll know. As I said before, there are some fantastic changes in the new 2.0 implementation, and already some nice plugins being developed by the community. Well worth taking a peek under the covers.

CF8 Grid Renderers and Events Source

I had several people ping me for some sample code for my CF8 Ajax Grid: Renderers and Events posting, on (what else) custom cell renderers and event listeners. I have just uploaded a zip of commented source code to that post. Just click the 'Download' link at the base of the post for all the source code goodness:)

My First ExtJS DataGrid Pt 7: Custom Cell Renderers

So, it's been awhile. No, I haven't forgotten you, I've just been busy with a lot of things. One of which has been implementing a new ExtJS DataGrid in a project I'm working on. Sure, there's a lot more going on, but that's becoming a nice front end piece. As previously promised, I want to look at a renderer.


My First ExtJS DataGrid Pt 6: The Grid

Alright, rolling right along. Last tutorial (see the bottom of this post for a complete listing) we covered the initial setup of our ColumnModel, which is telling our DataGrid what the basic layout of our grid columns will be and to which fields of our DataStore each column will be mapped to. Now it's time to actually instantiate our grid.

So, the first thing we have to do is create our Grid object and tell it which html element will be our grid within our page. Basically we'll tell the function the ID of the div element, what DataStore object to use, and which ColumnModel object to use.

view plain print about
1// create the editor grid
2var grid = new Ext.grid.Grid('topic-grid', {
3 ds: ds,
4 cm: cm
5 });

This is it in it's most basic form. We're going to stay away from any fancy stuff for now, and get to selection models and stuff in a later post. Let's add to it a little bit by stating that the grid may be resizable.

view plain print about
1// make the grid resizable, do before render for better performance
2var rz = new Ext.Resizable('topic-grid', {
3    wrap:true,
4    minHeight:100,
5    pinned:true,
6    handles: 's'
8rz.on('resize', grid.autoSize, grid);

That will make the grid resizable, and should be declared prior to rendering the grid. Rendering the grid is our next step, and way simple.

view plain print about
1// render it

Can't get much easier than that. Going back to the resizable for a second, don't ask, I don't know. Easiest one for me to figure on sight is the minHeight attribute, but I haven't reviewed the API enough to know what all is going on. If you figure it out before I do then leave a comment. Next we'll need to add the paging tool bar to the footer. We'll get the footer, then add the paging toolbar.

view plain print about
1var gridFoot = grid.getView().getFooterPanel(true);
3// add a paging toolbar to the grid's footer
4var paging = new Ext.PagingToolbar(gridFoot, ds, {
5 pageSize: 25,
6 displayInfo: true,
7 displayMsg: 'Displaying users {0} - {1} of {2}',
8 emptyMsg: "No users to display"

Notice the arguments of the PagingToolbar() function, the footer object, the DataStore object, and a JSON object with attributes of the pageSize (number of records), whether to display data set info, the message of the count, and a message to display should no records be returned.

The final step here is to load the DataStore. Once this is done you will have a complete, basic DataGrid for display.

view plain print about
1// trigger the data store load
2ds.load({params:{start: 0, limit: 25}});

Notice here the 'params'. These are name/value pairs that are passed, via post, whenever you request the next page of your data, with these values being your initial request (starting at row 0, returning 25 records). If you go back and look at your pagingService.cfm (included in the download) you'll see where these values are used.

So, that's the end of this post. You now have a basic DataGrid. In our next tutorial we'll start to style some things, and show you how to implement a custom 'renderer' for a specific column's data.

More Entries