Aug
16

CheckBoxes in a cfgrid

116 comments Posted by: Nahuel

This is an old example that we made for a presentation that we gave to the Michigan user group. It shows how to check and uncheck checkBoxes in a cfgrid. Once you have a least one item checked, you can remove it from the grid. A confirmation pops up before the action gets executed just in case. Then you need to submit the form to see the results.

Checkboxes in a cfgrid

<cfsavecontent variable="actionRemove">
   var contactList = contactList;
   var console = console;
   var confirm = function (evt)
   {
if (evt.detail == mx.controls.Alert.OK)
{
for(var i:Number = contactList.length-1; i >= 0; i--)
         {
            var item:Object = contactList.dataProvider[i];
            
            if(item.checked.toString() == "true")
            {
               contactList.selectedIndex = i;
               GridData.deleteRow(contactList);
            }
         }
}
   }
   alert("Are you sure you want to remove the checked records?", "Warning",
   mx.controls.Alert.OK | mx.controls.Alert.CANCEL, confirm);
</cfsavecontent>
<cfsavecontent variable="selectToggle">
   if(selectBtn.label == "Check all")
   {
      for(var i:Number = 0; i < contactList.length; i++)
      {
         contactList.editField(i, "checked", "true");
      }
      selectBtn.label = "Uncheck all";
   }
   else if(selectBtn.label == "Uncheck all")
   {
      for(var i:Number = 0; i < contactList.length; i++)
      {
         contactList.editField(i, "checked", "false");
      }
      selectBtn.label = "Check all";
   }
</cfsavecontent>
<cfdump var="#form#">
<cfform name="addressBook" format="flash" width="410" height="310">
      <cfformgroup type="panel" label="Contacts">
      <!--- grid with contact names and email addresses --->
         <cfgrid name="contactList" query="contactsQuery" height="220" rowheaders="false"
               selectmode="edit">

            <cfgridcolumn name="checked" header="Delete" type="boolean" width="46"/>   
            <cfgridcolumn name="firstName" header="First Name" />
            <cfgridcolumn name="lastName" header="Last Name" />
            <cfgridcolumn name="email" header="Email" />
         </cfgrid>
         <cfformgroup type="horizontal">
            <cfinput type="button" name="addContact" value="Add" onClick="GridData.insertRow(contactList);"/>
            <cfinput type="button" name="removeContact" value="Remove Checked" onClick="#actionRemove#"/>
            <cfinput type="button" name="selectBtn" width="90" value="Check all" onClick="#selectToggle#"/>
            <cfinput type="submit" name="submitBtn" value="Submit"/>
         </cfformgroup>
      </cfformgroup>
</cfform>

View live example
Download the source

Category: CFForm | ColdFusion |

116 Comments so far

Write yours
barry.b
1. barry.b wrote on August 16, 2005 at 3:22 AM
kewl stuff...I'm starting to appreciate cfform, cfgrid and cfchart even more...

forgive my ignorance but is there anyway around needing a query datatype for cfgrid (or even cfchart)?

&lt;cfgrid name=&quot;contactList&quot; query=&quot;contactsQuery&quot;

why? we use arrays of structs because of flash remoting and also because all of our data has to be manipulated before conversion (we can't use the origional query - eg: every text field has to be at least rTrim'ed, dates formatted to ISO standard etc before leaving the model layer).

it works fine like that and we can swap out flash with dhtml view layers if needed.

is there no other way apart from converting the array'o'structs back to a query? the double conversion seems a shame...

thanks
Wayne
2. Wayne wrote on August 16, 2005 at 7:37 AM
Hi Nahuel,

Thank you for you prompt response. I have just one question. The cfdump is an array of the grid changes, with that I want to pass the array as (args) to _global.updateTimesheet = function(args:Object){

my code here?
}

I have not been able to get the code correct to pass to a cfc (may I ask what would it look like?). I not sure what argument must be set in my cffunction. I have done this without flash remoting to a cfc by means of a submit as per your example (using a cfargument name=&quot;formdata&quot; as type=&quot;struct&quot;, then loop over the struct as per the CF7 docs examples.

Kind Regards
Wayne
Mike Nimer
barry,
you can use cfgridrow instead of the query attribute. Just loop over the query outputting one cfgridrow for each row in the query (with all of your data tweaked the way you like it).

PaulH
4. PaulH wrote on August 18, 2005 at 2:29 AM
cool stuff as usual, getting boring ;-)

a couple/three questions:
- why are you peeling the row off the grid dataprovider (var item:Object = contactList.dataProvider[i];)? any benefit to doing it that way?

- any reason why you're going thru the grid in reverse order?

- i used your code as a model bit i'm seeing cases where GridData.deleteRow(contactList); isn't clearing all the selected rows. any ideas?

thanks again, i check this blog at least once a day, great stuff.
Nahuel
Hi Paul,
- why are you peeling the row off the grid dataprovider, any benefit to doing it that way?
No, You can either do this or getItemAt. I use both.

- any reason why you're going thru the grid in reverse order?
Yes, if you go forward, you will find that some items don't get removed. Why? Because if you have, for example, the third and four item checked, when you remove the third, the fourth takes the place of the third but your i now is 4, so you'd never reach the fourth item in your loop.

- i used your code as a model bit i'm seeing cases where GridData.deleteRow(contactList); isn't clearing all the selected rows. any ideas?
No, try to track it down and send me how to reproduce the behavior and I will check it

-i check this blog at least once a day, great stuff.
Cool :)
PaulH
6. PaulH wrote on August 18, 2005 at 11:21 PM
thanks, i think the reason the grid rows aren't getting all deleted is because i'm looping in the wrong direction. i keep expecting actionscript to be more voodoo-like i guess ;-)
Wayne
7. Wayne wrote on August 19, 2005 at 6:28 AM
Hi Paul

Please would you show the correct code to loop the grid to remove the selected rows. The source code is not working.

If I may; could I see the code for a reverse loop(ascending) and then (descending)

