Reputation: 11
I am new to jQuery and I am stuck. I am dynamically adding rows to a jQuery table. I want to calculate each row (length * width) = row-total I want to SUM each column and show a grand total at the bottom of the table.
I also want to dynamically add a new row when a user inputs a number in the second to last width input. So I do not have to click a button.
I have figured out how to append rows to the table but I cannot get the calculation to work. Here is my work, and a fiddle here!
<table class="table table-striped table-bordered table-condensed tab_logic turf" id="turf">
<thead>
<tr class="persist headings">
<td colspan="3"><a class="toggle" tabindex="997" href="#">Turf Measurements</a></td>
<td tabindex="998"><a class="toggle" href="#">Show / Hide</a></td>
</tr>
<tr class="headings">
<td class="heading">Turf</td>
<td class="heading">Length</td>
<td class="heading">Width</td>
<td class="heading">Total</td>
</tr>
<tr class="grand-total">
<td>Combined Totals</td>
<td class="length-total"></td>
<td class="width-total"></td>
<td class="table-total" ></td>
</tr>
</thead>
<tfoot>
<tr class="grand-total persist">
<td>Combined Totals</td>
<td class="length-total"></td>
<td class="width-total"></td>
<td class="table-total" ></td>
</tr>
</tfoot>
<tbody>
<tr id='addr1' class="calculation visible">
<td>1</td>
<td class="length">
<input type="text" class="length form-control input-md" value="" tabindex="1" /></td>
<td class="width">
<input type="text" class="width form-control input-md" type="text" value="" tabindex="2" /></td>
<td class="row-total"><input type="text" class="row-total form-control" value="" readonly /></td>
</tr>
<tr class="calculation visible">
<td>2</td>
<td class="length">
<input type="text" class="length form-control input-md" value="" tabindex="3" /></td>
<td class="width">
<input type="text" class="width form-control input-md" value="" tabindex="4" />
</td>
<td class="row-total"><input type="text" class="row-total form-control" value="" readonly />
</td>
</tr>
<tr id='addr2' class="calculation visible">
</tbody>
</table>
<div><a id="add_row" class="btn btn-default pull-left"><span class="glyphicon glyphicon-plus-sign"></span> Add Row</a></div>
<div><a class="btn btn-default pull-left calculate" title="calculate row">Calculate</a></div>
<div><a href="#" id='delete_row' class="pull-right btn btn-default"><span class="glyphicon glyphicon-minus-sign"></span> Delete Row</a></div>
I have two different pieces of code I was trying to use to create the calculations.
`$(document).ready(function(){
var i=2;
var ti=5;
$("#add_row").click(function(){
$('#addr'+i).html("<td>"+ (i+1) +"</td><td class='length'><input name='length"+i+"' type='text' class='length form-control input-md' value='' tabindex='"+(ti++)+"' /></td><td class='width'><input name='width"+i+"' type='text' class='width form-control input-md' value='' tabindex='"+(ti++)+"' /></td><td class='row-total'><input type='text' class='row-total form-control' value='' readonly /></td>");
$('#turf tr:last').after('<tr id="addr'+(i+1)+'" class="calculation visible"></tr>');
i++;
});//end add_row click
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
}); //end delete_row click
});//end function`
Is what adds the rows. I would prefer to have it add rows dynamically versus needing to click a button.
And this is what I am using to calculate with.
$(document).ready(function () {
$('.calculation').change('click', function() {
$('.turf').find('tbody').find('tr').each(function() {
var l = $(this).find('input.length').val();
var w = $(this).find('input.width').val();
var dateTotal = (l * w);
$(this).find('input.row-total').val(dateTotal);
}); //END .each
return false;
}); // END click
});
I have another piece of calculation code in the fiddle but it is commented out because I am getting lost trying to go between two different pieces of code.
Upvotes: 1
Views: 3888
Reputation: 178412
You need to delegate the event to the container and then point at the dynamically added object using a class. Also it is .on("click",...)
(button, radio or checkbox) or .on("change",...)
(select or text field) not .change("click",...)
Try this:
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function recalc() {
var lt=0,wt=0,tt=0;
$("#turf").find('tr').each(function () {
var l = $(this).find('input.length').val();
var w = $(this).find('input.width').val();
var dateTotal = (l * w);
$(this).find('input.row-total').val(dateTotal?dateTotal:"");
wt+=isNumber(w)?parseInt(w,10):0;
lt+=isNumber(l)?parseInt(l,10):0;
tt+=isNumber(dateTotal)?dateTotal:0;
}); //END .each
$("#length-grand-total").html(lt);
$("#width-grand-total").html(wt);
$("#table-grand-total").html(tt);
}
and add
$("#turf").on("click", ".calculation", recalc);
$("#turf").on("keyup blur", ".form-control", recalc);
// add a row if a length is entered in the last row
$("#turf").on("keyup",".length:last", function() {
if (!$(this).data("done")) { // only do this once per field
$(this).data("done",true);
addRow();
}
});
$("#delete_row").on("click",delRow);
to your load
and change tfoot to
<tfoot>
<tr class="grand-total persist">
<td>Combined Totals</td>
<td id="length-grand-total"></td>
<td id="width-grand-total"></td>
<td id="table-grand-total"></td>
</tr>
</tfoot>
Upvotes: 2