By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,652 Members | 1,422 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,652 IT Pros & Developers. It's quick & easy.

Javascript: Sum up columns of a table

P: 55
Hi all,

I have a simple table set up in which a user can insert values into the boxes and onkeydown it will sum up the column.

Table:

Expand|Select|Wrap|Line Numbers
  1. <table>
  2. <tr>
  3. <td><input type="text" onkeydown="calcTotal(this, 'tot')" /></td>
  4. <td><input type="text" onkeydown="calcTotal(this, 'tot1')" /></td>
  5. </tr>
  6. <tr>    
  7. <td><input type="text" onkeydown="calcTotalCol(this, 'tot')" /></td>
  8. <td><input type="text" onkeydown="calcTotalCol(this, 'tot1')" /></td>
  9. </tr>
  10. <tr>    
  11. <td><input type="text" onkeydown="calcTotal(this, 'tot')" /></td>
  12. <td><input type="text" onkeydown="calcTotal(this, 'tot1')" /></td>       
  13. </tr>
  14. <tr>    
  15. <td><input type="text" id="tot" /></td>
  16. <td><input id="tot1" type="text" /></td>
  17. </tr>   
  18. </table>
  19.  
javascript:

Expand|Select|Wrap|Line Numbers
  1. function calcTotal(txtBox, totBox) 
  2.          {
  3.             var col = txtBox.parentNode.parentNode.parentNode;
  4.             var inputs = col.getElementsByTagName("input"); //Get input boxes 
  5.             sum = 0;    //Set sum to 0
  6.  
  7.             for (i=0; i< inputs.length; i++) 
  8.             {
  9.                 if (inputs[i].type == "text") 
  10.                 {
  11.                     if(inputs[i].id.indexOf(totBox) == -1) //Pass id of total text box
  12.                     {
  13.                         if (inputs[i].value != null && inputs[i].value != "") 
  14.                         sum += parseInt(inputs[i].value); //Calculate the total
  15.                     }
  16.                     else
  17.                     {
  18.                         inputs[i].value = sum;  //Store total in box
  19.                     }
  20.                  }
  21.              }
  22.          }
  23.  
I think my problem is I am getting the wrong objects when traversing through the DOM of the table, think I may be getting the tbody rather than the column, so I need help in getting the columns to sum them up if anyone can help.

Many thanks in advance.
Mar 22 '09 #1
Share this Question
Share on Google+
13 Replies


RamananKalirajan
100+
P: 607
Hi...

I have just changed some part of your code.... This is one way of summing the column.. you can work in n no.. of ways to find the sum...

HTML Code

Expand|Select|Wrap|Line Numbers
  1. <table> 
  2. <tr> 
  3. <td><input type="text" onblur="calcTotal(this, 'tot')" /></td> 
  4. <td><input type="text" onblur="calcTotal(this, 'tot1')" /></td> 
  5. </tr> 
  6. <tr>     
  7. <td><input type="text" onblur="calcTotal(this, 'tot')" /></td> 
  8. <td><input type="text" onblur="calcTotal(this, 'tot1')" /></td> 
  9. </tr> 
  10. <tr>     
  11. <td><input type="text" onblur="calcTotal(this, 'tot')" /></td> 
  12. <td><input type="text" onblur="calcTotal(this, 'tot1')" /></td>        
  13. </tr> 
  14. <tr>     
  15. <td><input type="text" id="tot" /></td> 
  16. <td><input id="tot1" type="text" /></td> 
  17. </tr>    
  18. </table> 
JS Code

Expand|Select|Wrap|Line Numbers
  1. <script type="text/javascript">
  2. function calcTotal(txtBox, totBox)
  3. {
  4.     var totVal;
  5.     try
  6.     { 
  7.     totVal = document.getElementById(totBox).value;
  8.     if(totVal!= null && totVal!='')
  9.      {
  10.        document.getElementById(totBox).value= eval(parseInt(document.getElementById(totBox).value) + parseInt(txtBox.value));   
  11.      }
  12.      else
  13.      {
  14.         document.getElementById(totBox).value= txtBox.value;           
  15.      }
  16.     }
  17.     catch(e)
  18.     {}
  19. }
  20. </script>
Regards
Ramanan Kalirajan
Mar 24 '09 #2

P: 55
Thank you very much that does the job nicely :)
Mar 25 '09 #3

acoder
Expert Mod 15k+
P: 16,027
Ugh! No need for the eval on line 10 - the parseInt will add up nicely.
Mar 28 '09 #4

P: 4
This second solution works really well except (and my javascript understanding is almost nil) the NaN comes up if a field is tabbled through/nothing is entered in a box...

How can that be addressed?

Thank you.
Dec 11 '09 #5

acoder
Expert Mod 15k+
P: 16,027
Use the isNaN function. See also http://www.w3schools.com/jsref/jsref_isnan.asp
Dec 12 '09 #6