Would really appreciate it thanx
PaulH
8. PaulH wrote on August 19, 2005 at 7:06 AM
wayne, the sample code works fine. use that.
David Brannan
9. David Brannan wrote on August 23, 2005 at 8:47 PM
I'm trying to submit only numerical fields if checked. The fields are invoiceID and numerical, but not boolean.

&lt;cfgridcolumn name=&quot;invoiceNum&quot; header=&quot;Select&quot; type=&quot;boolean&quot; width=&quot;50&quot; /&gt;

This doesn't work, of course.

The data comes from a query, so not certain how to have it selected for submission.

Ideas?


rob
10. rob wrote on August 26, 2005 at 1:07 AM
Database adding and deleting records question.

How does the items checked get remove from the database?

I tryed using your code and my table with my db, I can add/remove items but when I click Submit the record remains in the database without getting updated.

Would really appreciate it.
Muchas Gracias.
Laura
Rob,
When you run the example, and submit the form, you will see that there are several variables in the form scope that tell you what has been added, what has been edited and what has been deleted. It is your job to go through each array and remove what it needs to be removed, the same for update, and insert.
If you deleted something, you will see:
CONTACTLIST.ROWSTATUS.ACTION with an array containing a D (for deleted), those must be deleted. Otherwise you will see I for inserted, and U for updated, with the new and old value.

Hope that helps
David Brannan
12. David Brannan wrote on August 26, 2005 at 10:42 AM
I'm having trouble with what should be a very simple procedure.

1. I want to populate a cfgrid with a query.
2. I want to be able to select a row with a check box.
3. If a check box is selected I want a hidden field to be submitted along with the data in the row.

This is a great example, but it doesn't quite fit this senerio.
Rob
13. Rob wrote on August 26, 2005 at 12:28 PM
Laura;

Thanks for your reply, forgive my ignorance but I'm lost.

-It is your job to go through each array and remove what it needs to be removed, the same for update, and insert.

Do I need to do this within the cfsavecontent tag or I need to loop over to delete the selected rows???

Can you direct me to a sample code on how to delete the rows from the DB after submitting from cfgrid. I tried cfgridupdate but is not working with the flash form cfgrid.

Thank you guys again for sharing your talent/ideas with the rest of us.
David Brannan
14. David Brannan wrote on August 26, 2005 at 1:01 PM
I got it - just needed to add &quot;checked&quot; to my database w/ default as &quot;no&quot;. Now it populates the grid with my query, allows me to select a row with a checkbox, and submit the rows selected.

What a no brainer.
Laura
David,
Depending on your database, you usually can also do
SELECT *, checked='false'
FROM yourTable

If you don't want to polute your database and queries with the view needs, you could also use
QueryAddColumn(contactsQuery, &quot;checked&quot;, &quot;bit&quot;, arraynew(1));

at the top of the page after you get your regular query. I think that would be the cleanest method.
Rich Fergus
16. Rich Fergus wrote on September 11, 2005 at 12:21 PM
Absolutely brilliant posts! So very helpful; This may all too simple but;
Is there a way to automatically select the first item in a CFGRID after it loads?
Steve Hanzelman
When I downloaded the source (this is just what I was looking for to solve an issue), it does not remove items from the grid.

I get the alert message, but the row selected is not removed and the delete box remains checked. If I hit Submit, the rowstatus is a U.

Any ideas? What obvious issue am I missing?

Thanks,
Steve
Laura
Steve,
Sorry about that. The source in the zip had a small mistake. Wonder why nobody caught it before.

I already uploaded the one that works. The only change is in
contactList.editField(i, &quot;checked&quot;, true);
to
contactList.editField(i, &quot;checked&quot;, &quot;true&quot;);

and the same for false.
Steve Hanzelman
Laura,
Thanks for the response.

I probably was the first to notice since I'm a real putz when it coomes to noticing scripting errors.

Works fine now.

Steve
Joske Vermeersch
20. Joske Vermeersch wrote on September 15, 2005 at 1:38 AM
This sucks.
Donwload the 2 files, put them in the same dir, but the lame thing gives an error: can't find component contacts.
I do not have the time to debug someone else's code.
This problem happens frequently,
Why is it so hard to post working examples?
PaulH
Joske, that's uncalled for--these folks have taken the time to share their work w/the community when they didn't have to. i've learned a ton of stuff about flash forms from this blog for which i'm pretty grateful. there's really no need for that kind of comment.
Richfergus
22. Richfergus wrote on September 15, 2005 at 12:11 PM
I agree PaulH!

Joske, perhaps you should refrain from complaining. This is by far one of the best forums on the net. It has helped me tremendously.
Jason
23. Jason wrote on September 28, 2005 at 9:17 AM
First of all, thanks for showing us the power of flash form!

How to get the grid row recordCount in AS?
I'm trying to limit the row that we insert into the grid using AS. So that the add button will turn off when the grid row reaches x number.
Laura
Jason,
Check for myGrid.dataProvider.length
(where myGrid is the name of your grid)
Jason
25. Jason wrote on September 28, 2005 at 2:19 PM
Amazing, it works ;)
Thanks Laura!
Michael White
Speed Problems: I am using this for timesheets approval. I'm experiencing a great deal of slowness with a particular page. my routine looks like:

&lt;!--- Actionscript routine to Select/Deselect All ---&gt;
&lt;cfsavecontent variable=&quot;selectToggle&quot;&gt;
   if(selectBtn.label == &quot;Check all&quot;)
   {
      for(var i:Number = 0; i &lt; gridTimecard.length; i++)
      {
         gridTimecard.editField(i, &quot;Invoiced&quot;, true);
      }
      selectBtn.label = &quot;Uncheck all&quot;;
   }
   else if(selectBtn.label == &quot;Uncheck all&quot;)
   {
      for(var i:Number = 0; i &lt; gridTimecard.length; i++)
      {
         gridTimecard.editField(i, &quot;Invoiced&quot;, false);
      }
      selectBtn.label = &quot;Check all&quot;;
   }
&lt;/cfsavecontent&gt;

