I was working on a project yesterday, and I was using an editable CFGrid to manage a list of data. On my form I wanted to create a button with an onClick event that would take the data from the selected row in my CFGrid , and then do some processing and update that row on the CFGrid and in the database automatically. To do this I needed some way to update the data in a specific cell on the grid,
but there was no obvious way to do that.
I consulted the Adobe docs and they provide us with a few different grid related functions. Originally I had thought about just writing a function that updates the data through a cfc call then calls ColdFusion.Grid.refresh, which Manually refreshes a displayed grid. I couldn't use this however because when you call it the whole grid page gets refreshed and you loose the row you have selected.
I determined at this point I was going to have to use ColdFusion.Grid.getGridObject, which Gets the underlying Ext JS - JavaScript Library object for the specified HTML format CFGrid control. Then I began a long and tedious process of trying to figure out how to use yet another giant JavaScript Library that I am completely unfamiliar with. The ext documentation was a little bit of a help, but ultimately it came down to me just fiddling with it for several hours until it clicked in my head.
Here is a working sample of what I am talking about. This is a simplified version of what I had to do for my real project but it will give you the important part. This is a little contacts manager, and if you select a row and click the "Toggle Cool Factor" button then the selected rows "cool" flag will be changed.
Now for the example code. This code is pretty much like all the other blog entries you see out there by everyone that tell you how to create a cfgrid that is bound to a CFC.
You start with a CFC like with a Get function and an Edit function like:
<cfset THIS.dsn="yourdatabasename">
<!--- Get contacts --->
<cffunction name="getcontacts" access="remote" returntype="struct">
<cfargument name="page" type="numeric" required="yes">
<cfargument name="pageSize" type="numeric" required="yes">
<cfargument name="gridsortcolumn" type="string" required="no" default="">
<cfargument name="gridsortdir" type="string" required="no" default="">
<!--- Local variables --->
<cfset var contacts="">
<!--- Get data --->
<cfquery name="contacts" datasource="#THIS.dsn#">
SELECT contactid, lastname, firstname, email, cool
FROM contacts
<cfif ARGUMENTS.gridsortcolumn NEQ ""
and ARGUMENTS.gridsortdir NEQ "">
ORDER BY #ARGUMENTS.gridsortcolumn# #ARGUMENTS.gridsortdir#
</cfif>
</cfquery>
<!--- And return it as a grid structure --->
<cfreturn QueryConvertForGrid(contacts,
ARGUMENTS.page,
ARGUMENTS.pageSize)>
</cffunction>
<!--- Edit an contact --->
<cffunction name="editcontact" access="remote">
<cfargument name="gridaction" type="string" required="yes">
<cfargument name="gridrow" type="struct" required="yes">
<cfargument name="gridchanged" type="struct" required="yes">
<!--- Local variables --->
<cfset var colname="">
<cfset var value="">
<!--- Process gridaction --->
<cfswitch expression="#ARGUMENTS.gridaction#">
<!--- Process updates --->
<cfcase value="U">
<!--- Get column name and value --->
<cfset colname=StructKeyList(ARGUMENTS.gridchanged)>
<cfset value=ARGUMENTS.gridchanged[colname]>
<!--- Perform actual update --->
<cfquery datasource="#THIS.dsn#">
UPDATE contacts
SET #colname# = <cfif colname eq "cool"><cfif yesnoformat(value) eq "yes">1<cfelse>0</cfif><cfelse>'#value#'</cfif>
WHERE contactid = #ARGUMENTS.gridrow.contactid#
</cfquery>
</cfcase>
</cfswitch>
</cffunction>
</cfcomponent>
Then you create a page with a CFGrid , and javascript to interact with the CFGrid object like this:
<script language="JavaScript">
toggleCool = function(){
currCool = ColdFusion.getElementValue("contactsGrid","contactForm","Cool");
//if only there were a ColdFusion.setElementValue() //then this would be soooo much easier //instead we do this:
//create an instance of the cfc I imported above via cfajaxproxy (coolest tag ever!)
var contactsObj = new CFCs.contacts;
//set error handler function
contactsObj.setErrorHandler(errorHandler);
//get the gridobject
var myGrid = ColdFusion.Grid.getGridObject("contactsGrid");
//get the selected row
var row = myGrid.dataSource.data.items[getGridIndexById(myGrid,myGrid.getSelections()[0].id)].data;
// now that I have the selected row, I can access the columns buy using the // name I assigned the cfgridcolumn in uppercase
if (row.COOL == "1"){
row.COOL = "0";
}else{
row.COOL = "1";
}
// Ihave updated the value of my cool row in the grid datasource now I need to // update the real database. to do this I call the editcontact function in my // CFC just like the cfgrid would have
contactsObj.editcontact('U',row,{COOL:row.COOL});
// Then I call the myGrid.view.refreshRow function which reads from the grid data and // refreshes what is displayed in the specified row
myGrid.view.refreshRow(getGridIndexById(myGrid,myGrid.getSelections()[0].id));
}
// I made a little function here to get the selected rows index by the id
getGridIndexById = function(thisGrid,id){
for(var i=0,_8=thisGrid.dataSource.data.items.length;i<_8;i++){
if(thisGrid.dataSource.data.items[i].id==id){return i;}
}
return -1;
}
//basic error handler
errorHandler = function(statusCode,statusMsg) {
alert(statusCode+': '+statusMsg)
}
</script>
<!--- here is a button with an onclick event to change if they are cool or not --->
<input type="Button" value="Toggle Cool Factor" onclick="toggleCool();">
<cfform id="contactForm" name="contactForm">
<cfgrid name="contactsGrid"
format="html"
pagesize="10"
striperows="yes"
selectmode="edit"
bind="cfc:contacts.getcontacts({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})"
onchange="cfc:contacts.editcontact({cfgridaction},{cfgridrow},{cfgridchanged})">
<cfgridcolumn name="contactid" display="false" />
<cfgridcolumn name="lastname" header="Last Name" width="100"/>
<cfgridcolumn name="firstname" header="First Name" width="100"/>
<cfgridcolumn name="email" header="E-Mail" width="200"/>
<cfgridcolumn name="cool" header="Cool Person" width="200"/>
</cfgrid>
</cfform>
And there you have it! Enjoy.


P.s. like the working example!
Check out this article from Todd Sharp:
http://cfsilence.com/blog/client/index.cfm/2006/6/...