Two CFGRID Examples: Related grids and updating checkboxes

This post is more than 2 years old.

I've had a simple CFGRID demo sitting in my local web server for a few months now and never got around to sharing it on the blog. Today I responded to user with another CFGRID question and figured it would be good to share them both in one example. (Plus, the code has been sitting in my test.cfm file all that time and I want to get rid of it. ;) So let's start with the first example - relating one cfgrid to another.

I've got two simple cfgrids tied to the cfartgallery database. The first cfgrid is bound to the Media database table:

<cfgrid bind="cfc:test.getMedia({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})" name="mediaGrid" format="html" width="400"> <cfgridcolumn name="mediaid" display="false"> <cfgridcolumn name="mediatype"> </cfgrid>

The CFC, test, has a basic query to grab the media info. Notice we have to support the 4 required arguments gridpage, pagesize, sortcolumn, and sortdirection, when binding with grids.

component {

remote struct function getMedia(page,size,col,dir) {
	var q = new com.adobe.coldfusion.query();
	q.setDatasource("cfartgallery");
	q.setSQL("select mediaid, mediatype from media");
	return queryConvertForGrid(q.execute().getResult(),page,size);
}

}

So far so good, right? Ok, how do I bind another grid to this one?

<cfgrid bind="cfc:test.getArt({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},{mediaGrid.mediaid})" name="artGrid" format="html" width="400" bindonload="false" > <cfgridcolumn name="artname"> <cfgridcolumn name="price"> </cfgrid>

I've taken a normal bound cfgrid, and simply appended additional arguments to the end of the required list. In this case, I've bound to the first grid's mediaid column. Now all I need is a CFC method that handles this:

remote struct function getArt(page,size,col,dir,media) { var q = new com.adobe.coldfusion.query(); q.setDatasource("cfartgallery"); q.setSQL("select artname, price, issold from art where mediaid = :mediaid"); q.addParam(name="mediaid",value="#arguments.media#",cfsqltype="cf_sql_integer"); return queryConvertForGrid(q.execute().getResult(),page,size); }

Pretty simple, right? I don't really make use of ColdFusion's Ajax UI stuff any more, but it certainly does a good job of simplifying things.

Now let's take it a step further. What if we wanted to bind a checkbox to a grid? Turns out - there isn't a simple way to do this. Binding a text box is simple enough. If we add the issold property to the grid (to "listen" to data in a grid, it has to be a grid column) we can then work with it:

<cfgrid bind="cfc:test.getArt({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection},{mediaGrid.mediaid})" name="artGrid" format="html" width="400" bindonload="false" > <cfgridcolumn name="artname"> <cfgridcolumn name="price"> <cfgridcolumn name="issold" display="false" > </cfgrid>

For my first test, I used a text field, just to ensure it was binding ok:

<cfinput type="text" name="issold" bind="{artGrid.issold}">

This worked, but wasn't the checkbox we wanted. What we really want is - bind to the grid's issold value and set or clear the checked attribute. cfinput does support a bindAttribute argument, but it only works with text fields, which seems truly odd. There's a simple enough workaround though. You can bind to a change in a grid by attaching it to a JavaScript function.

<cfajaxproxy bind="javascript:noteChange({artGrid.issold})">

This little gem here just says - when the grid changes, specifically the issold value, run a JavaScript function. We can then do:

<script> function noteChange(sold){ var b = false; if (sold == 1) { b = true; } document.getElementById("issoldcb").checked=b; } </script>

In case you're wondering, the logic there around sold was because it was being treated as a string.

If you want to test this, try the demo here: http://www.raymondcamden.com/demos/2012/jan/22/test.cfm

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for HERE Technologies. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Joshua Miller posted on 1/23/2012 at 8:05 PM

With Adobe fully embracing jQuery, I'm curious if there are plans for this type of control to be replaced with versions based on jQuery or existing jQuery plugins in Zeus? There are some solid jQuery versions of tables already such as DataTables (http://datatables.net/). Is there going to be a push toward jQuery community-supported plugins?

Comment 2 by Raymond Camden posted on 1/23/2012 at 8:14 PM

Can't really answer that now, Joshua, sorry. I don't think we have said anything about the Ajax UI controls.

Comment 3 by Joshua Miller posted on 1/23/2012 at 8:16 PM

No problem Ray, just thought I'd ask in case it was known or announced at a conference and I just missed it.

Comment 4 by Tim Rubel posted on 2/8/2012 at 1:15 AM

Joshua, I am going to guess Adobe has something in the works, if Ray can't comment right now. He has probably signed a NDA that prevents him talking about any specifics not already release in the future release.

Comment 5 by Raymond Camden posted on 2/8/2012 at 1:16 AM

I did more than sign an NDA - I work for Adobe now. :)

Comment 6 by Chuck Duppong posted on 3/7/2013 at 2:14 AM

Thanks Ray; very helpful.

Comment 7 by Michael Kane posted on 5/14/2013 at 10:03 PM

Ray, any update about cfgrid vs Jquery? I'm still using CF 9.0.1, and wondering if I should or should not use cfgrid for an app I'm working on.

Comment 8 by Raymond Camden posted on 5/14/2013 at 10:40 PM

Michael, it is not the official Adobe position, but *my* position (and Forta agrees) is to avoid all of the UI controls. I *always* recommend rolling your own via one of the many options out there. jqGrid is a great one and I'd recommend it.