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>