I have a grid with 26 columns (only half are visible) so I can pass them all to a processing page to enter them into another table.
I have already updated my home server to 7.01, What can I do to speed this routine up when I get over a hundred timecards?
Nahuel
Hi Michael,
I'm thinking that the problem comes from the amount of columns that you have. Having 26 columns may slow down the datagrid.
Instead to put half of them visible false you can try to don't put them at all, or just put 4 or 6. If the speed is the same we know that is number of columns. is not the problem.
BTW the code is very simple and I don't know how we can optimize it more.
Jason
28. Jason wrote on October 05, 2005 at 5:34 AM
How can I bind a &lt;cfinput type=&quot;checkbox&quot;&gt; to a &lt;cfgridcolumn type=&quot;boolean&quot;&gt;

&lt;cfinput name=&quot;Status&quot; label=&quot;Status&quot; type=&quot;checkbox&quot; bind=&quot;{myGrid.selectedItem.Status}&quot;
onchange=&quot;myGrid.dataProvider.editField(myGrid.selectedIndex, 'Status', Status.selected);&quot;&gt;

I tried this but it couldn't work, any idea?
Joe
29. Joe wrote on October 05, 2005 at 6:32 PM
Let me say your actionscripts are awesome!

I have a question though, when my data is filtered and then selected, the form doesnt pass any data. but when its not filtered, the data is passed. I combined your filtering and checkbox actionscripts.

Thanks so much for any ideas!
Nahuel
Hi Jason,
You can try this code:
&lt;cfinput name=&quot;Status&quot; label=&quot;Status&quot; type=&quot;checkbox&quot; value=&quot;{(myGrid.selectedItem.checked.toString() == 'true')}&quot;
onclick=&quot;myGrid.dataProvider.editField(myGrid.selectedIndex, 'Status', Status.selected);&quot;&gt;

Joe,
You need to use this code if you want to maintain the changes:
http://www.asfusion.com/blog/entry/filtering-a-cfgrid-as-you-type--revisited-
Liz
31. Liz wrote on October 07, 2005 at 11:27 AM
Is there a way to pass data from a cfinput onchange event to &lt;cfsavecontent variable=&quot;Test&quot;&gt; without using cf_flashCallCFC?
Christian Russo
33. Christian Russo wrote on October 21, 2005 at 7:12 AM
The uncheck/check all function works great, but i noticed one problem. I have a grid that consists of 500+ rows, and when I click on the button, I get this message: &quot;A script in this movie is causing Macromedia Flash Player 7 to run slowly. If it continues to run, your computer may become unresponsive. Do you want to abort the script?&quot;

I assume this is due the massive for loop that is running (with 500 rows), but does anyone know of any fix for this or way around it?
Christian Russo
34. Christian Russo wrote on October 21, 2005 at 7:44 AM
There's also another problem I'm having, which is somewhat related to this topic, so i figured i'd post it here.

I want to have a constantly changing number in my form based on how many items are checked in my grid. I noticed there was no onchange for cfgridcolumn, and the onchange for cfgrid won't actually run a script if i'm just clicking checkboxes (i have to actually click on another part of the row for &quot;onchange&quot; to work). Does anyone have any suggestions?
Laura
Christian,
You need to use this technique to avoid the warning:
http://www.asfusion.com/blog/entry/looping-over-the-records-of-a-large-cfgrid

regarding your second question, there a workaround, but it is a little complex to post here. I will try to make an example soon.
Christian Russo
36. Christian Russo wrote on October 25, 2005 at 10:27 AM
Thanks Laura, it worked great. Gets a little slow near the end, but at least it works!! I actually remember looking at that post a while back, but i completely forgot about it.
Sami Hoda
37. Sami Hoda wrote on October 31, 2005 at 6:10 PM
I dont know if anyone else is having this problem. I am using checkboxes as discussed here, and when I submit the form, it shows what was selected fine. However, if I select two items, then unselect one, it thinks both are selected. Anyone else having selecting, then unselecting checkbox issues?
Laura
Sami,
I tested it here: http://www.asfusion.com/blog/examples/item/checkboxes-in-a-cfgrid
and I don't see any problem. Do you do anything else besides checking and unchecking?
John
I have a checkbox that only certain users can click on, is this possible?

I know that if you have a cfgrid that is editable you can mark certian colums as not editable with select=&quot;no&quot;.

Is there a way to do this for certian rows.
Certian record can only be changed by certain users.

Thanks in advance

John
Jan Dolphijn
I have used your addressbook code (thanks ! great work) combined with a query of a msaccess db. I have trouble cfupdating the addressbook because all kinds of strange variables are generating errors. In the cfdump of the page after trying an update every field in the db is repeated ( while not using columns in the grid, with columns only the those fields generate faults) like contactlist.firstname, contactlist.job etc. etc.
Which are not defined in the db and hence generate faults.
The cfinsert is working fine, no strange happenings. You could check the page out and try an update. http://62.194.144.168/birdz/step8.cfm the dump is still on this page.

Does any of you have a clue how to work around these variables ? They are getting on my nerves
:-).

thnx.

Jan (Netherlands)

Melissa
41. Melissa wrote on November 10, 2005 at 8:51 AM
Is there any way to have select boxes inside of a cfgrid? I want to use a cfgrid for my cfform but I need to have dropdowns so that I can control the input from the user.
Sami Hoda
42. Sami Hoda wrote on November 10, 2005 at 2:17 PM
How can we verify atleast one box is selected using Actionscript and thus display an alert saying, &quot;Please select at least one result&quot;?

Laura
Jan,
I can't really help you because I never use cfupdate/cfinsert. I don't recommend their use because you have no control on what goes on.

Melissa,
The simple answer, not it is not possible unless you use hacks.

Sami,
I would loop over the items like in the example checking if there is any true, stopping when I found one. If after looping I couldn't find anything, I would show an alert.
Ed
Can someone post what their contacts.cfc looks like if they are using a query instead of the hard coding the data?

Thanks in advance,