P: 4
Thanks, acoder.

I figured out a solution for the original question and I managed to edit the preceding code to total both rows and columns.

Here's the next question: can this be further altered so that changes to the fields can be counted - right now it just keeps adding to the totals but I want it to keep a running total of the current numbers only.

Possible?

Javascript
Expand|Select|Wrap|Line Numbers
  1. <script type="text/javascript"> 
  2. function calcTotal(txtBox, totBox, rowBox) 
  3. //val(txtBox.item);
  4. //val(txtBox
  5.  if (txtBox.value.length!=0){
  6.     var totColVal; 
  7.     var totRowVal;
  8.     try 
  9.     {  
  10.     totColVal = document.getElementById(totBox).value; 
  11.     if(totColVal!= null && totColVal!='') 
  12.      { 
  13.        document.getElementById(totBox).value= eval(parseInt(document.getElementById(totBox).value) + parseInt(txtBox.value));    
  14.      } 
  15.      else 
  16.      { 
  17.         document.getElementById(totBox).value= txtBox.value;            
  18.      } 
  19.     } 
  20.     catch(e) 
  21.     {} 
  22.      try 
  23.     {  
  24.     totRowVal = document.getElementById(rowBox).value; 
  25.     if(totRowVal!= null && totRowVal!='') 
  26.      { 
  27.      document.getElementById(rowBox).value= (parseInt(document.getElementById(rowBox).value) + parseInt(txtBox.value));    
  28.      } 
  29.      else 
  30.      { 
  31.         document.getElementById(rowBox).value= txtBox.value;            
  32.      } 
  33.     } 
  34.     catch(e) 
  35.     {} 
  36. } }
  37. </script> 
  38.  
HTML
Expand|Select|Wrap|Line Numbers
  1. </head>
  2.  
  3. <body>
  4. <form action="calc.php" method="post" enctype="text" name="multipart/form-data" target="_self"><table>  
  5. <tr>  
  6. <td><input type="text" name="1000-0" onblur="calcTotal(this, 'tot0', 'row0')" /></td>  
  7. <td><input type="text" name="1020-0" onblur="calcTotal(this, 'tot1', 'row0')" /></td>  
  8. <td><input name="row0" type="text" id="row0" readonly="readonly"/></td>  
  9. </tr>  
  10. <tr>      
  11. <td><input type="text" name="1000-1" onblur="calcTotal(this, 'tot0', 'row1')" /></td>  
  12. <td><input type="text" name="1020-1" onblur="calcTotal(this, 'tot1', 'row1')" /></td>  
  13. <td><input name="row1" type="text" id="row1" readonly="readonly"/></td>  
  14. </tr>  
  15. <tr>      
  16. <td><input type="text" name="1000-2" onblur="calcTotal(this, 'tot0', 'row2')" /></td>  
  17. <td><input type="text" name="1020-2" onblur="calcTotal(this, 'tot1', 'row2')" /></td>   
  18. <td><input name="row2" type="text" id="row2" readonly="readonly"/></td>        
  19. </tr>  
  20. <tr>      
  21. <td><input name="1000-tot" type="text" id="tot0" readonly="readonly" /></td>  
  22. <td><input name="1020-tot" type="text" id="tot1" readonly="readonly" /></td>  
  23. </tr>     
  24. </table>  <input type="submit" name="submit" value="Submit" /></form>
  25. </body>
  26. </html>
Dec 21 '09 #7

acoder
Expert Mod 15k+
P: 16,027
You'll have to recalculate the totals each time. If you want to get a bit more complicated, you could store the values in a 2-dimensional array and change the corresponding value and then recalculate using the array (so that you don't have to access all of the elements each time).

PS. eval is not required in your code.
Dec 22 '09 #8

P: 4
Thanks again, acoder.

