I’m using a <cfgrid> to display some data returned from a query. Not exactly rocket science, but I’ve managed to run into a bit of difficulty meeting a couple of final client requirements. Let me set up the scene here. First I have a form with several different search criteria, which are independent of each other. Depending on which search criterion is selected, a different grid will display. Each grid will has an Action column with links to another page.
First we call the CFC and add the “Actions” column to the returned query recordset:
<cfinvoke component=“#APPLICATION.ManageFieldOffice#” method=“retrieveProjectNames” returnvariable=“qRetrieveProjectNames” CountryID=“#CountryID#”/>
<cfset queryAddColumn(qRetrieveProjectNames, “viewlink”,“varchar”, arrayNew(1))/>
<cfloop query=“qRetrieveProjectNames”>
<cfsavecontent variable=“viewtext”>
<cfoutput>
<a href=“#APPLICATION.self##xfa.lnkViewFieldOffice#&cntFieldOffice=#cntFieldOffice#&vTab=1″>View</a> | <a href=“#APPLICATION.self##xfa.lnkViewCountry#&countryID=#CountryID#”>View Country Record</a>
</cfoutput>
</cfsavecontent>
<cfset querySetCell(qRetrieveProjectNames, “viewlink”,viewtext, currentRow)>
</cfloop>
Then we display the results in the grid:
<cfgrid format=“html” name=“countryResults” query=“qRetrieveProjectNames” pagesize=“25″ width=“700″ striperows=“true”>
<cfgridcolumn name=“cntFieldOffice” display=“false” headerbold=“true”>
<cfgridcolumn name=“strProjectName” header=“Project Name” width=“300″ headerbold=“true”>
<cfgridcolumn name=“Country” headerbold=“true”>
<cfgridcolumn name=“strProjectNumber” header=“Project Code” headerbold=“true”>
<cfgridcolumn name=“viewlink” header=“” width=“200″>
</cfgrid>
Thanks to Ray Camden for his code example that guided me in creating the links for the Action column.
Here’s my CFC method:
<cffunction name=“retrieveProjectNames” output=“false” access=“public” returntype=“query” hint=“I retrieve all project office names”>
<cfargument name=“CountryID” type=“numeric” required=“false”/>
<cfargument name=“CountryList” type=“string” required=“false”/>
<!— var scope variables —>
<cfset var qRetrieveProjectNames = “”/>
<cftry>
<cfquery name=“qRetrieveProjectNames” datasource=“#variables.dsn#”>
SELECT tblFOAdminInfo.cntFieldOffice, tblFOAdminInfo.strProjectName, tblFOAdminInfo.strProjectNumber, tblFOAdminInfo.CountryID, tlkpCountry.Country
FROM tblFOAdminInfo
JOIN tblFOFieldOffices ON tblFOFieldOffices.cntFieldOffice = tblFOAdminInfo.cntFieldOffice
JOIN tlkpCountry ON tlkpCountry.CountryID = tblFOAdminInfo.CountryID
WHERE
tblFOFieldOffices.ysnDisable = <cfqueryparam value=“0″ cfsqltype=“cf_sql_bit”>
<cfif IsDefined(“ARGUMENTS.CountryID”) AND ARGUMENTS.CountryID GT 0>
AND tblFOAdminInfo.CountryID = <cfqueryparam value=“#ARGUMENTS.CountryID#” cfsqltype=“cf_sql_integer”>
<cfelseif IsDefined(“ARGUMENTS.CountryList”)AND ARGUMENTS.CountryList NEQ “”>
AND tblFOAdminInfo.CountryID IN (#ARGUMENTS.CountryList#)
</cfif>
ORDER BY tblFOAdminInfo.strProjectName
</cfquery>
<cfreturn qRetrieveProjectNames />
<cfcatch type=“ANY”>
<cfreturn false>
</cfcatch>
</cftry>
</cffunction>
So here’s what the grid looks like:
So this works just fine, however there’s one small problem. The client wants to page through large recordsets. Not an extraordinary request by any means, but I’ve run into a problem. The <cfgrid> ignores the pagesize attribute when a query attribute is specified. To get around this, I could just use a bind parameter in <cfgrid>, which I did. This cuts down significantly on the code since I no longer need to cfinvoke my CFC method. I call it right from the <cfgrid> tag.
My grid code now looks like this:
<cfgrid name=“regionResult2″ format=“html” pagesize=“25″ preservepageonsort=“true” width=“700″ bind=“cfc:fieldoffice.field_v201_beta.cfapps.components.ManageCountry.getCountryByRegion({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection}, getRegionSearchParam())”>
<cfgridcolumn name=“Country” header=“Countries” width=“550″ headerbold=“true” />
<cfgridcolumn name=“viewlink” header=“Action” width=“200″>
</cfgrid>
I had to modify my CFC method as follows to supply the grid with the data:
<cffunction name=“getCountryByRegion” output=“false” access=“remote” returntype=“struct” hint=“I get Countries for a given strRegion”>
<cfargument name=“page” required=“true”/>
<cfargument name=“pagesize” required=“true”/>
<cfargument name=“gridsortcolumn” required=“true”/>
<cfargument name=“gridsortdirection” required=“true”/>
<cfargument name=“strRegion” type=“string” required=“true”/>
<cfset var qRetrieveCountryByRegion = “”/>
<cfquery name=“qRetrieveCountryByRegion” datasource=“FieldOffices”>
SELECT tlkpCountry.Country, tlkpCountry.CountryID
FROM tblFOCountry
INNER JOIN tlkpCountry ON tblFOCountry.CountryID = tlkpCountry.CountryID
WHERE tblFOCountry.strRegion = <cfqueryparam value=“#ARGUMENTS.strRegion#” cfsqltype=“cf_sql_varchar”>
ORDER BY tlkpCountry.Country
</cfquery>
<cfreturn queryconvertforgrid(qRetrieveCountryByRegion,page,pagesize) />
</cffunction>
A few things I learned in modifying my CFC method for this grid:
- I had to change the returntype from query to structure as Firebug showed a returntype is not of type query.
- Had to hardcode my DSN. When I checked Firebug, I noticed the response was “Datasource ” not found” so my dynamic value was not working for some reason.
- Had to add the 4 standard cfgrid arguments
Since I eliminated my cfinvoke to call the method, I figured I’d just move my code to add the Actions link to the query recordset. After the query is executed, I add the code and the use queryconvertforgrid() to return the whole thing. Now my grid appears and paging is available, but there is no Actions column.

I have to be missing something. I cannot believe that I can’t add a link to a grid created using the bind parameter of the <cfgrid> tag. Good thing I’m heading to CFUnited tomorrow. Perhaps I can find some help there.