Our Blog

We were asked about solving the problem of adding the values of a column in a flash cfgrid, so we made an example in response.

The cfgrid shows the items of a shopping cart. The quantity column is editable, so we can change the number of items we want to buy. Then, we click "Calculate Order" and the total shows at the bottom. Although we are triggering the addition at the button's onclick event, we could do the same at the cfgrid onchange. The relevant part is when we get the column value and add it to the total.

To get a specific column in row i:

cart.getItemAt(i)['price']; //where price is the name of the column and cart is the name of the grid

In addition, we are changing the value of the subtotal column with the price multiplied by the quantity in row i:

cart.editField(i, 'amount', subTotal); //where amount is the name of the column we want to edit

The complete code:

<cfsavecontent variable="calculateTotal">
   var totalAmount = 0;
   var item;
   var subTotal = 0;
   
   for(var i = 0; i < cart.length; i++) {
      item = cart.getItemAt(i);

      //get subtotal

      subTotal = number(item['price']) * item['quantity'];
      
      //tally the amount up

      totalAmount += subTotal;
      
      //change the subtotal column for this row

      cart.editField(i, 'amount', subTotal);
   }
   //show the total

   total.text = totalAmount;
</cfsavecontent>

<cfform name="myForm" format="flash">
   <cfgrid name= "cart" query="products" rowheaders="false" selectmode="edit">
      <cfgridcolumn name="price" display="No">
      <cfgridcolumn name="name" header="Product" select="false">
      <cfgridcolumn name="quantity" header="Quantity" type="numeric" width="60" dataalign="right" >               
      <cfgridcolumn name="amount" header="Subtotal" type="currency" dataalign="right" select="false" width="60">
   </cfgrid>

   <cfinput type="Button" name="calculateBtn" value="Calculate Order" onclick="#calculateTotal#">
   <cfinput type="Text" name="total" disabled="true" label="Total $" size="5">
</cfform>

Note that if we have many rows this may not be the best method as it may cause the "A script in this movie is causing Flash Player to run slowly" alert. We can avoid it by using a different technique. More on that in my next post.

Live example
Download the source

Laura

Laura

