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.
After that, I create a basic Cell Renderer:
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.
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.
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).
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.
It's invisible when initialized, because we only want to show it 'on click'. We need a quick method for 'showing' the window.
2 ColdFusion.Window.show('winDetails');
3 }
We can now reference this in our 'on click' function.
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.
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.


#1 by Rey Bango on 11/30/07 - 5:20 PM
#2 by dave on 12/10/07 - 3:14 PM
Thanks for the post!
#3 by Dave on 12/14/07 - 8:47 PM
SELECT
'<a href="javascript:showOrderDetail(' +CAST(ROWID AS varchar(5))+ ');"><img src="http://mysite.com/images/button_Open.gif" width="40" height="15" border="0"></a>' AS CLICK_IMG
FROM
ORDERS
#4 by Cutter on 12/15/07 - 8:46 AM
I could have wrapped an 'onclick' anchor around the image in the renderer just as easily, but we lose out on two separate concepts here. The first is the purpose of the post, to show how to do custom renderers and how to add event listeners. The second one gets a little more grey area, to maintain unobtrusive JavaScript. Sure, the grid is rendered by JavaScript to begin with, and the renderer is done by javascript (and all the js is directly in the page anyway, since this implementation is through the CF 8 tags).
But, that is part of the point. It's rendered, whether it was written inline or not. And best practice dictates that JavaScript code should remain unobtrusive, so we assign the event listener, within an external JS file. I know it doesn't make any sense, especially when dealing with Ajax components, but you try to walk the lines of standards as much as possible, vearing when necessary. The usage of 'javascript:method()' within an anchor tag (or any tag), would be considered obtrusive, and should be avoided. Getting out of old, bad habits now will help all of us in the long run.
#5 by Mischa on 1/8/08 - 3:04 PM
Thanks!
Mischa.
#6 by Cutter on 1/9/08 - 4:20 PM
In answer to your question:
/index.cfm/2008/1/9/Ask-Cutter-Calling-functions-when-paging-the-CF8-DataGrid
#7 by todd sharp on 3/4/08 - 9:05 AM
#8 by Steve 'Cutter' Blades on 3/4/08 - 9:14 AM
#9 by j on 3/23/08 - 6:41 AM
#10 by Mario Lago on 8/27/08 - 10:05 AM
#11 by Steve 'Cutter' Blades on 8/27/08 - 10:46 AM
Thank You Mario, for undervaluing the effort that I put out to share information that people can use. If you had looked around some, you might have noticed that the download link contained all of the sample code, which you could run yourself, or seen the next post on the blog stating that the download had been added. No, you felt it necessary to call me an Idiot within my own space. Thank you so much for letting me know just how much my hard work, on my own time, to help others means to the community. Truly inspirational.
#12 by bb on 5/15/09 - 12:41 PM
#13 by Fatboy Csaba on 8/14/09 - 1:59 AM
#14 by Dan O'Keefe on 9/14/09 - 5:23 PM
#15 by Steve 'Cutter' Blades on 9/15/09 - 6:23 AM
Call me Cutter:)
I'll have to go back and look over this code. It's been out there a while, so something might have changed...? Which server version are you using?
#16 by Dan O'Keefe on 9/15/09 - 9:40 AM
CF 8.01 Enterprise. Thanks.
#17 by Steve 'Cutter' Blades on 9/15/09 - 3:47 PM
Wow! Not sure how this has been missed all this time, but my original example contained another folder with a CFC for getting data from one of the CF sample (derby) datasources. I guess I forgot to include it in the zip, which is now way long gone.
The importance to the examples is really in understanding how, through JavaScript, you can create custom renderers for your columns, as well as a general understanding of working with an event driven paradigm.
If you have any questions, drop me a line.
#18 by Shiv on 8/2/10 - 9:27 AM
Thanks a lot for this article. It really helped me out. CFGrid has so many options but with little documentation.
Thanks again.
#19 by Shiv on 8/3/10 - 8:37 AM
This post help me to add custom renderer. Now I need to show summary total of value column in the grid. I read that its possible using EX JS but havn't got any example. can you help ?
Thanks
#20 by Steve 'Cutter' Blades on 8/3/10 - 8:47 AM
Yes, this is possible in a straight Ext JS implementation, through the use of the summary plugin. There's an example in the Ext JS Demo area:
http://www.sencha.com/deploy/dev/examples/grid/tot...
#21 by Misty on 9/21/11 - 6:01 PM
I have an Issue here very similar to yours tutorial. Can you please guide me a bit!
Scenario is
"I have a CFgrid data coming and i want to create a link on cfgrid field ID. it should come as a hyperlink!
and i want to open a cfwindow onclick of ID and open the page inside the data based on the ID i pass, how can i do that!
Also can i add the export functionality within the cfwindow to export that data to excel"
#22 by Steve 'Cutter' Blades on 9/22/11 - 7:42 AM
It's been quite a while since I looked at all of this (cfajax components). What you're trying to do isn't overly difficult, just more involved than the cfajax components typically allow. Don't get me wrong, they're beautiful for small, quick implementations. But, when you're diving into more complex functionality, such as this, then you hit a point where you have to start writing your own js implementations, rather than having CF do it for you.