Almost three years ago I wrote a blog entry on doing custom grid renderers with CFGRID and the Ext grid for ColdFusion 8. This week a reader and I went back and forth in the comments concerning how to build a renderer that would modify a column but check other column values for the logic. So for example, in that previous blog entry my logic for a custom product column was to check to see if the product was "Product 4". What if I wanted to check the price for example? Here is an updated version that works with ColdFusion 9 and does just that.
<head>
<script> myf = function(data,cellmd,record,row,col,store) {
console.dir(record.data);
//old logic, prod 4 only
//if(data == "Product 4") return "<b style='color:red'>" + data + "</b>";
//new logic, price > 50 and type is weapon
if(record.data.TYPE == 'weapon' && record.data.PRICE > 50) return "<b style='color:red'>" + data + "</b>";
else return data;
}
testgrid = function() {
mygrid = ColdFusion.Grid.getGridObject('data');
cm = mygrid.getColumnModel();
cm.setRenderer(0, Ext.util.Format.usMoney);
cm.setRenderer(1,myf);
mygrid.reconfigure(mygrid.getStore(),cm);
}
</script>
</head> <body> <cfset data = queryNew("price,product,type")>
<cfloop from=1 to=10 index="x">
<cfset total = randRange(20,100) & "." & randRange(1,99)>
<cfset product = "Product #X#">
<cfset queryAddRow(data)>
<cfset querySetCell(data, "price", total+0, x)>
<cfset querySetCell(data, "product", product, x)>
<cfset querySetCell(data, "type", "#randRange(0,1)?'weapon':'fruit'#")>
</cfloop> <cfform name="test">
<cfgrid autowidth="true" name="data" format="html" query="data" width="600">
<cfgridcolumn name="price" header="Price">
<cfgridcolumn name="product" header="Product">
<cfgridcolumn name="type" header="Type">
</cfgrid>
</cfform> <cfset ajaxOnLoad("testgrid")>
</body>
</html>
<cfajaximport/>
<html>
If you compare this code to the older entry, the changes are:
- In my fake query, I added a new type column. All my products are either weapons or fruits. (Although one could argue that you could turn some weapons into fruits. I mean turn some fruits into weapons. Yeah, that's it.)
- Next look at the myf function. I kept the old logic in there commented out. You can see it made use of the data argument which is the cell being formatted. I ignore that though and check the rest of the row. This is passed in the record object. As you see, I check the TYPE and PRICE, and based on my business rule, I color the item red.
- One small other change - back in the testgrid function (which remember is run when the application starts up), I changed getDataSource to getStore. This reflects the fact that the Grid used in CF9 has a different API then the one run in CF8.
If you want to see a demo of this, just hit the button below. You may need to reload once or twice since the values are random.
Archived Comments
Your demo doesn't appear to be working for me. I see no red weapons. FF 3.5 on Win.
Ahhh... you left a console.dir in there... once I open Firebug and run it it works.
Yes, I did. I'm now doing it just to tick people off. ;) (Seriously though - folks shouldn't run w/o console - ever - not us anyway.)
This version of Firebug I have doesn't run unless it's open. Which is fine with me. I'd rather not be slowed down by Firebug but it's right there when I need it.
This was great info. Just transitioned to CF9 and trying to making cfgrid work in a number of ways. Your code works fine as a stand-alone. I noticed that if the <head></head> tags are removed (html/body tags didn't seem to be needed) that the rendering would not take place. This said it appears when using Spry tabs and trying to render it doesn't work because the <head> tags have been closed in our index.cfm file. Adding the <script> into the calling page doesn't appear to make it work either. Any ideas on where to place the <script>? Does the <...ajaxOnLoad ()> need to be in the main program that calls the tabs?
Sorry - I haven't used Spry tabs in years.
So, hmm here i was testing this using IE, and it hasnt worked all this time, changed to FF... and it works...
even these days we r still having issues with browser compatibility... really silly
any fix to make it work in IE, also?
See the console.dir command? Just remove it. It's FF/Firebug, Chrome, and Safari only.
If I have a cfgridcolumn type = boolean, it means that I will have a checkbox in the cfgrid. If I render it to the function myf, it will return True or False. Can this myf return the checkbox?
thnks
I'm sure it can. I'd do what I did when I posted this - check the Ext docs.
Thanks for your reply!
I already did read the ExtJS 3 documentation... I tried to create a object Ext.form.Checkbox and return it, but it didnt work :(
Yeah, sorry, can't help much more than to say keep trying. :) I'm not an Ext person.
This is just a nit, but it's a bit confusing when using the same name for different objects, e.g., "data" for the query and the CFGrid.
One's client-side and one's server-side. ;)
Wow. Your quick response makes me wonder how you find time to do your OWN work. Thanks.
I'm reading a tech spec. It took me 60 seconds to read and response. Less than a smoke break. ;)
I am having an issue with the line of code that calls "record.data.TYPE" in the myf function. Which works well when I am using the query attribute but how would I call the "record.data.type" if my (editable) cfgrid is using the bind attribute and not a query attribute?
Also why is the colunm name "TYPE" uppercase? This one just bugs me.
I found out why I was having an issue with 'record.data.TYPE". In your example you use the same name for several objects "data". I rename the objects to match my script, however I was confused that record.data. was not to be rename. Everything works like champ now.
Calm Down and keep CFing....