jQuery Total and subtotal gives NaN - javascript

I'm making a total and subtotal table using jQuery but I get a lot of problems. The first problem, when I reload this page, the total and subtotals display NaN even though the values from the input have been entered by default.
The second problem, data in the second row and so on, still takes the price on the first row only.
What I want:
I want the total and subtotal to be calculated automatically at the
beginning and can be changed in the future.
I want each Total to
calculate the price of each row
This is my code:
$(document).ready(function () {
$counter = 1;
$('table#invoiceitems').on('keyup', '.quantity , .price',function () {
UpdateTotals(this);
});
$counter = 1;
CalculateSubTotals();
CalculateTotal();
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('.quantity').val();
var price = $('.price').html();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.subtotal').text(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateSubTotals() {
// Calculate the Subtotals when page loads for the
// first time
var lineTotals = $('.subtotal');
var quantity = $('.quantity');
var price = $('.price').html();
$.each(lineTotals, function (i) {
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).val());
$(lineTotals[i]).text(tot.toFixed(2));
});
}
function CalculateTotal() {
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.subtotal');
var quantityTotal = $('.quantity');
var grandTotal = 0.0;
var totalQuantity = 0;
$.each(lineTotals, function (i) {
grandTotal += parseFloat($(lineTotals[i]).text());
totalQuantity += parseInt($(quantityTotal[i]).val())
});
$('.totalquantity').text(totalQuantity);
$('.grandtotal').text(parseFloat(grandTotal).toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="invoiceitems">
<thead>
<tr>
<td><strong>Paper</strong>
</td>
<td><strong>Price</strong>
</td>
<td><strong>Quantity</strong>
</td>
<td><strong>Total</strong>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"><strong>SUBTOTAL</strong>
</td>
<td>
<label class="grandtotal"></label>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">15000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">20000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
</tbody>
</table>

Inside CalculateSubTotals, price is a string:
var price = $('.price').html();
so
$(price[i]).val()
doesn't make sense - it's a plain string already, and can't be meaningfully wrapped in jQuery.
If you want to access individual .price elements, then use just $('.price').
Also, the .prices are spans, not inputs - to get the text in a span, you should use .text(). Only use .val() to get text from input-like elements, such as from input and textarea:
var price = $('.price');
// ...
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
// ^^^^^^^
The same fix needs to be made to your UpdateTotals function.
$(document).ready(function() {
$counter = 1;
$('table#invoiceitems').on('keyup', '.quantity , .price', function() {
UpdateTotals(this);
});
$counter = 1;
CalculateSubTotals();
CalculateTotal();
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('.quantity').val();
var price = $container.find('.price').text();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.subtotal').text(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateSubTotals() {
// Calculate the Subtotals when page loads for the
// first time
var lineTotals = $('.subtotal');
var quantity = $('.quantity');
var price = $('.price');
$.each(lineTotals, function(i) {
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
$(lineTotals[i]).text(tot.toFixed(2));
});
}
function CalculateTotal() {
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.subtotal');
var quantityTotal = $('.quantity');
var grandTotal = 0.0;
var totalQuantity = 0;
$.each(lineTotals, function(i) {
grandTotal += parseFloat($(lineTotals[i]).text());
totalQuantity += parseInt($(quantityTotal[i]).val())
});
$('.totalquantity').text(totalQuantity);
$('.grandtotal').text(parseFloat(grandTotal).toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="invoiceitems">
<thead>
<tr>
<td><strong>Paper</strong>
</td>
<td><strong>Price</strong>
</td>
<td><strong>Quantity</strong>
</td>
<td><strong>Total</strong>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"><strong>SUBTOTAL</strong>
</td>
<td>
<label class="grandtotal"></label>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">15000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1" />
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">20000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1" />
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
</tbody>
</table>

The problem is, You already got content of price in line var price = $('.price').html(); Then why are you trying to get value in this line $(price[i]).val() ?
There is no value key to get, And input fields only have value attribute.
Solution is,
var price = $('.price');
AND
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
$(document).ready(function () {
$counter = 1;
$('table#invoiceitems').on('keyup', '.quantity , .price',function () {
UpdateTotals(this);
});
$counter = 1;
CalculateSubTotals();
CalculateTotal();
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('.quantity').val();
var price = $('.price').html();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.subtotal').text(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateSubTotals() {
// Calculate the Subtotals when page loads for the
// first time
var lineTotals = $('.subtotal');
var quantity = $('.quantity');
var price = $('.price');
$.each(lineTotals, function (i) {
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
$(lineTotals[i]).text(tot.toFixed(2));
});
}
function CalculateTotal() {
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.subtotal');
var quantityTotal = $('.quantity');
var grandTotal = 0.0;
var totalQuantity = 0;
$.each(lineTotals, function (i) {
grandTotal += parseFloat($(lineTotals[i]).text());
totalQuantity += parseInt($(quantityTotal[i]).val())
});
$('.totalquantity').text(totalQuantity);
$('.grandtotal').text(parseFloat(grandTotal).toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="invoiceitems">
<thead>
<tr>
<td><strong>Paper</strong>
</td>
<td><strong>Price</strong>
</td>
<td><strong>Quantity</strong>
</td>
<td><strong>Total</strong>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"><strong>SUBTOTAL</strong>
</td>
<td>
<label class="grandtotal"></label>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">15000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">20000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
</tbody>
</table>

Related

Want to add CGST + SGST in Subtotal in JQuery

I have this HTML Code from Invoice:-
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Subtotal Rs.</td>
<td td class="total-value">
<textarea id="subtotal" name="i_subt" readonly="readonly"></textarea>
</td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">CGST (2.5%) Rs.</td>
<td td class="total-value">
<textarea id="cgst" name="i_cgst">.00</textarea>
</td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">SGST (2.5%) Rs.</td>
<td td class="total-value">
<textarea id="sgst" name="i_sgst">.00</textarea>
</td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Total Rs. </td>
<td class="total-value">
<textarea id="total" name="i_ttl" readonly="readonly"></textarea>
</td>
</tr>
i have this code, I want too add 2 taxes namely CGST (2.5%) & SGST (2.5%) in subtotal...
function update_total() {
var total = 0;
$('.price').each(function(i){
price = $(this).html().replace("$","");
if (!isNaN(price)) total += Number(price);
});
total = roundNumber(total,2);
$('#subtotal').html(total);
//NEED some Code here to add CGST & SGST to Total
$('#total').html(total);
update_balance();
}
My Code is adding "Qty * Unit Price = Item total" of each item in Subtotal Perfectly. I need some code to add CGST * SGST in Sub-Total to make Total.
Use the equation (total * 2.5)/100 to find GST # 2.5%.
See below code to find the GST of Subtotal and add it to total
function update_total() {
var total = 0;
var gst = 0;
$('.price').each(function(i){
price = $(this).html().replace("$","");
if (!isNaN(price)) total += Number(price);
});
total = roundNumber(total,2);
$('#subtotal').html(total);
//NEED some Code here to add CGST & SGST to Total
gst = roundNumber((total * 2.5)/100,2);
$('#cgst').html(gst);
$('#sgst').html(gst);
$('#total').html(total + gst);
update_balance();
}

Need to get the total and discount calculated on a table row via Javascript

I need to calculate totals and the discount amounts on the following table.
<tbody id="generate_invoice_table">
<tr>
<td>16</td>
<td>Glass Polish Normal</td>
<td><input type="text" class="form-control text-right quantity" value="1"></td>
<td class="price">8000.00</td><td><input type="text" class="form-control text-right discount"></td>
<td><input type="text" disabled="" class="form-control text-right amount"></td>
<td><input type="checkbox" checked="" name="check-invoice"></td>
</tr>
</tbody>
So basically, I want to enter quantity and then the discount and show the amount at the last input box.
The Javascript is given below, I get the message trs.find is not a function...
$('#invoice').delegate('.quantity,.price,.discount', 'keyup', function () {
var t = document.getElementById("generate_invoice_table");//find table data
var trs = t.getElementsByTagName("tr");
var qty = trs.find('.quantity').val();
var price = trs.find('.price').val();
var dis = trs.find('.discount').val();
varamt = (qty * price) - (qty * price * dis) / 100;
trs.find('.amount').val(amt);
total();//calculate total and show after the invoice table
});
});
function total() {
var t = 0;
$('.amount').each(function (i, e) {
varamt = $(this).val() - 0;
t += amt;
});
$('.total').html(t);
}
delete line with var t= and try to replace the next line whit this code:
var trs = $("#generate_invoice_table tr");
As was mentioned it's bettter to choso what you gonna use pure JS or jQuery. On example below there are onkeyup events on discount and quantity inputs. In event handler recalc() price, quantity and discount are read using document.getElementById selectors. The amount calculated and inserted into appropriate input.
amt count I took without changes.
function recalc() {
var price = Number(document.getElementById('price').innerText);
var quantity = Number(document.getElementById('quantity').value);
var discount = Number(document.getElementById('discount').value);
var total = '';
if (price && quantity) {
total = discount ? ((quantity * price) - (quantity * price * discount) / 100) : (quantity * price);
}
document.getElementById('amount').value = total;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tbody id="generate_invoice_table">
<tr>
<td>16</td>
<td>Glass Polish Normal</td>
<td>
<input type="text" id="quantity" class="form-control text-right quantity" value="1" onkeyup="recalc()">
</td>
<td class="price">
<span id="price">8000.00</span>
</td>
<td>
<input type="text" id="discount" class="form-control text-right discount" onkeyup="recalc()">
</td>
<td>
<input type="text" disabled="" id="amount" class="form-control text-right amount">
</td>
<td>
<input type="checkbox" checked="" name="check-invoice">
</td>
</tr>
</tbody>
Hope this helps

Error within HTML Code

I am in the process of writing a webpage. I have everything done that is needed, however, when you enter any quantity over 30 it will make the id = "shipping" color red. It does this but it does it for anything less than 30 as well. Also I am having trouble with my submit button sending off to a server/url. Any help is appreciated! I will attach my code!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Widgets R' Us </title>
<style>
table,
td {
border: 1px solid black;
}
</style>
<script type="text/javascript">
//Check if non -number or a negative number
function realNumber() {
var qty1 = document.getElementById("Quantity1").value;
var qty2 = document.getElementById("Quantity2").value;
var qty3 = document.getElementById("Quantity3").value;
//isNaN is a predetermined function
if ((isNaN(qty1) || qty1 < 0) || (isNaN(qty2) || qty2 < 0) || (isNaN(qty3) || qty3 < 0)) {
alert("The quantity given is not a real number or is a negative number!");
return false; //Will not allow for data to go to server.
} else {
return true;
}
}
function total() {
var p1 = document.getElementById("Price1").value; //Value is referenced to the input tag
var p2 = document.getElementById("Price2").value;
var p3 = document.getElementById("Price3").value;
var qty1 = document.getElementById("Quantity1").value;
var qty2 = document.getElementById("Quantity2").value;
var qty3 = document.getElementById("Quantity3").value;
var over = qty1 + qty2 + qty3;
if (realNumber()) {
var totals = (p1 * qty1) + (p2 * qty2) + (p3 * qty3);
var yes = (totals).toFixed(2);
document.getElementById("ProductTotal").innerHTML = "$" + yes;
if (over > 30) {
document.getElementById("shipping").style.color = "red";
} else {
document.getElementById("shipping").style.color = "black";
}
}
}
function checkOut() {
if (total()) {
if ((document.getElementById("shipping").style.color == "red") &&
(document.getElementById("extra").checked)) {
return true;
}
}
return false;
}
</script>
</head>
<body>
<div>
<h1><b><big> Widgets R' Us </b></strong>
</h1>
<h2><b> Order/Checkout </b></h2>
<form name "widgets" onsubmit="return checkOut();" action="https://www.reddit.com/" method="get">
<div id="mainTable">
<table>
<tr>
<td>Widget Model:</td>
<td>37AX-L
<td>
</tr>
<tr>
<td>Price per Unit:</td>
<td>$12.45 <input type="hidden" id="Price1" name="Price1" value="12.45" /</td>
</tr>
<tr>
<td>State:</td>
<td>Regular</td>
</tr>
<tr>
<td>Quantity:</td>
<td> <input type="text" id="Quantity1" name="Quantity1" value="0" /</td>
</tr>
</table>
<tr>
<td> </td>
<td> </td>
</tr>
<table>
<tr>
<td>Widget Model:</td>
<td>42XR-J</td>
</tr>
<tr>
<td>Price per Unit:</td>
<td>$15.34 <input type="hidden" id="Price2" name="Price2" value="15.34" /></td>
</tr>
<tr>
<td>State:</td>
<td>Regular</td>
</tr>
<tr>
<td>Quantity:</td>
<td> <input type="text" id="Quantity2" name="Quantity2" value="0" /></td>
</tr>
</table>
<tr>
<td> </td>
<td> </td>
</tr>
<table>
<tr>
<td>Widget Model:</td>
<td>93ZZ-A</td>
</tr>
<tr>
<td>Price per Unit:</td>
<td>$28.99 <input type="hidden" id="Price3" name="Price3" value="28.99" /></td>
</tr>
<tr>
<td>State:</td>
<td>Regular</td>
</tr>
<tr>
<td>Quantity:</td>
<td> <input type="text" id="Quantity3" name="Quantity3" value="0" /></td>
</tr>
</table>
<tr>
<td> </td>
<td> </td>
</tr>
<table>
<tr>
<td>Product Total:</td>
<td>
<p id="ProductTotal"> 0 </p>
</td>
</tr>
<tr>
<td> <input type="checkbox" id="extra" name="extra"> </td>
<td>
<p id="shipping">If the quantity exceeds 30 units, there will be extra shipping!</p>
</td>
</tr>
</table>
</div>
<tr>
<td> <input type="Submit" value="Submit" /> </td>
<td> <input type="button" value="Calculate" onClick="total()" /> </td>
</tr>
</form>
</body>
</html>
Problem with your values qty1,qty2,qty3. these values are reading as string. so instead of addding these values , its concatinating the strings. replace
var qty1 = document.getElementById("Quantity1").value;
var qty2 = document.getElementById("Quantity2").value;
var qty3 = document.getElementById("Quantity3").value;
with
var qty1 = parseInt(document.getElementById("Quantity1").value);
var qty2 = parseInt(document.getElementById("Quantity2").value);
var qty3 = parseInt(document.getElementById("Quantity3").value);
It will Solve your problem with 'Red'.
For the submit button, function total() is not returning anything. so change something like
function total() {
var p1 = document.getElementById("Price1").value; //Value is referenced to the input tag
var p2 = document.getElementById("Price2").value;
var p3 = document.getElementById("Price3").value;
var qty1 = parseInt(document.getElementById("Quantity1").value);
var qty2 = parseInt(document.getElementById("Quantity2").value);
var qty3 = parseInt(document.getElementById("Quantity3").value);
var over = qty1 + qty2 + qty3;
if (realNumber()) {
var totals = (p1 * qty1) + (p2 * qty2) + (p3 * qty3);
var yes = (totals).toFixed(2);
document.getElementById("ProductTotal").innerHTML = "$" + yes;
if (over > 30) {
document.getElementById("shipping").style.color = "red";
return true;
} else if(over>0) {
document.getElementById("shipping").style.color = "black";
return true;
}else{
document.getElementById("shipping").style.color = "black";
return false;
}
}
}
and checkout() as
function checkOut() {
if (total()) {
if (((document.getElementById("shipping").style.color == "red") &&
(document.getElementById("extra").checked))||
(document.getElementById("shipping").style.color != "red")) {
return true;
}
}
return false;
}
Replace
var over = qty1 + qty2 + qty3;
With
var over = parseInt(qty1) + parseInt(qty2) + parseInt(qty3);
There were some minor HTML errors but the real issue is that numeric strings were being concatenated. So, to get the quantity values you need to use parseInt() to extract the integer value so that math is performed instead of string concatenation. Also, it's a little odd that the user has to click the Calculate Button in order to see a total. The button does work correctly, but is this what you really want?
One more thing, as tempting as it may be to directly alter the color of elements with JavaScript, in terms of keeping the code more robust, it is preferable to simply change the class name as the code does in this example since I created two classes in the CSS for this purpose.
The form now submits as long as the checkbox is unchecked and the units do not exceed 30. I changed the method to "post" and adjusted the true/false return statements in checkOut(). Note when data is submitted using the POST method, then no form data appears appended to the URL; for more info see here. I also altered the totals() function so that now it returns a value, namely the total price.
var d = document;
d.g = d.getElementById;
var qty = [0, 0, 0, 0];
var shipping = d.g("shipping");
function realNumber() {
var qtyInvalid = [0, 0, 0, 0];
for (let i = 1, max = qtyInvalid.length; i < max; i++) {
qtyInvalid[i] = (isNaN(qty[i]) || qty[i] < 0);
}
if (qtyInvalid[1] || qtyInvalid[2] || qtyInvalid[3]) {
console.log("The quantity given is not a real number or is a negative number!");
return false;
}
return true;
}
function total() {
var over = 0;
var price = [0, 0, 0, 0];
for (j = 1, max = price.length; j < max; j++) {
price[j] = d.g("Price" + j + "").value;
qty[j] = d.g("Quantity" + j + "").value;
}
var totals = 0;
var yes = 0;
const radix = 10;
for (q = 1, max = qty.length; q < max; q++) {
over += parseInt(qty[q], radix)
}
//console.log(over);
if (!realNumber()) {
return false;
}
for (let k = 1, max2 = price.length; k < max2; k++) {
totals += (price[k] * qty[k]);
}
yes = (totals).toFixed(2);
d.g("ProductTotal").innerHTML = "$" + yes;
shipping.className = (over > 30) ? "red" : "black";
return totals;
} // end total
function checkOut() {
var retval = false;
var shippingIsRed = (shipping.className == "red");
var extraChecked = d.g("extra").checked;
if ( total() ) {
retval = (!shippingIsRed && !extraChecked)? true : false;
}
return retval;
} //end checkout
h1 {
font: 200% Arial, Helvetica;
font-weight: bold;
}
h2 {
font-weight: bold;
}
table,
td {
border: 1px solid black;
}
p.red {
color: #f00;
}
p.black {
color: #000;
}
<div>
<h1>Widgets R' Us</h1>
<h2>Order/Checkout</h2>
<form name="widgets" onsubmit="return checkOut()" action="https://www.example.com/" method="post">
<div id="mainTable">
<table>
<tr>
<td>Widget Model:</td>
<td>37AX-L
<td>
</tr>
<tr>
<td>Price per Unit:</td>
<td>$12.45 <input type="hidden" id="Price1" name="Price1" value="12.45" </td>
</tr>
<tr>
<td>State:</td>
<td>Regular</td>
</tr>
<tr>
<td>Quantity:</td>
<td> <input type="text" id="Quantity1" name="Quantity1" value="0" </td>
</tr>
</table>
<tr>
<td> </td>
<td> </td>
</tr>
<table>
<tr>
<td>Widget Model:</td>
<td>42XR-J</td>
</tr>
<tr>
<td>Price per Unit:</td>
<td>$15.34 <input type="hidden" id="Price2" name="Price2" value="15.34"></td>
</tr>
<tr>
<td>State:</td>
<td>Regular</td>
</tr>
<tr>
<td>Quantity:</td>
<td> <input type="text" id="Quantity2" name="Quantity2" value="0"></td>
</tr>
</table>
<tr>
<td> </td>
<td> </td>
</tr>
<table>
<tr>
<td>Widget Model:</td>
<td>93ZZ-A</td>
</tr>
<tr>
<td>Price per Unit:</td>
<td>$28.99 <input type="hidden" id="Price3" name="Price3" value="28.99"></td>
</tr>
<tr>
<td>State:</td>
<td>Regular</td>
</tr>
<tr>
<td>Quantity:</td>
<td> <input type="text" id="Quantity3" name="Quantity3" value="0"></td>
</tr>
</table>
<tr>
<td> </td>
<td> </td>
</tr>
<table>
<tr>
<td>Total Price:</td>
<td>
<p id="ProductTotal"> 0 </p>
</td>
</tr>
<tr>
<td> <input type="checkbox" id="extra" name="extra"> </td>
<td>
<p id="shipping" class="black">If the quantity exceeds 30 units, there will be extra shipping!</p>
</td>
</tr>
</table>
</div>
<tr>
<td> <input type="Submit" value="Submit" /> </td>
<td> <input type="button" value="Calculate" onClick="total()"> </td>
</tr>
</form>
I also removed some unnecessary repetitive code that fetches the quantity values, taking advantage of JavaScript closures and for-loops.

Why there is a 0 in the start of the value of the last input? [duplicate]

This question already has answers here:
How to add two strings as if they were numbers? [duplicate]
(20 answers)
Closed 6 years ago.
See this code. when I type some numbers in the .price and .qty inputs, if actually the t variable is 100, I get 0100 in the .total input. Why there is a 0 in the first and how can I solve it?
$('.detail').delegate('.quantity, .price, .discount', 'keyup', function() {
var tr = $(this).parent().parent();
var qty = tr.find('.quantity').val();
var price = tr.find('.price').val();
var amt = qty * price;
tr.find('.amount').val(amt);
total();
});
function total() {
var t = 0;
$('.amount').each(function(i, e) {
var amt = $(this).val();
t += amt;
});
$('.total').html(t);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody class="detail">
<tr class="row">
<td>
<input type="text" class="no" value="1">
</td>
<td>
<input type="text" class="pid">
</td>
<td>
<input type="text" class="productname">
</td>
<td>
<input type="text" class="price">
</td>
<td>
<input type="text" class="quantity">
</td>
<td>
<input type="text" class="amount">
</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><span class="total"></span></td>
</tr>
</tbody>
</table>
SEE THE FIDDLE: https://jsfiddle.net/z5d421at/
Your amount from the value is being read as a string. Use parseInt().
$('.detail').delegate('.quantity, .price, .discount', 'keyup', function() {
var tr = $(this).parent().parent();
var qty = tr.find('.quantity').val();
var price = tr.find('.price').val();
var amt = qty * price;
tr.find('.amount').val(amt);
total();
});
function total() {
var t = 0;
$('.amount').each(function(i, e) {
var amt = parseInt($(this).val());
t += amt;
});
$('.total').html(t);
}
An elements value is always a string, so $(this).val() returns a string, and doing "0" + "100" returns "0100" as those are strings.
You have coerce the strings to numbers
var t = 0;
$('.amount').each(function(i, e) {
var amt = +$(this).val();
t += amt;
});

Calculate table rows and populate the grand total field

I have table like below :
<table>
<thead>
<th>Product Type</th>
<th>Quantity</th>
<th>Unit</th>
<th>Total</th>
</thead>
<tr>
<td>Gas</td>
<td><input type="text" name="qty" /></td>
<td>
<select id="unit" name="unit">
<option value="30.42">Liter</option>
<option value="25.30">Ton</option>
<option value="45.10">Kg</option>
</td>
<td><input type="text" readonly="readonly" name="total" /></td>
</tr>
<tr>
<td>Diesel</td>
<td><input type="text" name="qty" /></td>
<td>
<select id="unit" name="unit">
<option value="20.42">Liter</option>
<option value="18.30">Ton</option>
<option value="25.10">Kg</option>
</td>
<td><input type="text" readonly="readonly" name="total" /></td>
</tr>
<tr>
<td>Fuel</td>
<td><input type="text" name="qty" /></td>
<td>
<select id="unit" name="unit">
<option value="30.42">Liter</option>
<option value="25.30">Ton</option>
<option value="45.10">Kg</option>
</td>
<td><input type="text" readonly="readonly" name="total" /></td>
</tr>
I would like to calculate ( qty * unit ) each row based qty and unit and put the result total column.
At the end of the calculation, I want to sum whole total fields and put the Grand Total field.
I tried like below which is always returning NaN but when I checked the value by typeof returning number!!! :
$(document).ready(function() {
$('input[name^=qty], select[name^=unit]').change(function(){
var total = 0;
var $row = $(this).parent();
var qty = parseFloat($row.find('input[name=qty]').val());
var price = parseFloat($row.find("select[name='unit'] option:selected").val());
total = parseFloat(qty * price);
$row.find('.amount').text(parseFloat(qty * price));
})
});
There are several errors here, including using text() on an input field, and using parent() instead of closest("tr").
I've also added classes to your elements to make the selectors easier. Try this:
$('.qty, .unit').change(function(){
var total = 0;
var $row = $(this).closest("tr");
var qty = parseFloat($row.find('.qty').val());
var price = parseFloat($row.find(".unit").val());
total = parseFloat(qty * price);
$row.find('.total').val(parseFloat(qty * price));
})
Example fiddle
UPDATE
Added blank default to selects:
$('.qty, .unit').change(function(){
var total = 0;
var $row = $(this).closest("tr");
var qty = parseFloat($row.find('.qty').val());
var price = parseFloat($row.find(".unit").val());
total = qty * price;
if (isNaN(total)) {
$row.find('.total').val("");
}
else {
$row.find('.total').val(total);
}
})
Fiddle
Instead of var $row = $(this).parent(); try
var $row = $(this).closest("tr");
The code you have is looking at the td and you need to find the tr. Closest looks for the closest match up the DOM tree.
Try this,not tested
$(document).ready(function() {
$('input[name^=qty], select[name^=unit]').change(function(){
var total = 0;
var $row = $(this).parent().prev(); //changed here
var qty = parseFloat($row.find('input[name=qty]').val());
var price = parseFloat($row.find("select[name='unit'] option:selected").val());
total = parseFloat(qty * price);
$row.find('.amount').text(parseFloat(qty * price));
})
});

Categories