Calculate grand total per column - javascript

Can someone here help me with this? The problem with this code is that when you add column(add supplier) it can't get the grand total for each total column. Does anyone here know how to solve this? It will be a big help with my project. Thanks in advance. This is my javascript that calculates the total (not the grand total)
$(function() {
$('#add_supplier').click(function() {
$('#supplier_table > thead > tr#first-header').append('<th colspan="2" class="supplier_name">Supplier</th>');
$('#supplier_table > thead > tr#second-header').append(
'<th>Price</th>' +
'<th>Total</th>'
);
$('#supplier_table > tbody > tr').append(
'<td><input type="text" class="form-control price text-right" ></td>' +
'<td><input type="text" class="form-control total text-right" readonly></td>'
);
$('#grandtotal > tbody > tr').append(
'<td><input class="form-control" disabled></td>' +
'<td><input type="text" class="form-control grandtotal text-right" readonly=""></td>'
);
refresh_index();
});
$('#add_item').click(function() {
$('#supplier_table tbody').append($("#supplier_table tbody tr:last").clone());
refresh_index();
});
function refresh_index() {
$('.price').each(function(i) {
i++;
$(this).attr('id', 'price-' + i);
$(this).attr('data-num', i);
event_handler();
});
$('.total').each(function(i) {
i++;
$(this).attr('id', 'total-' + i);
});
$('.qty').each(function(i) {
i++;
$(this).attr('id', 'qty-' + i);
});
$('.grandtotal').each(function(i) {
i++;
$(this).attr('id', 'grandtotal-' + i);
});
$('.supplier_name').each(function(i) {
i++;
$(this).attr('id', 'supplier_name-' + i);
});
}
refresh_index();
function event_handler() {
$('.price').unbind('keyup').bind('keyup', function() {
var id = this.id;
var num = id.split('-');
var pos = $(this).closest('tr').index() + 1;
var qty = $('#qty-' + pos).val();
var price = $(this).val();
var total = parseFloat(qty) * parseFloat(price);
if (isNaN(total)) {
var total = 0;
}
$('#total-' + num[1]).val(total);
var num_of_supplier_name = $('.supplier_name').length;
sum_of_total(num_of_supplier_name);
});
}
function sum_of_total(num) {
var sum = 0;
//iterate through each textboxes and add the values
$(".total").each(function() {
//add only if the value is number
if (!isNaN($(this).val()) && $(this).val().length != 0) {
sum += parseFloat(this.value);
}
});
//.toFixed() method will roundoff the final sum to 2 decimal places
$("#grandtotal-" + num).val(sum);
}
});
#supplier_table thead th,
td {
text-align: center;
}
#grandtotal tbody input:disabled {
border: none;
border-color: transparent;
background-color: transparent;
outline: none;
box-shadow: inset 0px 0px 0px 0px red;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<h2>Bordered Table</h2>
<p>The .table-bordered class adds borders to a table:</p>
<button type="button" class="btn btn-default" id="add_supplier">Add Supplier</button>
<button type="button" class="btn btn-default" id="add_item">Add Item</button>
<table class="table table-bordered" id="supplier_table">
<thead>
<tr id="first-header">
<th></th>
<th></th>
<th colspan="2" class="supplier_name" id="supplier_name-1">Supplier</th>
</tr>
<tr id="second-header">
<th>Item</th>
<th>Qty</th>
<th>Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr class="tbody-tr">
<td><input type="text" class="form-control" value="Mouse" readonly=""></td>
<td><input type="text" class="form-control qty" value="10" readonly=""></td>
<td><input type="text" class="form-control price"></td>
<td><input type="text" class="form-control total for_sum-1" readonly=""></td>
</tr>
<tr class="tbody-tr">
<td><input type="text" class="form-control" value="Keyboard" readonly=""></td>
<td><input type="text" class="form-control qty" value="20" readonly=""></td>
<td><input type="text" class="form-control price"></td>
<td><input type="text" class="form-control total for_sum-1" readonly=""></td>
</tr>
<tr class="tbody-tr">
<td><input type="text" class="form-control" value="Monitor" readonly=""></td>
<td><input type="text" class="form-control qty" value="30" readonly=""></td>
<td><input type="text" class="form-control price"></td>
<td><input type="text" class="form-control total for_sum-1" readonly=""></td>
</tr>
</tbody>
<table class="table table-bordered" id="grandtotal">
<thead>
<tr>
</tr>
</thead>
<tbody>
<tr>
<td><input class="form-control" disabled=""></td>
<td><input class="form-control" disabled=""></td>
<td><input class="form-control" disabled value="Grand Total : " style="text-align: right;"></td>
<td><input type="text" class="form-control grandtotal text-right" readonly=""></td>
</tr>
</tbody>
</table>
</table>
</div>
Demo jsFiddle

