Posted in ColdFusion | Posted on 08-28-2010 | 4,093 views
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.
2<cfloop index="x" from="1" to="10">
3 <cfset queryAddRow(q)>
4 <cfset querySetCell(q, "id", x)>
5 <cfset querySetCell(q, "name", "Name #x#")>
6</cfloop>
7
8<cfform name="mytest" method="post">
9 <cfgrid name="SelectStuff" query="q" format="html" width="400" height="250" multirowselect="true"></cfgrid>
10 <cfinput type="submit" name="submit" value="Submit">
11</cfform>
12
13<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:
This returns a struct of objects. How do you send that to the server? One option would be to turn into JSON:
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:
2for(var i=0; i<obj.length; i++) {
3 if(selected == "") selected = obj[i].ID;
4 else selected += "," + obj[i].ID;
5}
6document.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.
2<cfloop index="x" from="1" to="10">
3 <cfset queryAddRow(q)>
4 <cfset querySetCell(q, "id", x)>
5 <cfset querySetCell(q, "name", "Name #x#")>
6</cfloop>
7
8<script>
9function fixMe() {
10 obj = ColdFusion.Grid.getSelectedRows('SelectStuff');
11 var selected = "";
12 for(var i=0; i<obj.length; i++) {
13 if(selected == "") selected = obj[i].ID;
14 else selected += "," + obj[i].ID;
15 }
16 document.getElementById('selected').value = selected;
17 return true;
18}
19</script>
20
21<cfform name="mytest" method="post" onSubmit="return fixMe()">
22 <cfgrid name="SelectStuff" query="q" format="html" width="400" height="250" multirowselect="true"></cfgrid>
23 <input type="hidden" name="selected" id="selected">
24 <cfinput type="submit" name="submit" value="Submit">
25</cfform>
26
27<cfdump var="#form#">

