So, I was doing a real quick, down and dirty form and results app for something internal. Way temporary, with little scale-out, I wrote a form and processor, then used the CF8 DataGrid for the results display. Problem was, two of the fields were textareas that could contain a lot of info, so I needed a quick way to show and expanded details set. Now, had I been using ExpanderRow plugin, but this was just quick implementation prototyping type stuff.

What I needed was a column of icons that I could then link to a CFWindow with the total display. Now, I have to use a Cell Renderer to place the image in the empty column, but first I need the column.

view plain print about
1<cfgridcolumn name="Details" header="" width="25" display="true" />

After that, I create a basic Cell Renderer:

view plain print about
1setDetailButtonRenderer = function(grid,cm,col){
2        cm.setRenderer(col,function(value,p,r,ind){
3            var retVal = "<img src='/resources/images/icons/book_link.gif' width='16' height='16' alt='Details' />";
4            return retVal;}
5        });
6        grid.reconfigure(grid.getDataSource(),cm);
7    }

This didn't entirely work out, as it placed the image in every row, even if there wasn't a record. So, time to improvise. I adjust to see if there's value for a cell in this row's 'record', to determine whether I need the image.

view plain print about
1setDetailButtonRenderer = function(grid,cm,col){
2        cm.setRenderer(col,function(value,p,r,ind){
3            var ds = grid.getDataSource();
4            var theRecord = ds.getAt(ind);
5            if(theRecord.get('TS') != null){
6                var retVal = "<img src='/resources/images/icons/book_link.gif' width='16' height='16' alt='Details' />";
7                return retVal;
8            }
9        });
10        grid.reconfigure(grid.getDataSource(),cm);
11    }
12
13    function showRecWin(){
14     ColdFusion.Window.show('winDetails');
15 }

Alright, to call the renderer into play I have an init method that is fired by the CF ajaxOnLoad() method.

view plain print about
1init = function(){
2        var repGrid = ColdFusion.Grid.getGridObject('reportsGrid');
3        var repCM = repGrid.getColumnModel();
4
5        setDetailButtonRenderer(repGrid,repCM,8);
6    }

Now we're halfway there. Next I need to get a 'click' on the image cell. You do this by accessing the underlying Ext functions of the Grid object itself, for which you already have a reference (repGrid).

view plain print about
1init = function(){
2        var repGrid = ColdFusion.Grid.getGridObject('reportsGrid');
3        var repCM = repGrid.getColumnModel();
4
5        setDetailButtonRenderer(repGrid,repCM,8);
6
7        repGrid.on('cellclick',function(grid,rowIndex,columnIndex,e){
8            if(columnIndex==8){
9                
10            }
11        });
12    }

We are configuring an on cellclick function here, which is really a listener on the row itself. We further narrow it to only perform action if the column that the cursor was in 'on click' was our Details column, which is the 9th column of our grid, including hidden columns (remember that this uses a JavaScript array, which starts with zero, so the column you reference is always column count minus one).

Next thing we need is a quick modal pop-up for our 'Details.' CFWindow makes a great candidate for this.

view plain print about
1<cfwindow name="winDetails" title="Details" draggable="false" resizable="false" initShow="false" height="600" width="600" />

It's invisible when initialized, because we only want to show it 'on click'. We need a quick method for 'showing' the window.

view plain print about
1function showRecWin(){
2     ColdFusion.Window.show('winDetails');
3 }

We can now reference this in our 'on click' function.

view plain print about
1repGrid.on('cellclick',function(grid,rowIndex,columnIndex,e){
2        if(columnIndex==8){
3            showRecWin();
4        }
5    });

OK, we get our window, but now we need some data. Now, I could do an ajax call for the data, but it's already in my cell. It's just too long to easily display in the grid. Rather than do another server call, I'll just query the grid's Data.Store for the information.

view plain print about
1repGrid.on('cellclick',function(grid,rowIndex,columnIndex,e){
2        if(columnIndex==8){
3            showRecWin();
4            // This empties out any previously displayed content
5            document.getElementById("winDetails_body").innerHTML = "";
6            var ds = grid.getDataSource();
7            var theRecord = ds.getAt(rowIndex);
8            var valPurpose = theRecord.get('FEATUREPURPOSE');
9            var valFunction = theRecord.get('FEATUREFUNCTION');
10            document.getElementById("winDetails_body").innerHTML = "<b>Purpose:</b><br />" + valPurpose + "<br /><br /><b>Function:</b><br />" + valFunction;
11        }
12    });

Really simple, as long as you remember that ColdFusion's creation of the grid's ColumnModel will uppercase all of your cfgridcolumn's name attributes.

That's it. Really doesn't take a whole lot. A little digging in the documentation for the 1.1.1 version of the ExtJS library will give you a ton of information.