Home > database >  How to dynamically sum all columns for HTML table using JS
How to dynamically sum all columns for HTML table using JS

Time:04-23

enter image description here

I am new to JS. I have been trying to sum each column dynamically so that as there is a new year it will auto sum the column. So far I can only get it to work for 1 column at a time. Any help is greatly appreciated.

function computeTableColumnTotal(colNumber) {
    
    var result = 0;

    try {
        var tableBody = document.querySelector("tbody");
        var howManyRows = tableBody.rows.length;     
    
        for(var i = 1; i < (howManyRows-1); i   ) {
            var thisNumber = parseInt(tableBody.rows[i].cells[colNumber].childNodes.item(0).data);  
            
            if (!isNaN(thisNumber))
                result  = thisNumber;
            }
    }
    finally {
        return result;
    }
}

var final = 0
var howManyCols = document.querySelector("tbody").rows[0].cells.length
for(var j = 0; j < howManyCols; j   ) {
    final = computeTableColumnTotal(j)
}
console.log(final)
   

document.getElementById('toe').innerHTML  = '<tr><td>'   final;

CodePudding user response:

You need to put the total for each column in the corresponding cell in the last row.

var final = 0
var tbody = document.querySelector("tbody");
var howManyCols = tbody.rows[0].cells.length;
var totalRow = tbody.rows[tbody.rows.length - 1];
for (var j = 1; j < howManyCols; j  ) {
  final = computeTableColumnTotal(j);
  totalRow.cells[j].innerText = final;
}

function computeTableColumnTotal(colNumber) {

  var result = 0;

  try {
    var tableBody = document.querySelector("tbody");
    var howManyRows = tableBody.rows.length;

    for (var i = 1; i < (howManyRows - 1); i  ) {
      var thisNumber = parseInt(tableBody.rows[i].cells[colNumber].childNodes.item(0).data);

      if (!isNaN(thisNumber))
        result  = thisNumber;
    }
  } finally {
    return result;
  }
}
<table>
  <tbody>
  <tr>
    <td></td>
    <th scope="col">2013</th>
    <th scope="col">2014</th>
    <th scope="col">2015</th>
    <th scope="col">2016</th>
  </tr>
    <tr>
      <th scope="row">a</th>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr>
      <th scope="row">b</th>
      <td>5</td>
      <td>6</td>
      <td>4</td>
      <td>5</td>
    </tr>
    <tr>
      <th scope="row">c</th>
      <td>4</td>
      <td>5</td>
      <td>6</td>
      <td>7</td>
    </tr>
    <tr>
      <th scope="row">d</th>
      <td>5</td>
      <td>6</td>
      <td>8</td>
      <td>5</td>
    </tr>

    <tr>
      <th scope="row">Total</th>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
  </tbody>
</table>

CodePudding user response:

You could restructure your code like this to iterate over the total cells, ensuring the appropriate column is summed for each.

function getColumnValues(table, column) {
    const body = table.getElementsByTagName("tbody")[0];
    const rows = [...body.getElementsByTagName("tr")];
    const contents = rows.map(row => row.getElementsByTagName("td")[column].textContent);
    return contents.filter(c => !isNaN(c)).map(c => Number(c));
}
const sum = arr => arr.reduce((a, b) => a   b, 0);
const table = document.getElementsByTagName("table")[0];
const totals = [...table.getElementsByTagName("tfoot")[0].getElementsByTagName("td")];
for (const [i, cell] of totals.entries()) {
    cell.innerHTML = sum(getColumnValues(table, i));
}
<table><thead>
<tr><td></td><th scope="col">2013</th><th scope="col">2014</th><th scope="col">2015</th><th scope="col">2016</th></tr></thead>
<tbody>
<tr><th scope="row">a</th><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><th scope="row">b</th><td>5</td><td>6</td><td>4</td><td>5</td></tr>
<tr><th scope="row">c</th><td>4</td><td>5</td><td>6</td><td>7</td></tr>
<tr><th scope="row">d</th><td>5</td><td>6</td><td>8</td><td>5</td></tr>
</tbody>
<tfoot><tr><th scope="row">Total</th><td></td><td></td><td></td><td></td></tr>
</tfoot>
</table>

  • Related