Ed
Laura
Ed,
It's just a query:
&lt;cffunction name=&quot;getAll&quot; output=&quot;false&quot; access=&quot;public&quot; returntype=&quot;query&quot;&gt;

   &lt;cfset var allcontacts = &quot;&quot; /&gt;
   
   &lt;cfquery name=&quot;allcontacts&quot; datasource=&quot;yourDatasource&quot;&gt;
      SELECT   *, 'false' as checked
      FROM   contacts
   &lt;/cfquery&gt;

   &lt;cfreturn allcontacts /&gt;
&lt;/cffunction&gt;

You can add the checked column as I did above or:
SELECT *, checked='false'
FROM contacts

or
QueryAddColumn(allcontacts, &quot;checked&quot;, &quot;bit&quot;, arraynew(1));
Ed
Excellent. That works fine.

Thanks.

Ed
Ed
Okay, now I am ready to do delete the record from the table. Is it safe to see I can do something like so...

&lt;cfsavecontent variable=&quot;actionRemove&quot;&gt;
   var contactList = contactList;
   var confirm = function (evt)
   {
if (evt.detail == mx.controls.Alert.OK)
    {
         alert('&lt;cfoutput&gt;CONTACTLIST.ROWSTATUS.ACTION&lt;/cfoutput&gt;');
         
         &lt;cfquery datasource=&quot;dsNameHere&quot; name=&quot;deleterec&quot; &gt;
         
         &lt;!--- add delete sql here---&gt;
         
         &lt;/cfquery&gt;
         
for(var i:Number = contactList.length-1; i &gt;= 0; i--)
         {
            var item:Object = contactList.dataProvider[i];
            
            if(item.checked.toString() == &quot;true&quot;)
            {
               contactList.selectedIndex = i;
               GridData.deleteRow(contactList);
            }
         }
} else { alert(&quot;Cancel&quot;);   }
   }
   alert(&quot;Are you sure you want to remove this panorama?&quot;, &quot;Warning&quot;,
   mx.controls.Alert.OK | mx.controls.Alert.CANCEL, confirm);
   
&lt;/cfsavecontent&gt;

What I am not sure of is what I am referencing from the array of what has been selected for delete. Normally I would do like so...

DELETE FROM myTable
WHERE id = some_value

I am not sure how to get my 'some_value' once the form is submitted.

Hope this is clear.

Cheers (learning a lot!)

Ed
Ska
48. Ska wrote on November 29, 2005 at 3:44 PM
Hi-

I'm having problems getting this to work after the dataProvider has been modified via remoting to a web service. I have also tried loading all of my data into a grid and using that awesome applyFilter script from this site as well. Both seem to not post anything in the arrays (form.gridname arrays are ALL empty) after the dataProvider has been changed. It works just fine if I check the boxes and submit without filtering.

Any ideas?

Laura
Ed,
No, it does not work that way. You can't mix CF with actionscript like that. Remember that ActionScript runs in the Flash player. It is as if you would tell the flash player to execute &lt;cfquery&gt;. It won't be able to do it. In fact, if you get the query to execute, it will do it when the page loads, as it executes any code in the page. To clarify, &lt;cfsavecontent&gt; is only a way to get the actionScript script in a string and then paste in a control event handler that will execute when the ActionScript event fires in the client.
To do what you want, you will need to submit the form or call a remoting service.
I know it is strange, I hope that makes sense.

Ska,
It has been noted in the filter post that it does not work for editable grids if you want to submit it and get the arrays. There is also a fix to the filter code that does work with that. You will see that the code gets more complex because you need to do everything manually. Anyway, I would say that if you use remoting, stick with remoting, if you use submit, stick with loading the grid as normal.





DerekB
I'm populating my checkbox-grid from a cftree ala: http://www.asfusion.com/blog/entry/populating-a-cfgrid-with-flash-remoting

On submitting the form, with checkboxes checked of course, the array is empty. (The grid, in another page without the cftree, works 100%.)

Rumour is that this is a known bug in CF. Is it really?

What is the solution to passing the selected rows data to the next page, without having to rely on the array?

Thanks Laura and everyone for making this the premier place to look for Flashy forms type stuff.
Laura
DerekB,
Thank you for your comments. Regarding your question, see my answer to Ska above your comment. The same thing applies to populating the grid with remoting because you are manipulating the dataProvider directly. It is not a CF bug.
Joel
52. Joel wrote on December 07, 2005 at 9:08 AM
Is it possible to send selected records' pimary key to an &quot;action&quot; page once the user has chosen records and clicked on a submit button?

Great website by the way!

Thanks for the feedback.
Sami Hoda
53. Sami Hoda wrote on December 07, 2005 at 9:22 AM
Joel,

I've created a custom tag to do that. When I created it, I emailed it to Laura. She may want to post it on the site. It parses through what was clicked/unclicked (edited), and what was really left clicked to give you the necessary primary key for the row(s).

Let me know if you want a copy.

Sami Hoda
Ed
Sami, I am looking for this as well. Can you post or send me a copy?

Cheers,

Ed
Joel
55. Joel wrote on December 08, 2005 at 6:56 AM
Sami,

Thanks a copy of that custom tag would be great.

Joel
Sami Hoda
56. Sami Hoda wrote on December 08, 2005 at 9:35 AM
You guys will need to email me directly, so I can reply with an attachment.

samihoda &lt;at&gt; gmail &lt;dot&gt; com
Dimitry
57. Dimitry wrote on December 18, 2005 at 11:00 AM
Hi, I am a complete novice to flash forms. Can someone post a quick way to determine on the receiving template which check boxes were checked when the form was submitted? I can clearly see which were 'false' in the cfdump tag but how does it work like in reality? Hidden fields seem to be working fine if only one check box was checked but I cannot figure out a way to do the same if it were more than one. Any help will be highly appreciated.

Dimitry

Sami Hoda
58. Sami Hoda wrote on December 18, 2005 at 12:27 PM
Dimitry,

See my comment above.
Laura
Dimitry,
There is a good example in the docs:
http://livedocs.macromedia.com/coldfusion/7/htmldocs/00000266.htm
You just need to make a loop to find all the checked items.
Dimitry
60. Dimitry wrote on December 19, 2005 at 7:50 AM
Sami and Laura,

Thank you for your help. I think I'm on the right track now.

