Our Blog

I mentioned in the post Adding the values of a cfgrid column that if we need to loop over many rows in the cfgrid, we may receive the "A script in this movie is causing Flash Player to run slowly" alert from the Flash Player. In order to avoid that, we’ll separate the task in frames:

<cfsavecontent variable="changePrice">
   var newPrice = Number(amount.text);
   var i = 0;
   
   //make the loop with onEnterFrame instead of a "for"

   _root.onEnterFrame = function ()
   {
      if(i < productsGrid.length) {
         //do one iteration of the loop

         _root.updatePrice(i);
         i++;
      }
      else {
         //end the loop

         _root.onEnterFrame = undefined;         
      }
   }
   
   //this is the function that does whatever we need in each iteration

   _root.updatePrice = function (index){
         //edit the row

         productsGrid.editField(index, 'price', Number(productsGrid.getItemAt(index)['price']) + newPrice);
         //change the color of the edited row
         productsGrid.setPropertiesAt(index, {backgroundColor:0xF7FFB7});
   }   
</cfsavecontent>

<cfform name="myForm" format="flash">
   <cfgrid name= "productsGrid" query="products">
      <cfgridcolumn name="name" header="Product">
      <cfgridcolumn name="price" header="Price" type="numeric">
   </cfgrid>
   <cfinput type="text" name="amount">
   <cfinput type="button" name="updateBtn" value="Update" onclick="#changePrice#">
</cfform>

Live example
Download the source

Laura

Laura