The reason is an easy mistake often made in jQuery.
Your code is interpreted at first page load, all subsequent changes in the DOM are ignored.
There is an easy trick to always interpret all .totals.
Make "body" to find all "totals".
function sum_of_total(num) {
var sum = 0;
//iterate through each textboxes and add the values
$("body").find(".total").each(function() {
//add only if the value is number
if (!isNaN($(this).val()) && $(this).val().length != 0) {
sum += parseFloat(this.value);
}
});
//.toFixed() method will roundoff the final sum to 2 decimal places
$("#grandtotal-" + num).val(sum);
}
working fiddle: https://jsfiddle.net/juf54wby/

Related

Using jQuery to auto calculate amount

I've a simple form to auto calculate amount entered in the Amount field.
The Total Sum field is only updated upon entering the first row's Amount field. Total Sum field is not updated for subsequent rows.`
<?php
$sno = 1;
?>
<html>
<head>
<style>
body {
font-family: sans-serif;
}
#summation {
font-size: 18px;
font-weight: bold;
color: #174C68;
}
.amt {
background-color: #FEFFB0;
//font-weight: bold;
text-align: right;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th />
<th>Invoice No.</th>
<th>Invoice Date</th>
<th>Description</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
<?php echo $sno;?>
</td>
<td width="40px"><input class="txt" type="text" name="invoiceNo" style="text-transform:uppercase" /></td>
<td><input type="date" name="date" /></td>
<td><input class="txt" type="text" name="txt" /></td>
<td><input class="amt" type="number" name="amt" min="0" step="0.01" /></td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<button id="add_row" class="btn btn-primary btn-lg pull-left">Add Row</button>
<table>
<tr id="summation">
<td align="right" colspan="3">Total Sum :</td>
<td align="right" colspan="2"><span id="sum">0</span></td>
</tr>
</table>
</div>
<script>
$(document).ready(function() {
var i = 1;
var j = 1;
$("#add_row").click(function() {
$('#addr' + i).html("<td>" + (i + 1) + "</td><td><input type='text' name='invoiceNo" + i + "' class='form-control input-md' style='text-transform:uppercase'/></td><td><input type='date' name='date" + i + "' class='form-control input-md'/></td><td><input type='text' name='text" + i + "' class='form-control input-md'/></td><td><input type='number' name='amt" + i + "' class='amt' min='0' step='0.01'/></td>");
$('#tab_logic').append('<tr id="addr' + (i + 1) + '"></tr>');
i++;
});
$('.amt').each(function() {
$(this).keyup(function() {
calculateSum();
});
});
$('.amt' + j).each(function() {
$(this).keyup(function() {
calculateSum();
});
j++;
});
});
function calculateSum() {
var sum = 0;
$(".amt").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum").html(sum.toFixed(2));
}
</script>
</body>
</html>
The Total Sum field for subsequent rows is updated only when I change the contents in 1st row's Amount field.
How can I update the Total Sum automatically whenever the Amount field is entered for subsequent rows?
Thank you.
*** Updates ***
I've updated my code as per Paul's suggestion.
<?php
$sno = 1;
$i = 0;
?>
<html>
<head>
<style>
body {
font-family: sans-serif;
}
#summation {
font-size: 18px;
font-weight: bold;
color: #174C68;
}
.amt {
//background-color: #FEFFB0;
//font-weight: bold;
text-align: right;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<form enctype="multipart/form-data" method="post" name="form" id="form" action="data.php">
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic" border="1" style="border:2px solid black;border-collapse:collapse">
<thead>
<tr>
<th />
<th>Invoice No.</th>
<th>Invoice Date</th>
<th>Description</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
<?php echo $sno;?>
</td>
<td width="40px"><input class="txt" type="text" name="invoiceNo[<?php echo $i; ?>][invoiceNo]" style="text-transform:uppercase" /></td>
<td><input type="date" name="date[<?php echo $i; ?>][date]" /></td>
<td><input class="txt" type="text" name="desc[<?php echo $i; ?>][desc]" /></td>
<td><input class="amt" type="number" name="amt[<?php echo $i; ?>][amt]" step="0.01" /></td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<br>
<button id="add_row" class="btn btn-primary btn-lg pull-left" type="button">Add Row</button>
<table>
<tr id="summation">
<td align="right" colspan="3">Total Sum :</td>
<td align="right" colspan="2"><span id="sum">0.00</span></td>
</tr>
</table>
</div>
<br>
<tr>
<!--<td align="center"><button type="button" id="btn-ser1">Submit</button></td>-->
<td align="center"><button type="submit" id="btn-ser1">Submit</button></td>
</tr>
<script>
$(document).ready(function() {
var i = 1;
$('#add_row').click(function() {
$('#addr' + i).html("<td>" + (i + 1) + "</td><td><input type='text' name='invoiceNo[" + i + "][invoiceNo]' class='form-control input-md' style='text-transform:uppercase'/></td><td><input type='date' name='date[" + i + "][date]' class='form-control input-md'/></td><td><input type='text' name='desc[" + i + "][desc]' class='form-control input-md'/></td><td><input type='number' name='amt[" + i + "][amt]' class='amt' min='0' step='0.01'/></td>");
$('#tab_logic').append('<tr id="addr' + (i + 1) + '"></tr>');
i++;
});
});
$('#tab_logic').on('change', '.amt', function() {
this.value = parseFloat(this.value).toFixed(2);
});
// Use an event delegate on amt
$('#tab_logic').on('change', '.amt', function() {
calculateSum();
});
function calculateSum() {
var sum = 0;
$('.amt').each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$('#sum').html(sum.toFixed(2));
$('#total').val(sum);
}
//$('#btn-ser1').click(function(){
// data_array = $('#form').serialize();
// alert(data_array);
$('form').submit(function() {
data_array = $('#form').serialize();
//alert(data_array);
$('#arr').val(data_array);
});
</script>
<!--<input type="hidden" name="sno" value="<?php echo $sno; ?>">-->
<input type="hidden" id="total" name="total" />
<input type="hidden" id="arr" name="arr" />
</body>
</html>
When I submit the form & print the array, I get this sample output:
invoiceNo[0][invoiceNo]=a1&date[0][date]=2021-02-18&desc[0][desc]=a1&amt[0][amt]=1.47&invoiceNo[1][invoiceNo]=b2&date[1][date]=2021-02-17&desc[1][desc]=b2&amt[1][amt]=2.58&invoiceNo[2][invoiceNo]=c3&date[2][date]=2021-02-16&desc[2][desc]=c3&amt[2][amt]=3.69&total=7.74&arr=
How can I get the recurring values of invoiceNo, date, desc & amt to insert into a SQL statement?
Don't need any of the keyup, you can use the amt to delegate the handling to any of those.
Basically, remove this handling:
$('.amt').each(function() {
$(this).keyup(function() {
calculateSum();
});
});
$('.amt' + j).each(function() {
$(this).keyup(function() {
calculateSum();
});
j++;
});
Replace with:
// Use a change event delegate on amt
$('#tab_logic').on('change', '.amt', function() {
calculateSum();
});
Try the runnable example below.
Click the spinner buttons, the sum change is immediate. If a value is typed in, the sum updates after the field loses focus.
<?php
$sno = 1;
?>
<html>
<head>
<style>
body {
font-family: sans-serif;
}
#summation {
font-size: 18px;
font-weight: bold;
color: #174C68;
}
.amt {
background-color: #FEFFB0;
//font-weight: bold;
text-align: right;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th />
<th>Invoice No.</th>
<th>Invoice Date</th>
<th>Description</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
<?php echo $sno;?>
</td>
<td width="40px"><input class="txt" type="text" name="invoiceNo" style="text-transform:uppercase" /></td>
<td><input type="date" name="date" /></td>
<td><input class="txt" type="text" name="txt" /></td>
<td><input class="amt" type="number" name="amt" min="0" step="0.01" /></td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<button id="add_row" class="btn btn-primary btn-lg pull-left">Add Row</button>
<table>
<tr id="summation">
<td align="right" colspan="3">Total Sum :</td>
<td align="right" colspan="2"><span id="sum">0</span></td>
</tr>
</table>
</div>
<script>
$(document).ready(function() {
var i = 1;
var j = 1;
$("#add_row").click(function() {
$('#addr' + i).html("<td>" + (i + 1) + "</td><td><input type='text' name='invoiceNo" + i + "' class='form-control input-md' style='text-transform:uppercase'/></td><td><input type='date' name='date" + i + "' class='form-control input-md'/></td><td><input type='text' name='text" + i + "' class='form-control input-md'/></td><td><input type='number' name='amt" + i + "' class='amt' min='0' step='0.01'/></td>");
$('#tab_logic').append('<tr id="addr' + (i + 1) + '"></tr>');
i++;
});
});
// Use an event delegate on amt
$('#tab_logic').on('change', '.amt', function() {
calculateSum();
});
function calculateSum() {
var sum = 0;
$(".amt").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum").html(sum.toFixed(2));
}
</script>
</body>
</html>

How to calculate some field in one row using jquery

I have created some code to calculate some fields in row. But i added some function, so i can add row dynamically using jquery.
This is my source code on my codepen
Click here!
this is my function to calculate qtyItem column and price columns
$("tbody").keyup(function() {
var qtyItem = parseFloat($("#qtyItem").val());
var price = parseFloat($("#price").val());
var subTotal = qtyItem * price;
$("#subTotal").attr("value", subTotal);
});
the problem is when i try to calculate the 1st row, it's work fine. but the others not affected by the function in my script.
IDs must be unique, so avoid dulicated. For this you can use Template_literals (see the ${nextIdx} in the snippet).
You need to consider NaN values returned by parseFloat
Now, in your price event handler you can change strategy:
get the parent row
find an element looking for it in the children having an id starting with
The new code is now:
$(".addItem").click(function(e) {
var nextIdx = $("table tbody tr").length + 1;
var row = `<tr>
<td><input type="text" class="form-control" name="itemName" id="itemName${nextIdx}"></td>
<td><input type="number" class="form-control" name="qtyItem" id="qtyItem${nextIdx}"></td>
<td><input type="number" class="form-control" name="price" id="price${nextIdx}"></td>
<td><input type="number" class="form-control" name="subTotal" id="subTotal${nextIdx}" readonly></td>
</tr>`;
$("table").append(row);
});
//subTotal count
$("tbody").keyup(function(e) {
var crow = $(e.target).closest('tr'); // get parent row
// find qtyItem in the children
var qtyItem = parseFloat(crow.find("[id^=qtyItem]").val()) || 0;
// find price in the children
var price = parseFloat(crow.find("[id^=price]").val()) || 0;
var subTotal = qtyItem * price;
crow.find("[id^=subTotal]").attr("value", subTotal);
});
table,td, th{
border: 2px, solid, black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#">
<label for="username">Username</label>
<input id="username" type="text" placeholder="Input your username"> <br>
<label for="date">Date</label>
<input id="date" type="date"> <br>
<label for="itemSold">Item List</label>
<table>
<thead>
<tr>
<th>Item</th>
<th>Qty</th>
<th>price</th>
<th>SubTotal</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<button type="button" class="addItem">Add Item</button>
</form>
You can do it without use id attribute, instead that u can use the name attribute for each row.
$(document).ready(function() {
//add row on button click
$(".addItem").click(function() {
var row = `<tr>
<td><input type="text" class="form-control" name="itemName"></td>
<td><input type="number" class="form-control" name="qtyItem"></td>
<td><input type="number" class="form-control" name="price"></td>
<td><input type="number" class="form-control" name="subTotal" readonly></td>
</tr>`;
$("table").append(row);
});
const $tBody = $('tbody')
//subTotal count
$tBody.on("keyup", 'input[type="number"]', function() {
let $parentTr = $(this).closest("tr");
let qtyItem = parseFloat($parentTr.find('td input[name="qtyItem"]').val());
let price = parseFloat($parentTr.find('td input[name="price"]').val());
if (!isNaN(qtyItem) && !isNaN(price)) {
let subTotal = qtyItem * price;
$parentTr.find('td input[name="subTotal"]').attr("value", subTotal);
}
});
});
table,td, th{
border: 2px, solid, black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#">
<label for="username">Username</label>
<input type="text" placeholder="Input your username"> <br>
<label for="date">Date</label>
<input type="date"> <br>
<label for="itemSold">Item List</label>
<table>
<thead>
<tr>
<th>Item</th>
<th>Qty</th>
<th>price</th>
<th>SubTotal</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<button type="button" class="addItem">Add Item</button>
</form>

Table total auto-calculated when the newly expanded row is removed using Jquery

So my snippet gives me this error: this.closest is not a function but everything works fine in my page, so let's forget this part.
My question is I have a table where the column and rows can be auto-calculated when user input some values, referring this https://stackoverflow.com/a/52642412/8826120 comment. And now I am making add more button and all the functions are working fine(adding the new input values), but when I removed the new rows, it cannot auto-calculated the total values.
How can I make my total line auto-update when the newly expanded row is removed?
You can check it from below, but as I said before only on this page I've got error:this.closest is not a function. Thanks in advance
Note: I make the function like this Remove table rows updating total data using jQuery
$(document).on('input change', '.outstanding, .received, .paid', updateTable);
function updateTable() {
updateRow($(this).closest("tr"));
updateCol($(this).closest("td"), $(this));
updateTotal($(this.closest("table")));
}
function updateRow($row) {
var sum = 0,
sum2 = 0,
sum3 = 0;
$row.find('.outstanding, .received, .paid').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0) {
if ($(this).hasClass('outstanding')) {
out = $(this).val();
sum += parseFloat(this.value);
} else if ($(this).hasClass('received')) {
reci = $(this).val();
sum2 += parseFloat(this.value);
} else if ($(this).hasClass('paid')) {
paid = $(this).val()
sum3 += parseFloat(this.value);
}
}
});
$row.find('.amtOutstanding').val(sum + sum2 + sum3);
}
function updateCol($col, $input) {
var index = $col.index() + 1;
var sum = 0;
$col.closest('table').find('td:nth-child(' + index + ')').find('input').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0 && !$(this).attr('id')) {
sum += parseFloat(this.value);
}
});
if ($input.hasClass('outstanding')) {
$('#sch26_outstanding').val(sum.toFixed(2));
} else if ($input.hasClass('received')) {
$('#sch26_received').val(sum.toFixed(2));
} else if ($input.hasClass('paid')) {
$('#sch26_paid').val(sum.toFixed(2));
} else if ($input.hasClass('amtOutstanding')) {
$('#sch26_amtOutstanding').val(sum.toFixed(2));
}
}
function updateSchedule26() {
var sum = 0,
sum2 = 0,
sum3 = 0,
out, reci, paid;
$('.outstanding, .received, .paid').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0) {
if ($(this).hasClass('outstanding')) {
sum += parseFloat(this.value);
} else if ($(this).hasClass('received')) {
sum2 += parseFloat(this.value);
} else if ($(this).hasClass('paid')) {
sum3 += parseFloat(this.value);
}
}
});
var total = (parseInt(out) + parseInt(reci)) + parseInt(paid);
$(".amtOutstanding").val(parseFloat(total).toFixed(2));
$('#sch26_outstanding').val(sum.toFixed(2));
$('#sch26_received').val(sum2.toFixed(2));
$('#sch26_paid').val(sum3.toFixed(2));
}
function updateTotal($table) {
var sum = 0;
$table.find('.amtOutstanding').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$('#sch26_amtOutstanding').val(sum.toFixed(2))
}
function addMoreDepIT() {
var new_raw = $(
'<tr>'+
'<td><a href="javascript:void(0);" class="remove">Remove</td>'+
'<td><input type="number" min="0" name="" id="" class="form-control outstanding"></td>'+
'<td><input type="number" min="0" name="" id="" class="form-control received"></td>'+
'<td><input type="number" min="0" name="" id="" class="form-control paid"></td>'+
'<td><input type="number" min="0" name="" id="" class="form-control amtOutstanding" readonly></td>'+
'</tr>'
);
new_raw.insertBefore('#addMore');
$("#dep_it_table").on('click', '.remove', function() {
$(this).closest('tr').remove();
updateTable();
});
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<table class="table table-sm" id="dep_it_table">
<thead>
<tr>
<th style="width:16.67%">Name</th>
<th style="width:16.67%">Outstanding</th>
<th style="width:16.67%">Received</th>
<th style="width:16.67%">Paid</th>
<th style="width:16.67%">Sub Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name 1</td>
<td><input type="number" name="" id="" class="form-control outstanding"></td>
<td><input type="number" name="" id="" class="form-control received"></td>
<td><input type="number" name="" id="" class="form-control paid"></td>
<td><input type="number" name="" id="" class="form-control amtOutstanding" readonly></td>
</tr>
<tr>
<td>Name 2</td>
<td><input type="number" name="" id="" class="form-control outstanding"></td>
<td><input type="number" name="" id="" class="form-control received"></td>
<td><input type="number" name="" id="" class="form-control paid"></td>
<td><input type="number" name="" id="" class="form-control amtOutstanding" readonly></td>
</tr>
<tr id="addMore">
<td><i class="ft-plus hidden-lg-up"></i> Add More</td>
<td></td><td></td><td></td><td></td>
</tr>
<tr>
<td>Add Total</td>
<td><input type="number" name="" id="sch26_outstanding" class="form-control total_sum" readonly></td>
<td><input type="number" name="" id="sch26_received" class="form-control total_sum" readonly></td>
<td><input type="number" name="" id="sch26_paid" class="form-control total_sum" readonly></td>
<td><input type="number" name="" id="sch26_amtOutstanding" class="form-control" readonly></td>
</tr>
</tbody>
</table>
First you need to set all input of removed row to 0 and then recalculate every col and row total then you remove the row:
$("#dep_it_table").on('click', '.remove', function() {
var row = $(this).closest('tr');
row.find(".outstanding, .received, .paid").each(function(){
$(this).val(0)
$(this).change();
});
row.remove();
});
$(document).on('input change', '.outstanding, .received, .paid', updateTable);
function updateTable() {
updateRow($(this).closest("tr"));
updateCol($(this).closest("td"), $(this));
updateTotal($(this.closest("table")));
}
function updateRow($row) {
var sum = 0,
sum2 = 0,
sum3 = 0;
$row.find('.outstanding, .received, .paid').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0) {
if ($(this).hasClass('outstanding')) {
out = $(this).val();
sum += parseFloat(this.value);
} else if ($(this).hasClass('received')) {
reci = $(this).val();
sum2 += parseFloat(this.value);
} else if ($(this).hasClass('paid')) {
paid = $(this).val()
sum3 += parseFloat(this.value);
}
}
});
$row.find('.amtOutstanding').val(sum + sum2 + sum3);
}
function updateCol($col, $input) {
var index = $col.index() + 1;
var sum = 0;
$col.closest('table').find('td:nth-child(' + index + ')').find('input').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0 && !$(this).attr('id')) {
sum += parseFloat(this.value);
}
});
if ($input.hasClass('outstanding')) {
$('#sch26_outstanding').val(sum.toFixed(2));
} else if ($input.hasClass('received')) {
$('#sch26_received').val(sum.toFixed(2));
} else if ($input.hasClass('paid')) {
$('#sch26_paid').val(sum.toFixed(2));
} else if ($input.hasClass('amtOutstanding')) {
$('#sch26_amtOutstanding').val(sum.toFixed(2));
}
}
function updateSchedule26() {
var sum = 0,
sum2 = 0,
sum3 = 0,
out, reci, paid;
$('.outstanding, .received, .paid').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0) {
if ($(this).hasClass('outstanding')) {
sum += parseFloat(this.value);
} else if ($(this).hasClass('received')) {
sum2 += parseFloat(this.value);
} else if ($(this).hasClass('paid')) {
sum3 += parseFloat(this.value);
}
}
});
var total = (parseInt(out) + parseInt(reci)) + parseInt(paid);
$(".amtOutstanding").val(parseFloat(total).toFixed(2));
$('#sch26_outstanding').val(sum.toFixed(2));
$('#sch26_received').val(sum2.toFixed(2));
$('#sch26_paid').val(sum3.toFixed(2));
}
function updateTotal($table) {
var sum = 0;
$table.find('.amtOutstanding').each(function(i) {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$('#sch26_amtOutstanding').val(sum.toFixed(2))
}
function addMoreDepIT() {
var new_raw = $(
'<tr>'+
'<td><a href="javascript:void(0);" class="remove">Remove</td>'+
'<td><input type="number" min="0" name="" id="" class="form-control outstanding"></td>'+
'<td><input type="number" min="0" name="" id="" class="form-control received"></td>'+
'<td><input type="number" min="0" name="" id="" class="form-control paid"></td>'+
'<td><input type="number" min="0" name="" id="" class="form-control amtOutstanding" readonly></td>'+
'</tr>'
);
new_raw.insertBefore('#addMore');
$("#dep_it_table").on('click', '.remove', function() {
var row = $(this).closest('tr');
row.find(".outstanding, .received, .paid").each(function(){
$(this).val(0)
$(this).change();
});
row.remove();
});
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<table class="table table-sm" id="dep_it_table">
<thead>
<tr>
<th style="width:16.67%">Name</th>
<th style="width:16.67%">Outstanding</th>
<th style="width:16.67%">Received</th>
<th style="width:16.67%">Paid</th>
<th style="width:16.67%">Sub Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name 1</td>
<td><input type="number" name="" id="" class="form-control outstanding"></td>
<td><input type="number" name="" id="" class="form-control received"></td>
<td><input type="number" name="" id="" class="form-control paid"></td>
<td><input type="number" name="" id="" class="form-control amtOutstanding" readonly></td>
</tr>
<tr>
<td>Name 2</td>
<td><input type="number" name="" id="" class="form-control outstanding"></td>
<td><input type="number" name="" id="" class="form-control received"></td>
<td><input type="number" name="" id="" class="form-control paid"></td>
<td><input type="number" name="" id="" class="form-control amtOutstanding" readonly></td>
</tr>
<tr id="addMore">
<td><i class="ft-plus hidden-lg-up"></i> Add More</td>
<td></td><td></td><td></td><td></td>
</tr>
<tr>
<td>Add Total</td>
<td><input type="number" name="" id="sch26_outstanding" class="form-control total_sum" readonly></td>
<td><input type="number" name="" id="sch26_received" class="form-control total_sum" readonly></td>
<td><input type="number" name="" id="sch26_paid" class="form-control total_sum" readonly></td>
<td><input type="number" name="" id="sch26_amtOutstanding" class="form-control" readonly></td>
</tr>
</tbody>
</table>

How to generate table tr based on a total number

i wrote the blow code to generate tr for my table based on a total count .
there is a input type text that contains a number and i want to generatge tr for my table according to that number
but it is not working .
here is my snippet :
function findTotal(){
var table = $("#travells");
var rowNum = parseInt($("#total").val(), 10);
var resultHtml = '';
for(var i = 0 ; i < rowNum ; i++) {
resultHtml += ["<tr>",
"<td>",
(i+1),
"</td>",
'<td><input type="name" placeholder="text goes here..."></td>',
'<td><input type="name" placeholder="text goes here..."></td>',
'</tr>'].join("\n");
}
table.html(resultHtml);
return false;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onload="findTotal()">
<input type="text" value="8" id="total"/>
<table id="travells">
<thead>
<tr class="travelcounting">
<th>name</th>
<th>gender</th>
<th>country</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" id="Name" readonly/></td>
<td class="columns"><input type="text" id="gender" readonly/></td>
<td class="columns"><input type="text" id="country" readonly/></td>
</tr>
</tbody>
</table>
</body>
$( document ).ready(function() {
var table = $("#travells");
var rowNum = parseInt($("#total").val(), 10);
var resultHtml = '';
for(var i = 0 ; i < rowNum ; i++) {
resultHtml += ["<tr>",
"<td>",
(i+1),
"</td>",
'<td><input type="name" placeholder="text goes here..."></td>',
'<td><input type="name" placeholder="text goes here..."></td>',
'</tr>'].join("\n");
}
table.html(resultHtml);
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<input type="hidden" value="8" id="total"/>
<table id="travells">
<thead>
<tr class="travelcounting">
<th>name</th>
<th>gender</th>
<th>country</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" id="Name" readonly/></td>
<td class="columns"><input type="text" id="gender" readonly/></td>
<td class="columns"><input type="text" id="country" readonly/></td>
</tr>
</tbody>
</table>
When constructing these kind of strings, the new template literals from ES6 are a good fit. See here for more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
function findTotal(){
var body = document.getElementsByTagName("tbody")[0];
var rowNum = parseInt(document.getElementById("total").value, 10);
var resultHtml = '';
for(var i = 0 ; i < rowNum ; i++) {
resultHtml += `<tr>
<td>
${(i + 1)}
</td>
<td>
<input type="name" placeholder="text goes here...">
</td>
<td>
<input type="name" placeholder="text goes here...">
</td>
</tr>`;
};
body.innerHTML = resultHtml;
};
<body onload="findTotal()">
<input type="text" value="8" id="total"/>
<table id="travells">
<thead>
<tr class="travelcounting">
<th>name</th>
<th>gender</th>
<th>country</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" id="Name" readonly/></td>
<td class="columns"><input type="text" id="gender" readonly/></td>
<td class="columns"><input type="text" id="country" readonly/></td>
</tr>
</tbody>
</table>
</body>
$("#RowC").on("click",function(){
var TRCnt=$("tbody >tr").length;
for(var i=TRCnt;i< (parseInt($("#RowNum").val())+TRCnt);i++){
let tr=$("<tr/>");
let inputName=$("<input/>",{type:"text",name:"name",placeholder:"name",value:i+1});
let inputGender=$("<input/>",{type:"text",name:"gender",placeholder:"gender"});
let inputCountry=$("<input/>",{type:"text",name:"country",placeholder:"country"});
tr.append($("<td/>").html(inputName));
tr.append($("<td/>").html(inputGender));
tr.append($("<td/>").html(inputCountry));
$("tbody").append(tr);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" id="RowNum" />
<input type="button" id="RowC" value="click" />
<hr>
<table>
<thead>
<tr>
<th>name</th>
<th>gender</th>
<th>country</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
This is the jquery code:
$("#submitButton").click(function() {
var table = $("#resultTable");
var rowNum = parseInt($("#table-row-num").val(), 10);
var resultHtml = '';
for(var i = 0 ; i < rowNum ; i++) {
resultHtml += ["<tr>",
"<td>",
(i+1),
"</td>",
'<td><input type="name" placeholder="text goes here..."></td>',
'<td><input type="name" placeholder="text goes here..."></td>',
'</tr>'].join("\n");
}
table.html(resultHtml);
return false;
});
I wish you luck with implementation. :)
The Demo here: http://jsfiddle.net/fpd8dwtw/20/

Total becomes NaN after increment 10

I have a calculation table and the total becomes NaN after adding 10 rows.
I have even tried the suggestions as stated within this Stackoverflow article.
I have been testing this for over a day now and cannot fix the error. What am I missing?
jQuery(document).ready(function($){
var counter = 2;
$("#addItem").click(function () {
if(counter>50){
alert("You have reached the maximum items allowed (50)!");
return false;
}
var newTextBoxDiv = $(document.createElement('tr'))
.attr("id", 'itemRow' + counter);
newTextBoxDiv.after().html('<td class="first"><input placeholder="Charge # ' + counter + '" class="chrg" type="text" name="data[' + counter + '][0]" id="chrg' + counter + '" ></td>' + '<td><input placeholder="Item/Part # ' + counter + '" class="item" type="text" name="data[' + counter + '][1]" id="item' + counter + '" ></td>' + '<td><input placeholder="Description ' + counter + '" class="desc" type="text" name="data[' + counter + '][2]" id="desc' + counter + '" ></td>' + '<td style="text-align:center;"><input placeholder="Qty ' + counter + '" class="qty" type="text" name="data[' + counter + '][3]" id="qty' + counter + '" size="5" style="text-align:center;" /></td>' + '<td style="text-align:right;"><input placeholder="Cost ' + counter + '" class="cost" type="text" name="data[' + counter + '][4]" id="cost' + counter + '" size="10" style="text-align:right;" /></td>' + '<td style="text-align:right;"><span class="input-group-addon">$</span><input placeholder="Sub-Total ' + counter + '" class="stotal" type="text" name="stotal'+ counter + '" id="stotal'+ counter +'" size="10" style="text-align:right;" readonly /></td>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$(document).on('keyup', '.cost', function(st){
// grab ID to get row number
thisID = $(this).attr("id");
rowNum = thisID.slice(-1);
//get Amount entered
qty = $('#qty'+rowNum).val();
//get QTY
cost = $('#cost'+rowNum).val();
$('#stotal'+rowNum).val((qty*cost).toFixed(2));
currentCount = counter-1;
var tot = Math.round(0);
$('.stotal').each(function() {
tot += parseFloat($(this).val());
});
$('#preTotal').val((tot).toFixed(2));
$('#grand_total').val((tot).toFixed(2));
});
//calculate preTotal
$(document).on('focusin', '#shipping', function(pt){
var selection = document.getElementById("addShip");
if (selection.checked){
$("#shipping").change(function(preTotal,shipping) { // input on change
var preTotal = document.getElementById('preTotal').value;
var shipping = document.getElementById('shipping').value || 0;
var pTotal = parseFloat(shipping) + parseFloat(preTotal);
document.getElementById('preTotal').value = (pTotal.toFixed(2));
});
} else {
var preTotal = document.getElementById('preTotal').value;
var shipping = document.getElementById('shipping').value || 0;
var sTotal = parseFloat(preTotal);
document.getElementById('preTotal').value = (sTotal.toFixed(2));
}
});
//calculate taxes and total
$(document).on('focusin', '#taxTotal', function(tt){
var selection = document.getElementById("addShip");
//get field results
var preTotal = document.getElementById('preTotal').value || 0;
var shipping = document.getElementById('shipping').value || 0;
var taxTotal = document.getElementById('taxTotal').value || 0;
var taxRate = document.getElementById('taxRate').value || 0;
var gTotal = document.getElementById('grand_total').value || 0;
$("#taxTotal").change(function() { // input on change
var tTotal = document.getElementById('taxTotal').value / document.getElementById('preTotal').value * 100;
document.getElementById('taxRate').value = (tTotal.toFixed(2));
});
});
//calculate total + taxes
$(document).on('focusout', '#taxTotal', function(gt){
var shipping = document.getElementById('shipping').value || 0;
var tTotal = document.getElementById('taxTotal').value || 0;
var gTotal = document.getElementById('grand_total').value;
var fTotal = parseFloat(shipping) + parseFloat(tTotal) + parseFloat(gTotal);
document.getElementById('grand_total').value = (fTotal.toFixed(2));
});
});
}
function focusField() {
$('#addItem').click(function(){
$('.chrg').focus();
});
th {padding: 2px 2px;}
td {padding: 2px 2px;}
input {padding: 0px 2px;}
#addItemBtn {}
input.filler {border-color:#fff;border-style:solid;}
.input-group-addon {
padding: 2px 5px;
font-size: 14px;
font-weight: 400;
line-height: 1;
color: #555;
text-align: center;
background-color: #eee;
box-shadow: inset 0 0 0 1px grey;
border-right: 1px #eee solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="TextBoxesGroup" style="width:100%;">
<tr>
<th style="text-align:left;">Charge #</th>
<th style="text-align:left;">Item/Part #</th>
<th style="text-align:left;">Description</th>
<th style="text-align:center;">Qty</th>
<th style="text-align:right;">Cost</th>
<th style="text-align:right;">Sub-total</th>
</tr>
<tr id="itemRow1">
<td><input placeholder="Charge # 1" class="chrg" type="text" id="chrg1" autofocus /></td>
<td><input placeholder="Item/Part # 1" class="item" type="text" id="item1" style="margin-bottom:0 !important" /></td>
<td><input placeholder="Description 1" class="desc" type="text" id="desc1" /></td>
<td style="text-align:center;"><input placeholder="Qty 1" class="qty" type="text" id="qty1" size="5" style="text-align:center;" /></td>
<td style="text-align:right;"><input placeholder="Cost 1" class="cost" type="text" id="cost1" size="10" style="text-align:right;" /></td>
<td style="text-align:right;"><span class="input-group-addon">$</span><input placeholder="Sub-Total 1" class="stotal" type="text" id="stotal1" size="10" style="text-align:right;" readonly /></td>
</tr>
</table>
<table style="width:100%;">
<tr id="rowFiller">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><input class="btn btn-primary" type="button" id="addItem" value="Add Item" size="10" style="float:right;" onclick="focusField()" /></td>
</tr>
<!--<tr id="addItemBtn">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><input type="button" id="addItem" value="Add Item" style="float:right;" /></td>
</tr>-->
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td style="text-align:right;">
<label style="padding-right:5px;">remove shipping from taxable total
<input type="checkbox" id="addShip" class="addShip" name="addShip" checked ></label>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td style="text-align:right;">
<label style="font-weight:bold;padding-right:5px;display:inline-block;">Shipping</label>
<span class="input-group-addon">$</span>
<input placeholder="$00.00" name="shipping" id="shipping" size="10" style="float:right;text-align:right;" />
</td>
</tr>
<tr>
<td></td>
<td></td>
<td style="text-align:right;">
<label style="font-weight:bold;padding-right:5px;display:inline-block;">Pre-Total</label>
<input name="preTotal" id="preTotal" size="10" style="float:right;text-align:right;" readonly /></td>
<td></td>
<td>
</td>
<td style="text-align:right;">
<div style="text-align:right;display:inline;border-right:1px #ccc solid;margin-right:5px;">
<label style="font-weight:bold;padding-right:5px;display:inline-block;">Tax</label>
<input placeholder="00" class="taxRate" name="taxRate" id="taxRate" size="1" style="text-align:center;" />
<label style="font-weight:bold;display:inline-block;">%</label>
</div>
<label style="font-weight:bold;padding-right:5px;display:inline-block;">Total Tax</label>
<span class="input-group-addon">$</span><input placeholder="$00.00" name="taxTotal" id="taxTotal" size="10" style="float:right;text-align:right;" />
</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td style="text-align:right;font-weight:bold;"><label style="font-weight:bold;padding-right:5px;display:inline-block;">Grand Total</label>
<span class="input-group-addon">$</span><input placeholder="$00.00" name="grand_total" id="grand_total" size="10" style="float:right;text-align:right;" readonly /></td>
</tr>
</table>
Update:
I have resolved the issue as shown in the jsfiddle provided.
Add below condition to your code before actually parsing the values to float.
if(preTotal === ""){
preTotal = 0; // assign number value you like
}
and
if(gTotal === ""){
gTotal = 0; // here also.
}
Because, for the first time, these values come as empty strings.
Also, I noticed the "focusin" event being handled here. It fires the handler everytime user goes to put something inside the test box provided.

Categories

Resources