Dimitry
Brad Wood
61. Brad Wood wrote on January 03, 2006 at 8:01 AM
I am using checkboxes in a grid like this example describes:
type=&quot;boolean&quot;
The problem is, I need a click event to be fired when any of the checkboxes are clicked which tells me which one was clicked. I need this so I can update a text box with the total checked $. I tried attaching the cellPress event to the grid but that is not fired when the checkbox is clicked. I think I need to use the click event from the checkbox class, but I can't figure out for the life of me how to access the checkbox object since CF takes care of its creation. Will I need to attach an event to EVERY SINGLE check box in the grid? It will need to be dynamic since the contents of the grid may be reloaded with flash remoting at any time. Is this just way more complicated than it needs to be, or have I missed the &quot;simple boat&quot; :)
Please advise if you have any ideas.
MrBuzzy
62. MrBuzzy wrote on January 30, 2006 at 2:08 PM
Hi, is it possible to have a column of check boxes but have the rest of the columns not editable? It seem the only way to enable them is by having the who column editable (selectmode=edit).

Thanks in anticipation.
Brad Wood
63. Brad Wood wrote on January 30, 2006 at 2:15 PM
MrBuzzy,

Here's what I did to accomplish that:

selectmode=&quot;edit&quot; in my cfgrid tag and

select=&quot;no&quot; in EVERY cfgridcolumn tab BUT the checkbox.

Basicaly, you are turning &quot;on&quot; all the whole grid, and then turning &quot;off&quot; all but one column.

On a side note, some grid events like cells gaining focus aren't fired unless the cell is enabled.
nicetim
this is awesome..
can i fire a function when the checkbox is clicked?

thanks
tim
Justin Schier
Hi -
Thanks for this AWESOME stuff - it has helped me so much.

I would like to check to see than no more than 10 checkboxes are checked before the form can be submitted. In other words, if 12 checkboxes are checked by the user, an error should pop up saying &quot;please check max 10 checkboxes&quot;. Even better, as soon as the 11th checkbox is checked, the error should pop up and disallow the check.

Is there an easy way to do this?

Thanks very much,
Justin Schier
Yogesh Mahadnac
66. Yogesh Mahadnac wrote on February 18, 2006 at 10:27 PM
Hi Laura,

I'm using only remoting (as you've advised Ed to do in one of your posts). However, I'm having a bug at the moment, and I really don't know how to solve it. I'd be very much grateful if you could please help me out.
Ok, so here goes...

I have a button with a &quot;-&quot; (minus) label on it and when I click on this button, it should remove the checked items from my grid. The onClick event triggers the following function:

public function delFromGrid():Void {
var myGrid = myGrid;
var confirm = function (evt)
{
   if(evt.detail == mx.controls.Alert.YES)
   {
   for(var i:Number = myGrid.length - 1; i &gt;= 0; i--)
   {
    if(myGrid.getItemAt(i).checked.toString() == &quot;true&quot;) {
      myGrid.selectedIndex = i;
      alert(&quot;id: &quot;+myGrid.getItemAt(i).id); //it alerts the id correctly
                           //make a call to my CFC to flag the selected id
      var myID:Number = myGrid.getItemAt(i).id;
      myForm.myGlobalObjects.myCFCName.delRecord(myID);
//it never calls this function, and I really don't know why
                     
                     GridData.deleteRow(myGrid);

      }
               }
               
            }
         }
         alert(&quot;Are you sure you want to remove the selected record?&quot;, &quot;Warning&quot;,
         mx.controls.Alert.YES | mx.controls.Alert.NO, confirm);
      }

Now, the bug is:
You will notice the following line of code
myForm.myGlobalObjects.myCFCName.delRecord(myID);
But this piece of code is NEVER executed!
The part alert(&quot;id: &quot;+myGrid.getItemAt(i).id); is working, and even the GridData.deleteRow(myGrid); is working but not the call to my CFC!

And since I'm not submitting anything, I can't obviously check whether the gridName.ROWSTATUS.ACTION is &quot;D&quot; to process the deletion of the record id from my database.

I've also tried the following istead:

            if(myGrid.getItemAt(i).checked.toString() == &quot;true&quot;)
            {
               myGrid.selectedIndex = i;
               alert(&quot;id: &quot;+myGrid.getItemAt(i).id);
               
               //make a call to my CFC to flag the selected id
               var myID:Number = myGrid.getItemAt(i).id;
               
               //create a function to test whether the myID can be passed to another function
               checkID(myID);
               
               GridData.deleteRow(myGrid);
            }


And then in my function checkID, I do:

&lt;!--- Function to process id to be deleted ---&gt;
public function checkID( id:Number):Void {
   alert(&quot;received id: &quot;+id+&quot; from grid&quot;);
}

But it never alerts the id!!

So, I'm a bit stuck with this at the moment and I really can't figure out why this is not working at all!

The funny thing is, likewise, I have another button labelled &quot;+&quot; to add records to the grid using a function called addToGrid, and inside this function I call another function called buildData() which actually calls my CFC to insert the record to my database, and this works!!!

I'd be very much grateful if you could please help me sort out this problem.

Thanks and regards,
Yogesh Mahadnac
Yogesh Mahadnac
67. Yogesh Mahadnac wrote on February 19, 2006 at 9:48 PM
Hi, it's me again!

Actually I've figured out the solution and I wanted to share it with all of you here ;-)

Instead of just checkID(myID); I only needed to do _root.checkID(myID); and this did the trick.

Hope this helps you all.

Regards,
Yogesh Mahadnac
MJE
68. MJE wrote on March 03, 2006 at 4:37 PM
Hello,

Can someone please help me out? I am trying to retrieve the value of the items selected via AS, similar to fieldName.text, and while it's easy to retrieve the value with a regular form submission, I'm using flash remoting to insert the values into the db, and have not been able to figure out the right way to retrieve the values.

I've been trying
gridName.columnName
gridName.dataProvider.columnName
etc...
but nothing works! Please help!
MJE
69. MJE wrote on March 03, 2006 at 5:45 PM
I should clarify that basically I'm trying to retrieve the equivalent of the contactList.firstName array that is rendered when you hit submit, but via AS without hitting the submit button.

