Scott Bennett put up two nice postings which demonstrate how to extend ColdFusion 8’s built-in Grid control. I’ve mentioned before that CF8 uses Ext v1.0 and as such offers a ton of flexibility not generally mentioned in the CF documentation.
Grid Validation
In his first post, Scott shows how to implement validation of CFGrid data. Leveraging Ext’s validateedit event, which fires after a cell is edited but before the value is actually saved, Scott was able to include code that validated the data prior to being saved:
Now whenever the validateedit event fires, it will call the dataValidator() function. The dataValidator() function checks to see if the field that is being edited needs validation, and then validates the data if necessary. In this example, I added validation for the Expiration Date, and the numeric Sponsor ID for the coupon record. If the data fails validation an alert is thrown and the edit event is canceled(reverting the data back to it’s original value).
<html>
<head>
<title>CFGird Custom Date Validator</title>
<!— import the Ext date package —>
<cfajaximport tags=“cfinput-datefield”>
<!— create javascript function for rendering dates —>
<script language=“JavaScript” type=“text/javascript”>
setDateRenderer = function(){
mygrid = ColdFusion.Grid.getGridObject(’CouponsGrid’);
cm = mygrid.getColumnModel();
cm.setRenderer(3, Ext.util.Format.dateRenderer(’m/d/Y’));
mygrid.reconfigure(mygrid.getDataSource(),cm);
}
dataValidator = function(editEvent){
//Date Field Validation
if (editEvent.field == “EXPIRATIONDATE”){
if (isNaN(Date.parse(editEvent.value))){
alert(“Please enter a date in this field.”);
editEvent.cancel = true;
}
else {
data = new Date(Date.parse(editEvent.value));
editEvent.value = data.dateFormat(“m/d/Y”);
}
}
//Numeric Field Validation
if (editEvent.field == “SPONSORID”){
if (isNaN(editEvent.value)){
alert(“Please enter a numeric value in this field.”);
editEvent.cancel = true;
}
}
}
addValidator = function(){
mygrid = ColdFusion.Grid.getGridObject(’CouponsGrid’);
mygrid.on(’validateedit’,dataValidator);
}
init = function(){
setDateRenderer();
addValidator();
}
</script>
</head>
<body>
<!— Set up the Grid —>
<cfform id=“CouponForm” name=“CouponForm”>
<cfgrid name=“CouponsGrid”
format=“html”
pagesize=“10″
striperows=“yes”
selectmode=“edit”
bind=“cfc:coupons.getCoupons({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})”
onchange=“cfc:coupons.editCoupon({cfgridaction},{cfgridrow},{cfgridchanged})”>
<cfgridcolumn name=“Couponid” display=“false” />
<cfgridcolumn name=“SPONSORID” header=“Sponsor” width=“100″/>
<cfgridcolumn name=“COUPON” header=“Coupon” width=“100″/>
<cfgridcolumn name=“EXPIRATIONDATE” header=“Exp Date” width=“200″/>
</cfgrid>
</cfform>
<!— use AjaxOnLoad to call the init() function —>
<cfset ajaxOnLoad(“init”)>
</body>
</html>
Custom Date Renderer
In his second post, Scott again takes advantage of Ext’s capability and shows how to create a custom date renderer:
One of the coolest things about the ColdFusion 8 implementation of the CFGrid tag is that you can do a lot of customization, if you know your way around the Ext objects. I have found several blog entries about using custom renderers with the CFGrid tag. However, could not find a working example of one for date fields, so I decided to build one.
CouponForm.cfm
<html>
<head>
<title>Custom Date Renderer</title>
<!— import the Ext date package —>
<script src=“/CFIDE/scripts/ajax/ext/package/date.js” type=“text/javascript”></script>
<!— create javascript function for rendering dates —>
<script language=“JavaScript” type=“text/javascript”>
setDateRenderer = function(){
mygrid = ColdFusion.Grid.getGridObject(’CouponsGrid’);
cm = mygrid.getColumnModel();
cm.setRenderer(3, Ext.util.Format.dateRenderer(’m/d/Y’));
mygrid.reconfigure(mygrid.getDataSource(),cm);
}
</script>
</head>
<body>
<!— Set up the Grid —>
<cfform id=“CouponForm” name=“CouponForm”>
<cfgrid name=“CouponsGrid”
format=“html”
pagesize=“10″
striperows=“yes”
selectmode=“edit”
bind=“cfc:coupons.getCoupons({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})”
onchange=“cfc:coupons.editCoupon({cfgridaction},{cfgridrow},{cfgridchanged})”>
<cfgridcolumn name=“Couponid” display=“false” />
<cfgridcolumn name=“SPONSORID” header=“Sponsor” width=“100″/>
<cfgridcolumn name=“COUPON” header=“Coupon” width=“100″/>
<cfgridcolumn name=“EXPIRATIONDATE” header=“Exp Date” width=“200″/>
</cfgrid>
</cfform>
<!— use AjaxOnLoad to set the date renderer —>
<cfset ajaxOnLoad(“setDateRenderer”)>
</body>
</html>
</html>
The secret sauce in this code is the following line:
cm.setRenderer(3, Ext.util.Format.dateRenderer(’m/d/Y’));
That’s the built-in Ext method that allows you to define your custom date renderer. Again, this is not something that’s actively promoted by Adobe, most likely since they’re trying to abstract the intricacies of the Ext framework via a cozy HTML-centric syntax. This, in my opinion, is not a bad thing as it eases new developers into client-side development while still allowing experienced developers to extend their apps via the framework’s actual API.