Reputation: 335
I'm a beginner so I'm not sure whats wrong here. What im trying to achieve is to check if certain cells in a table (column) has numerical values in them and if they do include them in calculating the average value upon losing focus (blur) so that it would kind of be real time.
I'm not sure if calculation function is wrong itself, or if I'm addressing wrong column maybe or trying to insert calculated value in the wrong way. help would be appreciated.
Here is JSfiddle and the code excerpts: https://jsfiddle.net/NulisDefo/03rn7ew1/5/
table
<table id="myTable" class="table table-inverse">
<thead id = "headings" class = "thead-default">
<tr>
<th>Tabelio Nr.</th>
<th>Vardas</th>
<th>Pavardė</th>
<th>Pareigos</th>
<th>Bazinė alga, €</th>
<th>Valandinis atlyginimas, €</th>
<th>Veiksmai</th>
</tr>
</thead>
<tfoot class = "thead-default">
<tr>
<td colspan = "4">Vidurkis</td>
<!-- <td></td>
<td></td>
<td></td> -->
<td id = "alga">0</td>
<td id = "valandinis" colspan = "2">0</td>
<!-- <td></td> -->
</tr>
</tfoot>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
<td>1000</td>
<td><input type="button" value="Delete" onclick="deleteRow(this)"></td>
<td>
<p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
<p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
<td>2000</td>
<td>blum</td>
<td>
<p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
<p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
</td>
</tr>
<tr class = "testas">
<td>3</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
<td>5000</td>
<td>blum</td>
<td>
<p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
<p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
</td>
</tr>
</tbody>
</table>
script for calculating and trigger
$("table").on("blur", "td", function(){
calculate();
} );
function calculate() {
var sum = 0;
var counter = 0 //daliklis
$('#myTable tbody tr td:nth-child(5)').each(function() {
// $("table tbody tr td:eq(4)").each(function(){
if (!isNaN(this.value))
{
sum += parseFloat($(this).text());
counter += 1;
}
});
$("#alga").textContent(sum/counter);
};
I should probably mention, that prior existing entries can be edited only after pressing edit button.
EDIT: Ok, so apparently all of the solutions work, but the problem is, that if cell is empty, instead of excluding that part from calculation the returned result is NaN
Upvotes: 0
Views: 1171
Reputation: 1423
You can use focusout
event.
$("table").on("focusout", "tr", function(){
calculate();
});
I have updated the code like following.
focusout
for tr
. (Because this event listens change made to the contenteditable
and in your case tr
has contenteditable
not the td
.avg
in the
footer td which will tell that these columns needs average to
calculate.avg
class in calculation and also updated the logic a bit.text()
method to set and get the text of td
.Check updated fiddle
Upvotes: 1
Reputation: 5622
Your loop was not proper. Checkout the jsFiddle Demo .Now you just need to decide when to trigger calculate function which I think you can handle
function calculate() {
var sum = 0;
var counter = 0 //daliklis
$('#myTable tbody tr').each(function() {
// $("table tbody tr td:eq(4)").each(function(){
var a = $(this).children('td:nth-child(5)');
if (!isNaN(a.text()))
{
sum += parseFloat(a.html()); console.log(sum);
counter += 1;
}
});
$("#alga").text(sum/counter);
}
Upvotes: 1
Reputation: 456
function deleteRow(r) {
var i = r.parentNode.parentNode.rowIndex;
document.getElementById("myTable").deleteRow(i);
};
$("#pridet").on("click", function() {
$("<tr contenteditable><td></td><td></td><td></td><td></td><td></td><td></td></tr>").prependTo("table tbody");
$("table tbody tr td").last().clone().appendTo("table tbody tr:first");
});
$(".editbtn").click(function () {
var currentTD = $(this).parents("tr").find("td");
$.each(currentTD, function () {
$(this).prop("contenteditable", true)
});
});
$("table").on("blur", "td", function(){
calculate();
} );
function calculate() {
var sum = 0;
var counter = 0 //daliklis
$('#myTable tbody tr td:nth-child(5)').each(function() {
// $("table tbody tr td:eq(4)").each(function(){
if (!isNaN($(this).text()))
{
sum += parseFloat($(this).text());
counter += 1;
}
});
$("#alga").text(sum/counter);
}
calculate();
.btn {
width:10%;
padding-bottom:0;
margin-bottom:0;
border-bottom:0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">
<button id = "pridet">add</button>
<table id="myTable" class="table table-inverse">
<thead id = "headings" class = "thead-default">
<tr>
<th>Tabelio Nr.</th>
<th>Vardas</th>
<th>Pavardė</th>
<th>Pareigos</th>
<th>Bazinė alga, €</th>
<th>Valandinis atlyginimas, €</th>
<th>Veiksmai</th>
</tr>
</thead>
<tfoot class = "thead-default">
<tr>
<td colspan = "4">Average</td>
<!-- <td></td>
<td></td>
<td></td> -->
<td id = "alga">0</td>
<td id = "valandinis" colspan = "2">0</td>
<!-- <td></td> -->
</tr>
</tfoot>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
<td>1000</td>
<td>15.3</td>
<td>
<p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
<p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
<td>2000</td>
<td>16.8</td>
<td>
<p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
<p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
</td>
</tr>
<tr class = "testas">
<td>3</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
<td>5000</td>
<td>10.2</td>
<td>
<p class = "btn editbtn"><span class = "fa fa-edit"></span></p>
<p class = "btn" onclick="deleteRow(this)"><span class = "fa fa-trash"></span></p>
</td>
</tr>
</tbody>
</table>
</div>
</body>
$("#alga").text(sum/counter);
instead of $("#alga").textContent(sum/counter);
textContent
is not a function. Use $.fn.text instead.
Plus you use this.value
. Which should be $(this).text()
and you should initially call the calculate()
function once:
Upvotes: 1