I would like to either retrieve a list or an array that I can use to populate the database, based on what has been checked in the cfgrid.

I have also tried to create a function that loops over the ids and populate those into a variable as a list, but I'm totally stuck there too.

When I used this, it showed me that the IDs I selected were 2 and 7, but one value was inserted into the database, which was a -1!


for(var i:Number = grid.length - 1; i &gt;= 0; i--)
{
if(grid.getItemAt(i).id == &quot;true&quot;)
      {
   grid.selectedIndex = i;
   alert(&quot;id: &quot;+grid.getItemAt(i).metlID);
   addArguments.theList= grid.getItemAt(i).id;
      }
   
}

Please, please help! :)
Yogesh Mahadnac
70. Yogesh Mahadnac wrote on March 04, 2006 at 3:41 AM
Ok, I've done something similar, so maybe the following might help you.

In my flash form I have a small button which I've labelled &quot;Add&quot; to add items to the grid

&lt;cfinput type = &quot;button&quot; name=&quot;plus_pb&quot; value = &quot;Add&quot; onclick=&quot;addToGrid();&quot; tabindex=&quot;7&quot;&gt;

Now when I click on the &quot;Add&quot; button the following code is executed within my &lt;cfformitem type=&quot;script&quot;&gt;

&lt;/cfformitem&gt;


public function addToGrid():void {

var found = 0;
for(var i:Number = 0;i &lt; myGrid.length;i++)
{
   if(
   (myGrid.getItemAt(i).adjustment_date == date_txf.text) and
   (myGrid.getItemAt(i).id_broker == broker_cb.selectedItem.data) and
   (myGrid.getItemAt(i).id_currency == currency_cb.selectedItem.data) and
   (myGrid.getItemAt(i).id_adjustment_type == adjustment_cb.selectedItem.data) and
   (myGrid.getItemAt(i).adjustment_description == mydesc) and
   (myGrid.getItemAt(i).adjusted_amount == amount_txf.text)
   )
   {
      found = 1;
      alert(&quot;This adjustment already exists in the grid&quot;);
      break;
   }
}

if(found == 0)
{
   buildData();
}

}


Now, in my buildData function, I do the following:

public function buildData():Void{
   &lt;!--- Create structure ---&gt;
   var myData:Object = {};
   myData.adjustment_date = date_txf.text;
   myData.id_broker = broker_cb.selectedItem.data;
   myData.id_currency = currency_cb.selectedItem.data;
   myData.id_adjustment_type = adjustment_cb.selectedItem.data;
   myData.adjustment_description = mytxt;
   myData.adjusted_amount = amount_txf.text;
   
   &lt;!--- Make a call to add record to db ---&gt;
   if( mx.validators.Validator.isStructureValid(this, 'myForm') ){
      
      &lt;!--- Set busy cursor ---&gt;
      mx.managers.CursorManager.setBusyCursor();
      
      myForm.myGlobalObjects.adjustment.create(myData);
   }
}


Finally, in my CFC (adjustment.cfc)

&lt;cffunction name=&quot;create&quot; access=&quot;remote&quot; returntype=&quot;void&quot;&gt;

   &lt;cfargument name=&quot;adjustment_date&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;
   &lt;cfargument name=&quot;id_broker&quot; type=&quot;numeric&quot; required=&quot;yes&quot;&gt;
   &lt;cfargument name=&quot;id_currency&quot; type=&quot;numeric&quot; required=&quot;yes&quot;&gt;
   &lt;cfargument name=&quot;id_adjustment_type&quot; type=&quot;numeric&quot; required=&quot;yes&quot;&gt;
   &lt;cfargument name=&quot;adjustment_description&quot; type=&quot;string&quot; required=&quot;yes&quot;&gt;
   &lt;cfargument name=&quot;adjusted_amount&quot; type=&quot;numeric&quot; required=&quot;yes&quot;&gt;
   &lt;cfset locale = #SetLocale(&quot;English (UK)&quot;)#&gt;

&lt;!--- Each cfargument represents the corresponding &quot;field&quot; I've used in myData in the function buildData ---&gt;


&lt;/cffunction&gt;

If you need any further help, please don't hesitate to contact me on yogeshm@mail.com

Regards,
MJE
71. MJE wrote on March 04, 2006 at 7:54 AM
Thanks so much for your reply Yogesh,

Most of what you have, I also have done very similarly, and all of my values are inserting into the database fine, with the exception of the checkbox values from the grid.

The whole issue is that in this function, I would like to retreive the values of the checkboxes selected in the grid via ActionScript.

public function submitTask():Void {
   var addArguments:Object = {};
   
   &lt;!--- simple text inputs ---&gt;
   addArguments.taskName = taskName.text;
   addArguments.taskComments = taskComments.text;
   addArguments.taskPublication = taskPublication.text;
   addArguments.taskParagraph = taskParagraph.text;
   addArguments.wucIndex = wucIndex.text;
   addArguments.wuc = wuc.text;
   
   &lt;!--- radio button (e.g. addArguments.status = edit_status.selectedData;) ---&gt;
   
      //addArguments.myGrid= myGrid.id
   &lt;!--- need to do something different for myGrid grid to retrieve values --- but what??? - the following doesn't work---&gt;
    for(var i:Number = myGrid.length - 1; i &gt;= 0; i--)
{
if(myGrid.getItemAt(i).id == &quot;true&quot;)
      {
   myGrid.selectedIndex = i;
   alert(&quot;id: &quot;+myGrid.getItemAt(i).id); //this shows the id number
   addArguments.myGrid= myGrid.getItemAt(i).id;
      }
   
}
   
   &lt;!--- dropdowns ---&gt;
   addArguments.system = system.value;
   addArguments.type = type.value;    addArguments.jobGuide = jobGuide.text;
   
   &lt;!--- only make call if all required fields are supplied ---&gt;
   if( mx.validators.Validator.isStructureValid(this, 'myForm') ){
      &lt;!--- show clock cursor ---&gt;
      mx.managers.CursorManager.setBusyCursor();
&lt;!--- call service and insert data - this references the inc/myService.cfc ---&gt;
      myForm.myGlobalObjects.myService.create(addArguments);
   }
}


