CF901 CFGRID's new multirowselect feature

Earlier this week a user asked me to look into something odd with CF901’s new multirowselect feature for cfgrid. If you haven’t played with this yet, it is a way to enable multiple row selections in a grid. Unfortunately it doesn’t quite work as advertised, but in this blog entry I’ll tell you how to make it work.

First, let's start with a simple example so you can see what the attribute does when enabled.

<cfset q = queryNew("id,name")> <cfloop index="x" from="1" to="10"> <cfset queryAddRow(q)> <cfset querySetCell(q, "id", x)> <cfset querySetCell(q, "name", "Name #x#")> </cfloop> <cfform name="mytest" method="post"> <cfgrid name="SelectStuff" query="q" format="html" width="400" height="250" multirowselect="true"></cfgrid> <cfinput type="submit" name="submit" value="Submit"> </cfform> <cfdump var="#form#">

My code begins with a quick fake query on top. Next I've got a cfform with my grid inside. The only thing really interesting there is the multirowselect. I also added a quick dump of the form scope to the bottom. Let's take a look at how the grid is changed. I'll first show a picture with the option turned off, this is the default:

Now let's turn the option back on, as in the code above.

As you can see, there is a new column now with checkboxes. There is also a checkbox on top. Clicking that works as a Select All/Deselect All feature. So in theory, that should be it, right? Unfortunately, it completely doesn't work as shown above. If I click a few checkboxes and hit submit, I get this in the form scope.

Nothing. Ugh. So I pinged Adobe on this. Turns out - the real expectation for this feature was within Ajax-based applications. You can get the value just fine via JavaScript, but if you don't do this, nothing will be sent to the server. I've already filed a bug report on this.

So how can you make this work? The simplest solution is to use the getSelectedRows API:

obj = ColdFusion.Grid.getSelectedRows('SelectStuff');

This returns a struct of objects. How do you send that to the server? One option would be to turn into JSON:

jsonbj = ColdFusion.JSON.encode(obj);

However, this will give you a JSON representation of the entire row. You probably only want the ID values, right? Here is the code I came up:

var selected = ""; for(var i=0; i<obj.length; i++) { if(selected == "") selected = obj[i].ID; else selected += "," + obj[i].ID; } document.getElementById('selected').value = selected;

Basically - create a list of IDs from the object and assign it to a new form field, in this case, a hidden one. You can try this yourself via the demo link below, and I've pasted the entire completed template below.

<cfset q = queryNew("id,name")> <cfloop index="x" from="1" to="10"> <cfset queryAddRow(q)> <cfset querySetCell(q, "id", x)> <cfset querySetCell(q, "name", "Name #x#")> </cfloop> <script> function fixMe() { obj = ColdFusion.Grid.getSelectedRows('SelectStuff'); var selected = ""; for(var i=0; i<obj.length; i++) { if(selected == "") selected = obj[i].ID; else selected += "," + obj[i].ID; } document.getElementById('selected').value = selected; return true; } </script> <cfform name="mytest" method="post" onSubmit="return fixMe()"> <cfgrid name="SelectStuff" query="q" format="html" width="400" height="250" multirowselect="true"></cfgrid> <input type="hidden" name="selected" id="selected"> <cfinput type="submit" name="submit" value="Submit"> </cfform> <cfdump var="#form#">

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. 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.

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

Comments