19 Comments

  1. Webdevotion
    Can't you use grid.dataprovider ?
    First loop over the data, edit it, then
    set grid.dataprovider at once.
    This is more efficient than editing
    1 row at a time.
  2. Eric Snowden

    Eric Snowden

    I am trying something very similar but with no luck. I am trying to uncheck or check all the checkboxes in a column of a datagrid. I got it to work using the tracer found on cf_pim but can't get to work in the actual site. Here is my code...

    &lt;cfsavecontent variable=&quot;uncheck&quot;&gt;
    _root.onEnterFrame = function() {
       if (i &lt; _root.myGrid.length) {
          _root.myGrid.editField(i, 'send', false);
          i++;
       } else {
          _root.onEnterFrame = undefined;
       }
    };
    &lt;/cfsavecontent&gt;

    &lt;cfform format=&quot;flash&quot; name=&quot;flashForm&quot; width=&quot;540&quot; height=&quot;580&quot; skin=&quot;halosilver&quot;&gt;
    &lt;cfgrid name=&quot;myGrid&quot; Format=&quot;flash&quot; query=&quot;q_mailingList&quot; selectmode=&quot;edit&quot; delete=&quot;yes&quot; insert=&quot;yes&quot; fontsize=&quot;10&quot; rowheight=&quot;25&quot; gridlines=&quot;yes&quot; colheaders=&quot;yes&quot; height=&quot;500&quot;&gt;
       &lt;cfgridcolumn header=&quot;id&quot; name=&quot;listID&quot; display=&quot;no&quot;&gt;
       &lt;cfgridcolumn header=&quot;LAST NAME&quot; name=&quot;lastName&quot;&gt;
       &lt;cfgridcolumn header=&quot;FIRST NAME&quot; name=&quot;firstName&quot;&gt;
       &lt;cfgridcolumn header=&quot;EMAIL&quot; name=&quot;email&quot; width=&quot;185&quot;&gt;
       &lt;cfgridcolumn header=&quot;DATE ADDED&quot; name=&quot;date&quot; width=&quot;80&quot; select =&quot;no&quot;&gt;
       &lt;cfgridcolumn header=&quot;SEND EMAIL&quot; name=&quot;send&quot; width=&quot;80&quot; type=&quot;boolean&quot;&gt;
    &lt;/cfgrid&gt;
    &lt;cfformgroup type=&quot;horizontal&quot;&gt;
    &lt;cfinput type=&quot;button&quot; name=&quot;uncheckAll&quot; value=&quot;UNCHECK ALL&quot; onclick=&quot;#uncheck#&quot;&gt;
    &lt;/cfformgroup&gt;
    &lt;cfformgroup type=&quot;horizontal&quot;&gt;
    &lt;cfinput type=&quot;submit&quot; name=&quot;gridEntered&quot; value=&quot;SAVE&quot;&gt;
    &lt;/cfformgroup&gt;
    &lt;/cfform&gt;

    If you could help me out that would be greatly appreciated. Thanks!

    Eric
  3. Laura
    Webdevotion,
    yes, you can use dataprovider and it will definitely be faster. I wanted to give the user some kind of visual indication that the something was happening, so that is why I edit each row. In the other case, we could pop an alert when the process was finished.
    You can also make a small loop (ie: 5 iterations) inside the onEnterFrame function to edit more than one row each time to make it faster.
  4. Laura
    Eric,
    Your code is working for me. I only needed to declare the variable i before using it. Also make sure that the column send in your db (or query) has the same case as in the AS code.

    var i = 0;
    _root.onEnterFrame = function() {
    .......
    }
  5. Casey
    I have a cfgrid in a form. The cfgrid is not required and I would like to have a reset button if someone accidentally highlights a row and they don't want that option anymore in the form. How do I do that? I tried this uncheck code and was unsuccessful. I have also searched many forums on the web. thanks
  6. Casey A

    Casey A

    Hi all,

    Trying to get a simplified version of this to work...Any help will be appreciated!

    &lt;cfquery name=&quot;products&quot; datasource=&quot;#application.dsn.oiws#&quot;&gt;

       SELECT *
       FROM tbl_List360
       ORDER BY lastName
       
    &lt;/cfquery&gt;

    &lt;cfoutput&gt;
    &lt;body&gt;
    &lt;cfform name=&quot;myForm&quot; format=&quot;flash&quot; width=&quot;350&quot; height=&quot;250&quot;&gt;
    &lt;cfformgroup type=&quot;vBox&quot;&gt;
       
       &lt;cfgrid name= &quot;cart&quot; query=&quot;products&quot; height=&quot;150&quot; rowheaders=&quot;false&quot; selectmode=&quot;edit&quot;&gt;
             &lt;cfgridcolumn name=&quot;RACF&quot; header=&quot;Product&quot; select=&quot;true&quot;&gt;
          &lt;/cfgrid&gt;
       &lt;/cfformgroup&gt;
    &lt;/cfform&gt;
    &lt;/body&gt;
    &lt;/cfoutput&gt;
  7. Casey A

    Casey A

    Add a bit more to my situation...
    Our back end is SQL Server, in this table are several records. I want to give the user the ability to edit specific fields in this dataset through the cfform. What I've ran into so far is that the dataset is not populating the form. It feels like I'm missing a cfloop, or something to populate the form (at this point the form returns blank).
  8. Casey A

    Casey A

    Glad to say that this issue is resolved outside of a strange error that seems to be an issue with the software, not my coding. Thanks!
  9. Rick
    I am having a hell of a time, passing the grid object data to my &quot;flashRemotingResponder.cfc&quot; file, whats the best way to pass that?
  10. mafdoc
    I would also like to have a reset button if someone accidentally highlights a row on the grid. How do I do that? I also tried this uncheck code and was unsuccessful. I have also searched many forums on the web.
    Anybody come up with something?
    If you could tell me what to look for in AS.
  11. Rick,
    If you want to send the items of a grid you should send it like this:
    myGrid.dataProvider.items

    Mafdoc,
    You can unselect the grid with this code:
    myGrid.selectedIndex = undefined;
  12. Trevor Orr

    Trevor Orr

    Anyone have any idea how to get the status of a checkbox in a cfgrid? I have tried MANY different ways and can not get it. Any help would be greatly appreciated.
  13. mafdoc
    Thanks for the update!!
    I added this
    myGrid.selectedIndex = undefined;
    and
    myfieldnames.text =&quot;&quot;;
    and when the button is clicked
    all the fields and the grid are cleared.
    Thanks again.
  14. Ray
    Is there a way to loop over all the data in the grid and save it into a database??

    My situation is this: I have two cfgrids, both are populated via a query. You can click on a row in the first grid and add it to the second grid. Then I want to be able to save the data the is added to the second grid into the database. Is this possible? I'm sure it's similar to what you guys have written here, but I'm not sure exactly how to use it.

    Here is my code of my two grids:
    <cfformgroup type="horizontal">
             <!---<cfformitem type="text">Existing Users</cfformitem>--->
             <!--- Testing how a CFGRID will work ---> <!--- Testing how a CFGRID will work --->
              <cfgrid name="user_grid" query="getEmployees" selectmode="row" colheaders="yes"
                 rowheaders="no" width="250" height="200" format="Flash" onChange="#gridChange#">

                <cfgridcolumn name="EmpID" header="Employee ID" display="no">
                <cfgridcolumn name="Last_Name" header="Last Name">
                <cfgridcolumn name="First_Name" header="First Name">
                <cfgridcolumn name="Phone_Number" header="Phone Number" display="no">
                <!---<cfgridcolumn name="UserLevel" header="User Level" display="no">--->
                <!---<cfgridcolumn name="OffAbbr" header="Office" display="no">--->
              </cfgrid>
             
             
             <!---<cfformitem type="text">Users Assigned to the Project</cfformitem>--->
             <!--- Testing 2nd CFGRID --->
             <cfgrid name="user2_grid" query="choosenUsers" rowheaders="no" width="400" height="200" format="flash">
                <cfgridcolumn name="EmpID" header="Employee ID" display="no">
                <cfgridcolumn name="Last_Name" header="Last Name">
                <cfgridcolumn name="First_Name" header="First Name">
                <cfgridcolumn name="Phone_Number" header="Phone Number" mask="(999)999-9999" display="no">
                <cfgridcolumn name="UserLevel" header="User Level">
                <cfgridcolumn name="OffAbbr" header="Office">
             </cfgrid>
          
          </cfformgroup><!--- End Two Grids --->


    Any help is appreciated.

    Thanks!!
  15. Michael White

    Michael White

    I would like to process checked items on a grid that contains over 1000 records without timing out. I have two problems, one is the "Check All" function that loops through the grid and problem two is the processing page that takes the array from the form object and updates the records in the database. it works fine with < 800 records but beyond that I get the slow form warning. So what is the fastest way? I don't need any alerts or feedback, just zip through.
  16. Case
    Is there a way to change properties (like background color) of a particular cell in a grid (not whole row)?
    Thanks in advance
    Case
  17. Benjamin

    Benjamin

    Laura, thank you for the code, i was looking for something like that.

    My 5 cents :

    You can add a "kind of" counter in your form, something like :

    <cfinput type="Text"
    name="counter"
    required="No"
    visible="No"
    enabled="No"
    size="15"
    style="text-align:center;borderStyle:none;disabledColor:#000000;background-color:transparent;">

    and then, in your cfsavecontent :

    var newPrice = Number(amount.text);
    var i = 0;
    _root.onEnterFrame = function ()
    {
    _root.counter.visible = true;
    if(i < productsGrid.length) {
    _root.counter.text = "Processing " + i + " rows ...";
    _root.updatePrice(i);
    i++;
    }
    else {
    _root.counter.visible = false;
    _root.onEnterFrame = undefined;
    }
    }

    Hope this helps !
  18. John
    I'm trying to run this example, but instead of using a local "querynew" function, I'm retrieving data from an Oracle database. However, when I loop over the datagrid rows, I get a null for the values. Can anyone help me with this?
    Here is the function call to loop through the datagrid rows:

    <cfsavecontent variable="calculateTotal">
       var totalAmount = 0;
       var item;
       var subTotal = 0;
       var itemStr:String = "foo";

       for(var i = 0; i < cart.length; i++) {
          item = cart.getItemAt(i);
          //get subtotal
          subTotal = number(item['price']) * item['quantity'];
          itemStr = itemStr + ':' + item['name'].toString();

          //tally up the amount
          totalAmount += subTotal;

          //change the subtotal column for this row
          cart.editField(i, 'amount', subTotal);
       }
       //show the total
       total.text = totalAmount;
       names.text = itemStr;
    </cfsavecontent>
  19. John
    I'm trying to run this example, but instead of using a local "querynew" function, I'm retrieving data from an Oracle database. However, when I loop over the datagrid rows, I get a null for the values. Can anyone help me with this?
    Here is the function call to loop through the datagrid rows:

    <cfsavecontent variable="calculateTotal">
       var totalAmount = 0;
       var item;
       var subTotal = 0;
       var itemStr:String = "foo";

       for(var i = 0; i < cart.length; i++) {
          item = cart.getItemAt(i);
          //get subtotal
          subTotal = number(item['price']) * item['quantity'];
          itemStr = itemStr + ':' + item['name'].toString();

          //tally up the amount
          totalAmount += subTotal;

          //change the subtotal column for this row
          cart.editField(i, 'amount', subTotal);
       }
       //show the total
       total.text = totalAmount;
       names.text = itemStr;
    </cfsavecontent>