This is the grid that the values are being captured from:

&lt;cfgrid name=&quot;myGrid&quot; rowHeight=&quot;100&quot; rowheaders=&quot;false&quot; query=&quot;getData&quot; width=&quot;625&quot; height=&quot;350&quot; selectmode=&quot;edit&quot;&gt;
&lt;cfgridcolumn name=&quot;id&quot; header=&quot;Select&quot; type=&quot;boolean&quot; width=&quot;46&quot;&gt;   
&lt;cfgridcolumn header=&quot;Title of Data&quot; name=&quot;dataText&quot; select=&quot;no&quot; &gt;   
&lt;/cfgrid&gt;

How can I capture these values in the submitTask() function above?

Thanks again for the help!
Yogesh Mahadnac
72. Yogesh Mahadnac wrote on March 05, 2006 at 1:59 AM
Ok, to retrieve the values of the checkboxes, maybe you can try the following:

public function submitTask():Void {
var myGrid = myGrid;

for(var i:Number = 0; i &lt; myGrid.length; i++)
{
   if(myGrid.getItemAt(i).id.toString() == &quot;true&quot;)
   {
      var idx:Number = i;
      myGrid.selectedIndex = idx;
      
      var myID:Number = myGrid.getItemAt(idx).id; //here maybe you will have to change Number to String
      
      alert(&quot;id where checkbox is checked: &quot;+myID);
   }
}

}

Hope this helps.

Else you can contact me on yogeshm@mail.com

Good luck!
MJE
73. MJE wrote on March 05, 2006 at 10:56 AM
Thanks again Yogesh,

The code you provided however, is exactly what I'm using already (just using different syntax). Take a look at the code that I submitted in my last post.

It only saves one value at a time. I need to capture ALL of the values in a list or an array - for instance, if the user selected items 1, 3 and 5 out of the options 1,2,3,4,5,6,7,8 - I want to end up with a resulting list of:

addArguments.myGrid= &quot;1,3,5&quot; once it has been captured.

If someone can please help, I would greatly appreciate it!


Yogesh Mahadnac
74. Yogesh Mahadnac wrote on March 05, 2006 at 10:32 PM
Ok, maybe you can try the following:

public function submitTask():Void {
var myGrid = myGrid;
var myList:String = &quot;&quot;;

for(var i:Number = 0; i &lt; myGrid.length; i++)
{
if(myGrid.getItemAt(i).id.toString() == &quot;true&quot;)
{
var idx:Number = i;
myGrid.selectedIndex = idx;

var myID:Number = myGrid.getItemAt(idx).id; //here maybe you will have to change Number to String
myList = myList + myGrid.getItemAt(idx).id + &quot;,&quot;;
alert(&quot;id where checkbox is checked: &quot;+myID);
}
}

myList = myList.substr(myList.length,-1);
//then you can add mylist to your variable
addArguments.yourVariableName = myList;

}

Hope this helps.

Regards
MJE
75. MJE wrote on March 07, 2006 at 12:31 PM
Thanks again for your efforts Yogesh,

Unfortunately this isn't doing the trick either. I know there has to be a way to get these values in a list or an array - what am I missing??
Laura
MJE,
I am not completely sure about what you want to do, but if what you want is to get the checked id in an array, you would do something like (assume you have an id column):

var selectedIds:Array = [];
for(var i:Number = 0; i &lt; contactList.length; i++){
var item:Object = contactList.getItemAt(i);

if(item.checked.toString() == &quot;true&quot;) {
selectedIds.push(item.id);
}
}
This will give you an array will all the ids of the checked items.

Actually, I just found a function that I wrote some time ago to which you can pass the name of the column you want the array to be populate with.

public function getSelectedItems(grid:mx.controls.DataGrid, checkColumn:String, column:String):Array{
   var selected:Array = [];
   for(var i:Number = grid.length-1; i &gt;= 0; i--) {
      var item:Object = grid.getItemAt(i);
      
if(item[checkColumn].toString() == &quot;true&quot;) {
         selected.push(item[column]);
}
}
return selected;
}

checkcolumn is the name of the column that contains the checkbox, and the column is say &quot;id&quot; or &quot;lastName&quot;, whatever you want your array to have.
MJE
77. MJE wrote on March 07, 2006 at 3:52 PM
Hi Laura,

Thanks so much! I'm sure this is on the right track, and I'm probably using it wrong. I'll try to be more clear about exactly what I'm trying to do. When referencing this &quot;CheckBoxes in a cfgrid example&quot;, if you load it and check Alan and Andy, for example and then hit submit, the contactList.lastName array is returned with the values of Alan and Andy. That is what I want to retrieve via AS.

Referring to your Real Estate Sample Application, you capture the flash remoting variables to be populated into the database when the user submits the form. However, since the &quot;submit&quot; is not taking place, the contactList array isn't retreived. In your Real Estate example, you have a section where all of the values of entered data are captured - on the index.cfm page in the :

public function submitEdit():Void {
   var editArguments:Object = {};
   
   &lt;!--- simple text inputs ---&gt;
   editArguments.mls_id = edit_mls_id.text;
&lt;!--- radio button ---&gt;
   editArguments.status = edit_status.selectedData;
&lt;!--- checkboxes ---&gt;
   editArguments.hasPool = edit_hasPool.selected;
ETC....
   }
   }
}

Basically I am trying to set the editArguments.dataGridValuesThatWereChecked
to pass in the editArguments function.

I tried using the example that you submitted and somehow it hung the whole form. This is what I tried to use:

