ColdFusion MX7 offers Flash Forms which is a very nice, new, and quick touch to any application. Unfortunately, it does have limitations that send developers like myself hunting for answers to keep the integrity of strong application development with an effortless and clean interface. Here is one example that set me back a few and left me extremely frustrated with Adobe Live Docs.
CFGRID is a very powerful tool when displaying records from any database because they eliminate the annoyance tables can tend to have when writing HTML. It’s just a different way of thinking though when building style into the simple idea of a clean record set that gets returned. I have come across this one too many times with using Flash Forms, “How can I make this presentation/application more efficient for the user?” Simple, by reducing the amount of steps it takes to add, edit, and manipulate data without giving a mess of confusion in one page. This is not so simple when it comes to CFGRID. There are a million examples of how to edit data within the grid, delete rows, insert new rows, even total a column’s values. But very few actually show how to edit the information in the grid and write back to the database leading to my frustration with documentation available for ColdFusionMX7 & MX6. This really only poses a problem to those of us that started coldfusion a little later then most.
There is hope though! It is actually documented in ColdFusion 5’s explanations/examples of CFGRID. It gives a few tags that are extremely powerful making two days of Google searching worth the five maybe ten lines of code it takes to accomplish this. Here is my example which we will call “licenses.cfm“:
In your Grid there are only but two to three statements needed to make columns and/or whole rows editable. The first one resides in your start tag. For example:
cfgrid name="AllLicenses" query="qAllLicenses" format="flash" sort="yes" height="200"
selectmode="edit"
Notice the last part. Selectmode is what makes your grid editable allowing you to select any area and change the data. Within your tag you can designate which columns to make editable. Here is an example of how to restrict editing:
cfgridcolumn name="LicenseID" header="License ID" width="50" display="no" select="no"
The select=”no” statement is an immmediate reference to “selectmode” and this columns particular state/function. This example shows how to allow for an edit in a given column:
cfgridcolumn name="LicenseAdd" header="Add" width="30" type="boolean" select="yes"
Simple enough. Keep in mind that without these “select” tags in each cfgridcolumnit will just default making all columns editable. For my case I wanted to assign hardware items multiple software licenses. My goal was to provide a “oneshot” that would display a little information about the box, it’s current list of licenses applied, and all available licenses to add. With respect to building it in one page for the user I wanted them to have the ability to select via “checkbox” any remaining licenses attaching them to that specific box. Without Flash Forms it is a pretty easy task but then you lose the power of clean interface elements on the fly. With them is a different story.
I inserted a new field into my inventory database within my Licenses table called “LicenseAdd“. This is of boolean type and has no purpose other than to temporarily tag each license for later review upon “submit”. There is really only one more part to consider at this point. How do we update the database depending on which licenses have been checked inside the ? It’s pretty easy actually! You want to build a cfloopthat moves through an array that is combined of all records selected from the grid for insertion. Like so:
cfif IsDefined("FORM.LicenseAdd")
cfloop from="1" to="#ArrayLen(FORM.allLicenses.LicenseID)#" index="i"
cfinvoke component="inventoryCollectionManager.items" method="insertLicenseLocations"
cfinvokeargument name="LicenseID" value="#FORM.allLicenses.LicenseID[i]#"
cfinvokeargument name="ItemID" value="#URL.ItemID#"
/cfinvoke
/cfloop
cflocation url="viewAllLicenses.cfm?ItemID=#URL.ItemID#"
/cfif
Depending on whether any boxes are checked in the designated column:
cfif IsDefined("FORM.LicenseAdd")
Start at one and go until the Length of the Array:
cfloop from="1" to="#ArrayLen(FORM.allLicenses.LicenseID)#" index="i"
Then perform this action(write to a table in your database):
cfinvoke component="inventoryCollectionManager.items" method="insertLicenseLocations"
cfinvokeargument name="LicenseID" value="#FORM.allLicenses.LicenseID[i]#"
cfinvokeargument name="ItemID" value="#URL.ItemID#"
/cfinvoke
Stop loop after insert and redirect back to that same page to show added licenses.
/cfloop
cflocation url="viewAllLicenses.cfm?ItemID=#URL.ItemID#"
/cfif
That is about it. For another example on this please visit:
http://cfsilence.com/blog/client/index.cfm/2006/2/2/Cant-use-CFGRIDUPDATE–Try-this
and
http://livedocs.macromedia.com/coldfusion/5.0/CFML_Reference/Tags41.htm