6

I am trying to sum a table column total.

Here is an example of only two column for test purposes. I want to calculate table column's item total using a javascript loop.

How to create the loop if we don't know how many rows and columns are inside in table? I hope you understand what I mean and also hope for your kindly suggestion.

<p><b>Student at Stanford University 2013-2014</b></p>
<table><tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr></table>
<table id="sdtable">
    <tr><th>Business</th><td>12922</td><td>11420</td></tr>
    <tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
    <tr><th>Education</th><td>14560</td><td>13490</td></tr>
    <tr><th>Engineering</th><td>8750</td><td>9863</td></tr>
    <tr><th>Humanities & Sciences</th><td>7819</td><td>7219</td></tr>
    <tr><th>Medicine</th><td>5219</td><td>4200</td></tr>
</table>

<button onclick="Calculate()">Calculate</button>
<div id="Studentf" class="Studentf"></div>
<div id="Students" class="Students"></div>
<div id="Studentt" class="Studentt"></div>

and

var ftable = document.getElementById("sdtable");
var i= 0;
var sumFirst=0;
var sumSecond=0;
var sumTotal=0;

function Calculate(){

    for (i=0;i<ftable.rows.length; i++){
        sumFirst=sumFirst+parseInt(ftable.rows[i].cells[1].innerHTML);
        sumSecond=sumSecond+parseInt(ftable.rows[i].cells[2].innerHTML);
    } 
    sumTotal=sumFirst+sumSecond;

    document.getElementById("Studentf").innerHTML +="<b>Student in 2013 = </b>" +sumFirst;
    document.getElementById("Students").innerHTML +="<b>Student in 2014 = </b>" +sumSecond;
    document.getElementById("Studentt").innerHTML +="<b>Total Student = </b>" +sumTotal;

}
6
  • Why are the tables in a form? It doesn't seem to be used for anything. Commented Dec 24, 2014 at 9:42
  • You should wrap <th></th> in <thead></thead> section Commented Dec 24, 2014 at 9:44
  • document.getElementById("sdtable"), what is the id "sdtable" for, it's not used in html code. Commented Dec 24, 2014 at 9:48
  • #RobG i don't focus on html table display. it was made only for data purpose. Commented Dec 24, 2014 at 9:49
  • #Anand check it again at script. ftable = document.getElementById("sdtable"); ftable used in loop. Commented Dec 24, 2014 at 9:52

3 Answers 3

2

The key here is that you need to use cells collection to get number of columns that can change when you add new years to the table. You will also have to dynamically create elements for summary information per year.

Here is an example:

var ftable = document.getElementById("sdtable");
var i = 0;
var sumFirst = 0;
var sumSecond = 0;
var sumTotal = 0;

function Calculate() {

    var rows = ftable.tBodies[0].rows,
        header = ftable.tHead.rows[0],
        cells = ftable.tBodies[0].rows[0].cells,
        years = [];

    for (var i = 0; i < rows.length; i++) {
        for (var j = 1; j < cells.length; j++) {
            if (!years[j]) years[j] = 0;
            years[j] += parseInt(rows[i].cells[j].innerHTML);
        }
    }

    sumTotal = years.reduce(function(prev, curr) {
        return prev + curr;
    }, 0);

    var sum = document.getElementById("sum");
    sum.innerHTML = '';
    for (var j = 1; j < cells.length; j++) {
        console.log(header.cells[j])
        sum.insertAdjacentHTML('afterbegin', '<p><b>' + header.cells[j].innerHTML + '</b> = ' + years[j] + '</p>');
    }
    sum.insertAdjacentHTML('beforeend', "<b>Total Student = </b>" + sumTotal);
}

Demo: http://jsfiddle.net/x2sscpxL/1/

Sign up to request clarification or add additional context in comments.

Comments

1

The table should probably look more like:

<table>
  <thead>
    <tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr>
  </thead>
  <tbody id="sdtable">
    <tr><th>Business</th><td>12922</td><td>11420</td></tr>
    <tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
    <tr><th>Education</th><td>14560</td><td>13490</td></tr>
    ...
   </tbody>
  <tfoot>
    <tr><th>Totals:</th><th></th><th></th></tr>
</table>

to split the header, body and footer into separate table sections. The function should then be like:

function calculate(){

    // Get a reference to the tBody
    var tBody = document.getElementById('sdtable');
    if (!tBody) return;

    var row, rows = tBody.rows;
    var cell, cells;
    var cellTotals = {};

    // For each row in the body
    for (i=0, iLen=rows.length; i<iLen; i++) {
      row = rows[i];
      cells = row.cells;

      // Add the cells in each column, starting on the second column
      // i.e. starting with cell index 1
      for (var j=1, jLen=cells.length; j<jLen; j++) {
        cell = cells[j];

        if (j in cellTotals) {
          cellTotals[j] += Number(cell.textContent || cell.innerText);
        } else {
          cellTotals[j] = Number(cell.innerHTML);
        }
      }
    }

    // Write the totals into the footer
    var tFoot = tBody.parentNode.tFoot;
    row = tFoot.rows[0];
    for (var k=1; k<jLen; k++) {
      row.cells[k].innerHTML = cellTotals[k];
    }
}

Note that by convention, variables with a name starting with a capital letter are reserved for constructors (though constants usually are all caps).

Comments

1

Here is calculation of table witn n rows and n columns
Note: header cells wrapped in thead section

var ftable = document.getElementById("sdtable");
var tbody = ftable.getElementsByTagName("tbody")[0]
var columnsCount = ftable.rows[0].cells.length;
  
var sumTotal = [];
for(i=0; i<columnsCount;i++)
  sumTotal.push(0); //here initialize with zero

function Calculate(){

    for (i=0;i<tbody.rows.length; i++){
      for (j=0; j<columnsCount; j++)
        if (tbody.rows[i].cells[j] && tbody.rows[i].cells[j].innerHTML)           
         sumTotal[j] += parseInt(tbody.rows[i].cells[j].innerHTML);

    } 
    
  return sumTotal;
  

}
 

sumTotal = Calculate();



tfootrow = ftable.tFoot.rows[0];
console.log(tfootrow)

for(i=0; i<sumTotal.length; i++){
  tfootrow.insertCell(i).innerHTML = sumTotal[i];
  }
<table id="sdtable">
  <thead>
    <tr>
      <th>Business</th>
      <th>Earth Sciences</th>
      <th>Education</th>
      <th>Engineering</th>
      <th>Humanities & Sciences</th>
      <th>Medicine</th>
      </tr>
  </thead>
  <tbody>
    <tr><td>12922</td><td>11420</td></tr>
    <tr><td>4320</td><td>4611</td></tr>
    <tr><td>14560</td><td>13490</td></tr>
    <tr><td>8750</td><td>9863</td></tr>
    <tr><td>7819</td><td>7219</td></tr>
    <tr><td>5219</td><td>4200</td></tr>
    <tr><td></td><td>1</td><td>2</td></tr>
   </tbody>
   <tfoot>
     <tr></tr>
   </tfoot>
</table>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.