Reputation: 39
I need to sum values in a two column table, where for each row if col2 is not blank, add it to the total, else instead add col1. Then publish the total to a div
Below is what I've tried but it outputs blank.
var table = document.getElementById("PLTable");
var cost_est = document.getElementsByClassName("cost_estimate");
var act_cost = document.getElementsByClassName("act_cost");
var sum2 = 0;
for (var i = 0, row; row = table.rows[i]; i++) {
if (act_cost[i].innerText>0) {
sum2 += act_cost[i].innerText;
}
else {
sum2 += cost_est[i].innerText;
}
}
document.getElementById("cost_projected_total").innerHTML = sum2
<!--HTML data looks like this:-->
<table id="PLTable">
<thead>
<tr>
<th>cost estimate</th>
<th>cost actual</th>
</tr>
</thead>
<tr>
<td class = "cost_estimate">100</td>
<td class = "act_cost"></td>
</tr>
<tr>
<td class = "cost_estimate">100</td>
<td class = "act_cost">50</td>
</tr>
</table>
<div id="cost_projected_total">
</div>
Correct output should be sum2 = 150 & that result should be output inside the div.
Any ideas?
Upvotes: 1
Views: 629
Reputation: 4783
Loop through act_cost
and check if the text in each cell is a valid and > 0 number then add it to sum2
otherwise add the cost_est
at that index to sum2
.
const table = document.getElementById("PLTable"),
cost_est = document.querySelectorAll(".cost_estimate"),
act_cost = document.querySelectorAll(".act_cost"),
total = document.getElementById("cost_projected_total");
let sum2 = 0;
/** loop through the "act_cost" (2nd column) **/
/**
* el: current td from "act_cost".
* i: its index in "act_cost"
**/
act_cost.forEach((el, i) => sum2 += +el.textContent > 0 ? +el.textContent:+cost_est[i].textContent);
/** "+" transforms the text into a number if possible **/
total.textContent = 'Total: ' + sum2;
<table id="PLTable">
<thead>
<tr>
<th>cost estimate</th>
<th>cost actual</th>
</tr>
</thead>
<tr>
<td class="cost_estimate">100</td>
<td class="act_cost"></td>
</tr>
<tr>
<td class="cost_estimate">100</td>
<td class="act_cost">50</td>
</tr>
</table>
<div id="cost_projected_total"></div>
Upvotes: 1
Reputation: 7446
There are some points to address in your code.
I will try to summarize what was wrong and how it should be change:
table.rows
actually loops the head as well, so your index would go out of bounds.innerText
returns a text, so you first need to conver that value to a Number
first, otherwise it will concatenate the strings.So, basically, what I did to keep your code as it currently was is:
tbody
table.rows
to the count of the tbody
rows.Below is the working code with the mentioned changes and fixes, it could've been way shorted, I just want to keep the code as close to your so that you can understand where and what was wrong, without necessarely relying on an optimal solution.
var table = document.getElementById("PLTable");
var tbody = table.getElementsByTagName('tbody')[0];
var cost_est = document.getElementsByClassName("cost_estimate");
var act_cost = document.getElementsByClassName("act_cost");
var sum2 = 0;
for (var i = 0; i < tbody.getElementsByTagName('tr').length; i++) {
var row_act_cost = Number(act_cost[i].innerText);
var row_cost_est = Number(cost_est[i].innerText);
if (row_act_cost > 0) {
sum2 += row_act_cost;
}
else {
sum2 += row_cost_est;
}
}
document.getElementById("cost_projected_total").innerHTML = sum2;
<table id="PLTable">
<thead>
<tr>
<th>cost estimate</th>
<th>cost actual</th>
</tr>
</thead>
<tbody>
<tr>
<td class = "cost_estimate">100</td>
<td class = "act_cost"></td>
</tr>
<tr>
<td class = "cost_estimate">100</td>
<td class = "act_cost">50</td>
</tr>
</tbody>
</table>
<div id="cost_projected_total">
</div>
Upvotes: 1