28 Comments

  1. Trond Ulseth
    Hi,

    As usuall you guys continue to impress with pushing the limits of what is possible with cfforms.

    This post partly answers a question that were asked in a IRC room the other day, but the question there was not only if you can change the value in a cfgrid, but if you could have dropdown list of values to choose from.

    I answered that I've never seen it done, but since your example here is part of the way I thought I'd ask what you think. Do you think it's possible?
  2. Mike
    Thank you guys for answering my question! I'm very impressed ;) I love your work with cfforms - keep up the good work!
  3. Chad Yang

    Chad Yang

    Hi there,
    I'm really impressed with your excellent skills at using flash form,cfgrid. And with the "
    onload" example posted before, i have got some ideas of dynamically setting color of a specific row of cfgrid. However, it's not working by combing "onload" and "setting property of cfgrid", do you have any suggestions?
    By the way, how do you know the function of setting some properties of a certain flash form control, such as "setProperty()"?
    Thanks in advance :)
  4. Nahuel
    Chad Yang,
    What you are trying to achieve is difficult because the onload is called before the data in the datagrid is received (the data and the form do not load at the same time). When you change the property of a row, you are changing a empty datagrid. Later, when the data arrives, it overwrites all the changes ( I think that is the problem )
  5. Yami
    Thanks Laura. This here code:
    "cart.getItemAt(i)['price'];",
    "<cfsavecontent variable="calculateTotal">", and
    "onclick="#calculateTotal#"" were just the ideas
    I was looking for.

    Cheers!

  6. Clark Agathen

    Clark Agathen

    Excellent example! I'm working on a variation of this same thing. In a cfgrid, I need to allow a user to input a begin date, and in another column input an end date. I need to use the number of months difference (like cf's datediff function) and use it in a calculation. I can't get the days to work though. Any ideas?
  7. Axel Jensen
    again, time and time again, this stuff is awesome, good job guys.

    my question; i have a grid that i would like to automatically have the total of, much the way that the RealEstate application, when a certain action happens it calls a some remoting, and then gives back a result... then the result is what populates my grid, in this instance, i'm having that grid populate with a series of items, much like an assembly set of items, say you buy a computer, and you serialize the monitor, the printer, you want to add the memory as a line item, and so on....
    (i call it a batch or an assembly item...) so anyway, i run these query's in my cfc, to get the items i need, and then load the grid, but then would like the total to automatically show in the top right of the screen, i have this working with the calculate button, but am having trouble finding a place to execute #calculateTotal#, because since i add a batch of items, the datagrid is never actually touched, so i cant use the datagrid's onChange event... any ideas?
  8. Traci
    Ok - this is probably the coolest site I have found for helping with coldfusions new techniques.

    I have a project log grid that also tracks hours. I would like it to total the hours for the employee, but I have been unable to get it to work. Your assistance would be greatly appreciated as I am new to AS.

    <cfsavecontent variable="calculateTotal" onclick="#calculateTotal#">
    var totalAmount = 0;
    var item;
    var subTotal = 0;

    for(var i = 0; i < empHrsGrid.length; i++) {
    item = empHrsGrid.getItemAt(i);
    subTotal = number(item['hrs']) * number(1);
    totalAmount += subTotal;
    }
    total.text = totalAmount;
    </cfsavecontent>

    <cfform name="EditLog" action="" format="flash" method="post" height="500">
                
    <cfgrid name="empHrsGrid"
       query="getAllbyStaff"
       width="900"
       selectmode="edit"
       insert="no"
       delete="no"
       vspace="100"
       onchange="#calculateTotal#">

       
    <cfgridcolumn name="projectnumber" type="string_nocase" header="Project Number" width="75" headeralign="center" headerbold="yes" select="yes" dataalign="center">

    <cfgridcolumn name="hrs" type="numeric" header="Hours" width="50" headeralign="center" headerbold="yes" select="yes" dataalign="center" >

    <cfgridcolumn name="newcontactdate"type="numeric" header="Log Date" width="85" headeralign="center" headerbold="yes" select="yes" dataalign="center">

    <cfgridcolumn name="lognotes" header="Log Entry" headeralign="center" headerbold="yes" select="no" >
                
    </cfgrid>
                
    <cfinput type="submit" name="gridEntered" value="Submit" >

    <cfinput type="Button" name="calculateBtn" value="Calculate Total Hours (not quite working yet...)" onclick="#calculateTotal#">

    <cfinput type="Text" name="total" disabled="true" label="Total Hrs Posted" size="7">

    </cfform>


    I have been farting around with this for days... and I feel like an idiot. But I am sure that it is something kind of simplistic that I am missing. The total hours box shows 0 when it first loads but when the calculate is clicked, it shows NaN. I haven't gotten any of the onload, or onclick or onchange events to work either for calculatetotal.

    Please help one of your admirers...
  9. Laura
    Traci,
    Thank you :)
    I am not sure why I used number(), but it should be Number(). Before making the addition, I would check whether or not is NAN and if it is, then I would ignore it (probably a null which would correspond to a 0)
    It would look something like this (change as needed):
    var totalAmount = 0;
    var item;
    var subTotal = 0;
       
    for(var i = 0; i < myGrid.length; i++) {
       item = myGrid.getItemAt(i);
          
       //get subtotal
       subTotal = Number(item['price']);      
          
       if (isNaN(subTotal)) {
          subTotal = 0;
       }
          
       //tally the amount up
       totalAmount += subTotal;
    }
    //show the total

    total.text = totalAmount;
  10. John Beasley
    How can you convert the final number to currency? In the amount of ($0.00). Thanks for any help!

    John
  11. Axel
    <h3>DecimalFormat Function</h3>
    <p>Returns a number to two decimal places.
    <p>

    <cfloop FROM = 1 TO = 20 INDEX = "counter">
    <cfoutput>
    $#DecimalFormat(counter)#
    </cfoutput>
    <br>
    </cfloop>
  12. WM
    I have used this example and it works great. Thank you very much for all the generous support.

    I am using cfgrid to create a sub-form within a flash form. Fields from the main form will update table 1 (Orders) while the grid rows will be used to update table 2 (OrderDetails). Both on the same datasource. The entire form is to be submitted at once and AFTER the prices, etc have been calculated updated. How can I ensure that the

    grid.rowstatus.action[i] is set to "I"?

    so that the form handler inserts all the individual rows (via CFloop)?
    Thanks a lot.

    WM

    (I did try cfgridupdate, but it did not work. If anyone has
  13. yogesh patil

    yogesh patil

    hi, thanks 4 replay, Actully i want editable grid, if i enter qty in 1 column, then it will show total amount that item in next column without refreshing the page & with out pressing any button, in asp.net
    it is possible then please help me

    thanks again
  14. Maggie

    Maggie

    Hello, is there a way to get the value of how many columns are in the row? I want to take the total / number of columns
  15. Laura
    Maggie,
    You can get columnCount and columnNames.

    Check the docs for all the available properties and functions of the datagrid. http://livedocs.macromedia.com/flex/15/asdocs_en/mx/controls/DataGrid.html
  16. Nik
    Hi, just would like to say excellent tutorial, was very helpful for me.

    im having some trouble with making the cfgridcolumn type show as currency. i know there are some bugs with flash form, however im sure it can be done.

    in my senario i have data queried from an access db, the columns i require are set to curreny etc. however when i change the data type to curreny in cfgridcolumn i get a NaN error in the subTotal and Total calculations. im assuming this is because of the $ sign.

    Do you have any way around this?? i can post my code if you like, its just a tad too big.

    Thanks
    Nik
  17. Craig Barnes
    I know that many people have posted a responce of how great this site is and how this has help them. I MUST also say the same thing.
    My Love this example since it answers 60% of may questions regarding calculations. I am populating a grid with add on options for vehicles. I want the end user to click a select box inside of the grid and then calulate totals from each selected options cost and not include items that are not selected. Any idea's on how to do this effeciantly?
  18. Michelle

    Michelle

    I need some help with a bit of cfgrid coding.

    When I select a new position number from the drop down list, the form below needs to refresh with the all of the information from the table for the selected value. I can't get the onchange to work. (profile_grid.cfm is the current page) My onchange for the 'old' select statement I was using is onchange="this.form.vCase.value=this.form.vCaseFind[this.form.vCaseFind.selectedIndex].value;this.form.submit();" and it works perfectly.

    <CFGRID NAME="vPositionFind" WIDTH="80%" HEIGHT="90"
    QUERY="PositionNumberInfo" INSERT="No"
    DELETE="No" SORT="No"
    FONT="Tahoma" BOLD="No" ITALIC="No" textcolor="##2D0D00"
    fontSize = "10" colHeaderFontSize = "10"
    GRIDDATAALIGN="LEFT" GRIDLINES="Yes"
    ROWHEADERS="No" ROWHEADERALIGN="LEFT" colheadertextcolor="##990000"
    SELECTCOLOR="BLUE" SELECTMODE="single"
    bgcolor="##FFFFEE"
    onchange="getUrl('profile_grid.cfm?vPosition=' + vPositionfind.dataProvider[vPositionfind.selectedIndex]['PositionNumber'],'target');">
    <CFGRIDCOLUMN NAME="PositionNumber" HEADER="Pos.No."
    HEADERALIGN="LEFT" DATAALIGN="LEFT"
    SELECT="yes" DISPLAY="Yes"
    <CFGRIDCOLUMN NAME="EmpLName" HEADER="Employee Last"
    HEADERALIGN="LEFT" DATAALIGN="LEFT"
    SELECT="no" DISPLAY="Yes" >
    <CFGRIDCOLUMN NAME="EmpFName" HEADER="Employee First"
    HEADERALIGN="LEFT" DATAALIGN="LEFT"
    SELECT="no" DISPLAY="Yes">
    <CFGRIDCOLUMN NAME="DivisionCode" HEADER="DivCode"
    HEADERALIGN="LEFT" DATAALIGN="LEFT"
    SELECT="no" DISPLAY="Yes" >

    Any help you can give me with this would be greatly appreciated! Thanks!
  19. Craig Barnes

    Craig Barnes

    I worked through using the code from "adding values of a cfgrid" and the "checkbox in a cfgrid" examples and came up a way to add values when checkbox is selected in a cfgrid. The code works. I will post url to example later. Here is code.
    Hope this helps someone. I sure needed to do this in my application.

    <!--- replace <cfscript> block with a query:
    <cfquery name="products">
       SELECT name, amount, quantity, price
       FROM cart
       .......etc
    </cfquery>
    --->
    <cfscript>
       products = queryNew("");
       names = "SUN ROOF,Alloy Wheels,Leather,Power Steering,Manual Transmision";
       price = "150,300,650,300,-325";
       CHECK = "false,false,false,false,true";
       queryaddcolumn(products,"name",listtoarray(names));
       queryaddcolumn(products,"price",listtoarray(price));
       queryaddcolumn(products,"CHECK",listtoarray(CHECK));   
    </cfscript>

    <cfsavecontent variable="calculateTotal">
       var totalAmount = 0;
       var item;
       var subTotal = 0;
       
       for(var i = 0; i < cart.length; i++) {
          item = cart.getItemAt(i);
          //get subtotal
          
          if(item.CHECK.toString() == "true")
          {
          subTotal = number(item['price']) + subTotal;
       
             }
          
       }
       //show the total
       total.text = subTotal;
    </cfsavecontent>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>Adding the values of a cfgrid column</title>
    </head>
    <body>
    <cfform name="myForm" format="flash" width="320" height="250">
    <cfformgroup type="vBox">
       <cfformitem type="text">Select Items to update Value of Options</cfformitem>
       <cfgrid name= "cart" query="products" height="150" rowheaders="false" selectmode="edit">
              <cfgridcolumn name="name" header="Product" type="NUMERIC" width="150" dataalign="left" >               
             <cfgridcolumn name="price" header="price" type="numeric" dataalign="right" select="false" width="60">
             <cfgridcolumn name="CHECK" header="CHECK" type="boolean" width="60">
          </cfgrid>
       <cfformgroup type="horizontal" style="horizontalAlign:left;">
          <cfinput type="Button" name="calculateBtn" value="Calculate Order" onclick="#calculateTotal#" style="cornerRadius:0">
          <cfinput type="Text" name="total" disabled="true" label="ADDED VALUE $" size="7" style="disabledColor:Black; borderStyle:none; fontWeight:bold;">
       </cfformgroup>
       </cfformgroup>
    </cfform>
    </body>
    </html>
  20. nik
    Hi,

    just wondering how would i go about saving the totalamount to datasource? so that when the page is loaded the total amount already shows. also so a can use the total value in other parts of the form.
  21. Jim Zoeller

    Jim Zoeller

    I love this example. Can someone help me with calculating and displaying values in a row? I want to be able to calculate values in each row and add another column with that calculated value.
  22. mus
    Hi,

    May i know how to get a value from cfgrid to pass to another page...please help me...
  23. -paul
    Can some one tell me why none of the cfgrid's render data in Chrome... if they are in a cfform format-flash or they them selves are format=flash....

    no tech articles on this..
  24. Nicholas

    Nicholas

    Hi,

    Can some one give an example how to get column name or column number of the cfgrid cell which was clicked.
  25. Cheeky
    This post was a lifesaver!! I couldn't find any information on how to refresh a value in the cfgrid until I saw this post, specifically: cart.editField(i, 'amount', subTotal);

    Thanks so much!
  26. Ray Meade

    Ray Meade

    Will this code work with an HTML grid and if not, is there a script that will do the same thing in an HTML grid? Basically, I'm just trying to add a column to the grid containing the total cost based on quantity times price. I also need the total of the entire grid to bind to a subtotal field. This code does EXACTLY what I want it to except that it needs to work with an HTML grid.