(FYI: I really don't know javascript so try not to laugh at this pitiful effort)

Here's an attempt at using an array to calculate row/col values. BTW: The column headers are paycodes not just some seeminly random selection of numbers
.
Javascript
Expand|Select|Wrap|Line Numbers
  1. <script type="text/JavaScript">
  2. function calcTotal(cell,row,col){
  3. var total=0;
  4. var box={'1000':{},'1001':{},'1002':{},'1005':{},'1007':{},'1003':{},'1020':{},'1035':{},'1038':{},'1045':{},'1066':{},'1067':{},'Other':{}};
  5.     box[col][row]=cell;
  6.     for (j=0;j<2;j++){
  7.         if (box[col][j]>=0){
  8.             total+=(box[col][j]);
  9.             }
  10.         }
  11. document.getElementById(col).value;
  12. document.getElementById(row).value;
  13. }
  14. </script>
HTML
Expand|Select|Wrap|Line Numbers
  1. <table border=1px>
  2.   <tr>
  3.     <th>Day</th><th>Date</th><th>1000</th><th>1005</th><th>Other</th><th>Total hrs</th><th>Shift Diff</th>
  4.   </tr>
  5.   <tr>
  6.     <td>mon</td><td>12/24</td>
  7.     <td><input name='1000-0' id='1000-0' type='text' size='2' onblur='calcTotal(this,'0', '1000' )'/></td>
  8.     <td><input name='1005-0' id='1005-0' type='text' size='2' onblur='calcTotal(this,'0', '1005' )'/></td>
  9.     <td><input name='Other-0' id='Other-0' type='text' size='2' onblur='calcTotal(this,'0', 'Other' )'/></td>
  10.     <td><input name='total-0' id='0' type='text' size='2' /></td>
  11.     <td><input name='1007-0' id='1007-0' type='text' size='2' /></td>
  12.   </tr>
  13.   <tr>
  14.     <td>tue</td><td>12/25</td>
  15.     <td><input name='1000-1' id='1000-1' type='text' size='2' onblur='calcTotal(this,'1', '1000' )'/></td>
  16.     <td><input name='1005-1' id='1005-1' type='text' size='2' onblur='calcTotal(this,'1', '1005' )'/></td>
  17.     <td><input name='Other-1' id='Other-1' type='text' size='2' onblur='calcTotal(this,'1', 'Other' )'/></td>
  18.     <td><input name='total-1' id='1' type='text' size='2' /></td>
  19.     <td><input name='1007-1' id='1007-1' type='text' size='2' /></td>
  20.   </tr>
  21.   <tr>
  22.     <td>wed</td><td>12/26</td>
  23.     <td><input name='1000-2' id='1000-2' type='text' size='2' onblur='calcTotal(this,'2', '1000' )'/></td>
  24.     <td><input name='1005-2' id='1005-2' type='text' size='2' onblur='calcTotal(this,'2', '1005' )'/></td>
  25.     <td><input name='Other-2' id='Other-2' type='text' size='2' onblur='calcTotal(this,'2', 'Other' )'/></td>
  26.     <td><input name='total-2' id='2' type='text' size='2' /></td>
  27.     <td><input name='1007-2' id='1007-2' type='text' size='2' /></td>
  28.   </tr>
  29.  <tr>
  30.   <td colspan='2' align='right'>totals</td>
  31.     <td><input name='1000' id='1000' type='text' size='2'/></td>
  32.     <td><input name='1005' id='1005' type='text' size='2'/></td>
  33.     <td><input name='Other' id='Other' type='text' size='2'/></td>
  34.     <td><input name='total' id='total' type='text' size='2'/></td>
  35.     <td><input name='1007' id='1007' type='text' size='2'/></td>
  36.   </tr>
  37. </table>
One big question: Are the numbers stored in the array for the session? or will the array be reset when the function is executed? and if the latter...how can the values be preserved for the session?

Another question - Why won't box[i] work for box[box[i]][i] - is that recursive? I have to admit to being a little lost in the array...

The last two lines are just a hail-mary that I pulled from the preceding code. So how crazy is this code, anyway? rotfl or lmao?

Thank you!
Dec 23 '09 #9

P: 4
So I've pretty much figured this one out but am still trying to allow only numeric entries (including decimals)...

ended up abandoning the 2xArray and decided to just loop through each value for a given row/column - so far, so good.

One odd thing - the columns wouldn't total until I placed that loop first - any ideas on why that would be?

Javascript
Expand|Select|Wrap|Line Numbers
  1. function calculate(col, row){
  2. var numericExpression = /^[0-9]+$/; //verify numeric - needs to allow for decimals though...hmmm...
  3.     if(document.getElementById(col+"-"+row).value.match(numericExpression)){
  4. var input=0;  //initalize variable to get entered value
  5. var rowTot=0; //initalize variable to capture row totals
  6. var colTot=0; //initalize variable to capture column totals
  7. //setup up array for paycodes/column headers 
  8. codes=new Array('1000','1001','1002','1005','1007','1003','1020','1035','1038','1045','1066','1067','Other'); 
  9. //loop through all of the text fields for a given column and total them
  10.         for (i=0;i<2;i++){
  11.         input=(document.getElementById(col+'-'+i).value)*1
  12.         colTot=colTot+input;
  13.         document.getElementById(col).value = colTot;
  14.         }
  15. //loop through all of the text fields for a given row and total them
  16.         for (j=0;j<13;j++){
  17.         input=(document.getElementById(((codes[j])+'-'+row)).value)*1
  18.         rowTot=rowTot+input;
  19.         document.getElementById('row'+row).value = rowTot;
  20.         }
  21.     }
  22.     //if the entry isn't numeric then return no value
  23.     else {document.getElementById(col+"-"+row).value="";}
  24. }
html
Expand|Select|Wrap|Line Numbers
  1. Enter numbers here:<br>
  2.  
  3. <input name="1000-0" id="1000-0" type="text"  onblur="calculate('1000','0')">
  4. <input name="1001-0" id="1001-0" type="text"  onblur="calculate('1001','0')">
  5. <input name="row0" type="text" id="row0" readonly="readonly">
  6. <br>
  7. <input name="1000-1" id="1000-1" type="text"  onblur="calculate('1000','1')">
  8. <input name="1001-1" id="1001-1" type="text"  onblur="calculate('1001','1')">
  9. <input name="row1" type="text" id="row1" readonly="readonly">
  10. <br>
  11. <input name="1000" id="1000" type="text">
  12. <input name="1001" id="1001" type="text">
  13. <br>
Dec 23 '09 #10

Dormilich
Expert Mod 5K+
P: 8,639
2 notes from my side:

id values must only start with a letter or underscore, anything else is browser courtsy.

this and this thread also deal with summing up a table, maybe they give you some more insight.
Dec 24 '09 #11

acoder
Expert Mod 15k+
P: 16,027
So I've pretty much figured this one out but am still trying to allow only numeric entries (including decimals)...
Either use a floating point regular expression, e.g. something like: /^[0-9]+\.[0-9]{2}$/ or parseFloat with isNaN

One odd thing - the columns wouldn't total until I placed that loop first - any ideas on why that would be?
What would happen?
Dec 30 '09 #12

P: 4
I have a form. Diffrent fields that add up to a sub total. I need to sub totals to autocomplete the TOTAL sum??? I have tried a few things.. but it did not work. Im quite new to this.. I have used some code examples from the site.. (thanks)...

I just need to TOTAL SUM to display when i add some numericals to the top fields?? where am I going wrong???

Expand|Select|Wrap|Line Numbers
  1.  
  2. <html>
  3. <head>
  4.  
  5. <script type="text/JavaScript">
  6. function calculate(col, row){
  7. var numericExpression = /^[0-9]+$/; //verify numeric - needs to allow for decimals though...hmmm...
  8.     if(document.getElementById(col+"-"+row).value.match(numericExpression)){
  9. var input=0;  //initalize variable to get entered value
  10. var rowTot=0; //initalize variable to capture row totals
  11. var colTot=0; //initalize variable to capture column totals
  12. //setup up array for paycodes/column headers 
  13. codes=new Array('1000','1001','1002','1005','1007','1003','1020','1035','1038','1045','1066','1067','Other'); 
  14. //loop through all of the text fields for a given column and total them
  15.         for (i=0;i<2;i++){
  16.         input=(document.getElementById(col+'-'+i).value)*1
  17.         colTot=colTot+input;
  18.         document.getElementById(col).value = colTot;
  19.         }
  20. //loop through all of the text fields for a given row and total them
  21.         for (j=0;j<13;j++){
  22.         input=(document.getElementById(((codes[j])+'-'+row)).value)*1
  23.         rowTot=rowTot+input;
  24.         document.getElementById('row'+row).value = rowTot;
  25.         }
  26.     }
  27.     //if the entry isn't numeric then return no value
  28.     else {document.getElementById(col+"-"+row).value="";}
  29. }
  30.  
  31. function updatesum() {
  32. document.form.sum.value = (document.form.sum1.value -0) + (document.form.sum2.value -0);
  33. }
  34.  
  35. </script>
  36.  
  37. </head>
  38.  
  39. <body>
  40.  
  41. <p>Enter numbers here:<br>
  42. <form name="form"  >
  43.   <p>
  44.     <input name="1000-0" id="1000-0" type="text"  onblur="calculate('1000','0')" >
  45.     <input name="1001-0" id="1001-0" type="text"  onblur="calculate('1001','0')" >
  46.     <br>
  47.     <input name="1000-1" id="1000-1" type="text"  onblur="calculate('1000','1')" >
  48.     <input name="1001-1" id="1001-1" type="text"  onblur="calculate('1001','1')" >
  49.     <br>
  50.     <br />
  51.     sub total &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sub total<br />
  52.     <input name="sum1" id="1000" type="text" onblur="updatesum()" >
  53.     <input name="sum2" id="1001" type="text" onblur="updatesum()" >
  54.     <br />
  55.     <br />
  56.     Total Sum:
  57.     <input name="sum" readonly  />
  58. </form>
  59. </body>
  60. </html>
  61.  
  62.  
May 20 '10 #13

RamananKalirajan
100+
P: 607
In the Line Number 24, You are accessing an element with the id ('row'+row). But in the HTML, there is no element with id like that. Check for that. That is the problem.

Thanks and Regards
Ramanan Kalirajan
Sep 15 '10 #14

Post your reply

Sign in to post your reply or Sign up for a free account.