public function getSelectedItems(metlList:mx.controls.DataGrid, id:String, metlID:String):Array{
   var selected:Array = [];
   for(var i:Number = metlList.length-1; i &gt;= 0; i--) {
      var item:Object = metlList.getItemAt(i);
      
if(item[id].toString() == &quot;true&quot;) {
         selected.push(item[metlID]);
}
}
return selected;
alert(&quot;ids selected: &quot;+selected; //it hangs with or without this line}

This is the grid that I'm working with:

&lt;cfgrid name=&quot;metlList&quot; rowHeight=&quot;100&quot; rowheaders=&quot;false&quot; query=&quot;getMetls&quot; width=&quot;625&quot; height=&quot;350&quot; selectmode=&quot;edit&quot;&gt;
&lt;cfgridcolumn name=&quot;id&quot; header=&quot;Select&quot; type=&quot;boolean&quot; width=&quot;46&quot;&gt;   
&lt;cfgridcolumn header=&quot;METL ID&quot; name=&quot;metlID&quot; display=&quot;false&quot;/&gt;
&lt;cfgridcolumn header=&quot;METL&quot; name=&quot;metlText&quot; select=&quot;no&quot; &gt;   
&lt;/cfgrid&gt;

Hopefully this helps to clarify what I'm trying to do. Ultimately, I would like the list of metlIDs in a list or an array.

If you can help I would be SO grateful!! Thanks again for all of your efforts on this site - it is my main resource for developing cf flash form apps!
daniel fredereicks
Ok, so I have tried and tried to figure this out. I am using flash remoting to populate my grid. One of my columns is a checkbox. I want to dynamically &quot;check&quot; the checkbox if the data in the database is true. I can't seem to get it to work. I am looping over the data, but can't find the code to put inside the loop to select the checkbox.
Drew
79. Drew wrote on March 23, 2006 at 5:01 PM
Hi everyone,
Firstly...fantastic site Laura. Been here countless times in the past month as all google paths lead me here :).

My question is the same as Brad Wood asked above, yet as I see no reply to his post I'm gathering that it's not possible to fire an event on the checkbox object.

Can someone tell me definitively that this is the case? I will then can my nice flashy grid for now and move on.

Also, I've heard that Flex now uses a superior version of AS than cfform does. Is this true and do we think cfform will follow flex and use the same platform.
BillCupps
I noticed in a post a while back that someone else asked if there is a way to catch the click of a checkbox in a grid. Has anyone come up with a solution to this? I can capture that the user clicked on a different row with the onChange of the grid. But if the user just clicks on a checkbox that event doesn't fire. I've tried adding a listener in the onLoad. And while it works for the load, it still does not fire if the user just clicks on an editable checkbox in a grid.

var listener:Object = {};
var grid1:mx.controls.DataGrid = grid1;
       
listener.modelChanged = function(evt):Void {
if (grid1.dataProvider.length){
                grid1.selectedIndex = 0;
                     _root.updateGridAll();
}
}
grid1.addEventListener('modelChanged',listener);

Any ideas?
Edgar Febres
81. Edgar Febres wrote on April 17, 2006 at 9:47 AM
I'm trying to get this to work, but for some reason my grid doesn't get populated. I have this sample installed on two servers. One Windows2003 and the other RedHat EL 4.0. It works on the Win Machine but not on the RedHat. Furthermore, it will display on a PC but it won't display the grid at all on a Mac with Firefox on it.

Any ideas what is going on on the server side that I should be looking into?
Joseph Abenhaim
82. Joseph Abenhaim wrote on May 08, 2006 at 9:39 AM
Just out of curiousity, say i have a grid with a checkbox and a field name itemNumber, how would i pass items selected to a component using remoting. I can do it with simple text objects etc... but i havent been able to with a grid.
Vikrant
83. Vikrant wrote on May 26, 2006 at 5:20 PM
First off, GREAT site!!!!

I have been toying around with the grid filtering and this example. I was wondering if anyone has filtered another grid by what was selected by a checkbox in a secondary grid by means of a button.

Populate grid1 with information from a query. I would like to then select specific rows of that grid and click a Selection button and pass the selected information to grid2.
Basically filtering the next grid on if the checked box is true.

I am new to this and still digesting how the the applyFilter accually works in the grid filtering example.

Any info you can provide would be great.

-Vik
Patrick
84. Patrick wrote on June 07, 2006 at 6:40 PM
I'll start by also saying this site is awesome!!

Now onto my question...

I've got a checkbox in my grid and i want to disable some of the based on who they are. However, I'm not sure how to reference the checkboxes in the grid... Here's my code:

<cfform name="myform" width="600" format="Flash" action="saveFile.cfm?oppID=#oppID#" skin="haloorange" timeout="100" enctype="multipart/form-data" onload="onFormLoad();">

   <cfformgroup type="tabnavigator">
   <cfformgroup label="Attachments" type="page">
   
   
   <cfformgroup label="Current Attachments" type="panel">
   
<cfformitem type="script">
<!--- onload function --->
function onFormLoad(){
var listener:Object = {};

//put the controls in scope to avoid calling _root

var attachmentList:mx.controls.DataGrid = attachmentList;

listener.modelChanged = function(evt):Void {

attachmentList.removeEventListener('modelChanged',listener);
<!--- select first item --->
if (attachmentList.dataProvider.length){
          for(var i:Number = 0; i < attachmentList.dataProvider.length; i++) {
            if(attachmentList.dataProvider[i].AttachOwner.toString() == 'haj') { //enable checkbox }
   else { //disable checkbox }
         }
}
}

attachmentList.addEventListener('modelChanged',listener);
}
</cfformitem>


   
   
   <cfformitem type="text" style="color:##FF0000;">** Click on file name to view attachment **</cfformitem>
   
   <cfgrid name="attachmentList" query="attachmentsQuery" height="220" rowheaders="false"
               selectmode="edit" onchange="#launchAttachment#">

            <cfgridcolumn name="checked" header="Delete" type="boolean" width="46" >
            <cfgridcolumn name="AttachOwner" display="yes" select="no">
            <cfgridcolumn name="AttachID" display="no">
            <cfgridcolumn name="AttachName" header="Attachment" select="no" />   
            <cfgridcolumn name="Name" header="Attached By" select="no" />
            <cfgridcolumn name="DateTimeKey" header="Attach Date" mask="MM/DD/YYYY" select="