Calculate table rows and populate the grand total field - javascript

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));
})
});

Related

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

Jquery : Product between 2 lists of inputs into a 3rd list

I don't have much experience in jQuery, I'm facing the following challenge
I have the following table
<table>
<thead>
<tr>
<td>Qty</td>
<td>Description</td>
<td>Unit Price</td>
<td>Total Price</td>
<tr>
</thead>
<tbody>
<tr id="itemRow">
<td><input type="text" name="quantity"/></td>
<td><input type="text" name="description"/></td>
<td><input type="text" name="unitPrice"/>/td>
<td><input type="text" name="totalPrice"/></td>
<tr>
</tbody>
</table>
<input type="text" name="total"/>
Additionally, I'm able to clone #itemRow as many times as required, enlarging the amount of items.
The idea is to calculate the total price for each row (by quantity * unitPrice) and assign it to totalPrice. And assign the sum of totalPrice to total.
This is the javascript I'm using, but I get an error that says "cantidades[i].val() is not a function"
function calculate(){
var $total = $('#total');
var $cantidades = $('input[name=quantity]')
var $unitarios = $('input[name=unitPrice]')
var $totales = $('input[name=totalPrice]')
var len = $cantidades.length;
$total.val(0);
for (var i = 0; i < len; i++){
// calculate total for the row. ERROR HERE!
$totales[i].val($cantidades[i].val() * $unitarios[i].val());
// Accumulate total
$total.val($totalExento.val() + $totales[i].val());
}
}
What am I missing? I think I'm not getting "jQuery objects" from the selector but I'm not sure hot to do this.
Thanks in advance!
This line: var $cantidades = $('input[name=quantity]') retrieves a jQuery instance that cannot be accessed like you did with $cantidades[i].
Fix it like this:
var singleElementCantidades = $($cantidades[i]);
singleElementCantidades.val();
What happened is that $('input[name=quantity]') retrieves an array that is an instance of jQuery. And when you access its content by using cantidades[i] you are not managing a jQuery instance anymore, you are accessing something else wich doesn't have the definition of val.
$cantidades would give you a jquery object however by using index or 'get' property would actually give you the equivalent javascript object. So in your case, you would need to use $cantidades[i].value. instead of $cantidades[i].val().
for (var i = 0; i < len; i++){
$totales[i].value = $cantidades[i].value * $unitarios[i].value;
$total.val($totalExento.val() + $totales[i].value);
}
I think you cannot globally get $('input[name=quantity]'), $('input[name=unitPrice]') and $('input[name=totalPrice]').
You should identify them for each row.
Here a example on jsfiddle
<table>
<thead>
<tr>
<td>Qty</td>
<td>Description</td>
<td>Unit Price</td>
<td>Total Price</td>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="quantity"/></td>
<td><input type="text" name="description"/></td>
<td><input type="number" name="unitPrice"/></td>
<td><input type="number" name="totalPrice"/></td>
</tr>
</tbody>
</table>
<button type="button" id="addRow">addRow</button>
<button type="button" id="calculate">calculate</button>
<input type="number" name="total" id="total"/>
The js part:
$(document).ready(function () {
var $total = $('#total');
var $addRow = $('#addRow');
var $calculate = $('#calculate');
var $emptyRow = $('tbody tr').clone();
var $body = $('tbody');
$addRow.on('click', function () {
$body.append($emptyRow.clone());
});
$calculate.on('click', function () {
var total = 0;
$body.find('tr').each(function () {
var $row = $(this);
var q = Number($row.find('[name=quantity]').val());
var p = Number($row.find('[name=unitPrice]').val());
var subTotal = q * p;
$row.find('[name=totalPrice]').val(subTotal)
total += subTotal;
});
$total.val(total);
})
});

Javascript form sum of form inputs

I have this form working almost perfect. If I apply discount to default price is changes, if I apply taxes it autofills too. But the last field with the sum of price after discount plus taxes is not working. Any idea?
Here is the code and a Fiddle
<html>
<body>
<table width="339" border="0" cellpadding="0">
<tr>
<td width="98">Taxes</td>
<td width="115">Discount</td>
<td width="118">Default price</td>
</tr>
<tr>
<td><select class="select" name="taxes" onChange="updateInput()">
<option value="no" selected>no taxes</option>
<option value="19">19% taxes</option> <!-- <====================== -->
</select></td>
<td><select class="select" name="discount" onChange="updateInput()">
<option value="0" selected>0% discount</option>
<option value="5">5% discount</option>
<option value="10">10% discount</option>
<option value="20">20% discount</option>
</select></td>
<td><input type="text" class="input140" name="cost" id="cost" value="1000"></td>
</tr>
<tr>
<td>Price after discount</td>
<td>Taxes</td>
<td>Total Price to pay</td>
</tr>
<tr>
<td><input type="text" name="price" value="1000"></td>
<td><input type="text" name="ttaxes" value="0"></td> <!-- <====================== -->
<td><input type="text" name="total" value="0"></td>
</tr>
</table>
<script type="text/javascript">
function updateInput(){
var discount = document.getElementsByName("discount")[0].value;
var cost = document.getElementsByName("cost")[0].value;
document.getElementsByName("price")[0].value = cost - (cost * (discount / 100));
var taxes = document.getElementsByName("taxes")[0].value; // <======================
if ( isNaN( taxes ) ) // IF "no taxes" IS SELECTED...
document.getElementsByName("ttaxes")[0].value = 0;
else { cost = document.getElementsByName("price")[0].value;
document.getElementsByName("ttaxes")[0].value = (cost * (taxes / 100));
}
}
</script>
</body>
</html>
The Fiddle DEMO
https://jsfiddle.net/nte6xqdv/7/
I need the last field Total to pay to sum "Price after discount Taxes" automaticly but is not working
Thanks a lot
You may find it easier to identify the issues you are having if you separate out each part of the process.
If you store all of the elements you are going to be using at the beginning you will make your calculations easier to read plus avoid unnecessary DOM calls.
/**
* Elements
*/
var taxes = document.getElementsByName('taxes')[0];
var discount = document.getElementsByName('discount')[0];
var cost = document.getElementsByName('cost')[0];
var price = document.getElementsByName('price')[0];
var ttaxes = document.getElementsByName('ttaxes')[0];
var total = document.getElementsByName('total')[0];
/**
* Calculations
*/
function updateInput() {
price.value = cost.value - (cost.value * (discount.value / 100));
ttaxes.value = (price.value * (taxes.value / 100));
var sum = parseFloat(price.value) + parseFloat(ttaxes.value);
total.value = sum.toFixed(2);
}
/**
* Event Listeners
*/
taxes.addEventListener('change', updateInput);
discount.addEventListener('change', updateInput);
cost.addEventListener('change', updateInput);
cost.addEventListener('keyup', updateInput);
<table width="339" border="0" cellpadding="0">
<tr>
<td width="98">Taxes</td>
<td width="115">Discount</td>
<td width="118">Default price</td>
</tr>
<tr>
<td>
<select name="taxes" class="select">
<option value="0" selected>no taxes</option>
<option value="19">19% taxes</option>
</select>
</td>
<td>
<select name="discount" class="select">
<option value="0" selected>0% discount</option>
<option value="5">5% discount</option>
<option value="10">10% discount</option>
<option value="20">20% discount</option>
</select>
</td>
<td>
<input type="text" name="cost" class="input140" value="1000">
</td>
</tr>
<tr>
<td>Price after discount</td>
<td>Taxes</td>
<td>Total Price to pay</td>
</tr>
<tr>
<td><input type="text" name="price" value="1000"></td>
<td><input type="text" name="ttaxes" value="0"></td>
<td><input type="text" name="total" value="0"></td>
</tr>
</table>
I guess your problem is that two input are string, and you used + operator to concatenate them. It should be converted to a number to do add operation.
var total = document.getElementsByName("total")[0];
total.value = parseFloat(document.getElementsByName("price")[0].value) +
parseFloat(document.getElementsByName("ttaxes")[0].value);
https://jsfiddle.net/ssk7833/nte6xqdv/8/
function updateInput(){
var total = document.getElementsByName("total")[0];
var taxes = document.getElementsByName("ttaxes")[0].value;
var price = document.getElementsByName("price")[0].value;
var discount = document.getElementsByName("discount")[0].value;
var cost = document.getElementsByName("cost")[0].value;
document.getElementsByName("price")[0].value = cost - (cost * (discount / 100));
var taxes = document.getElementsByName("taxes")[0].value; // <======================
if ( isNaN( taxes ) ) // IF "no taxes" IS SELECTED...
document.getElementsByName("ttaxes")[0].value = 0;
else { cost = document.getElementsByName("price")[0].value;
document.getElementsByName("ttaxes")[0].value = parseInt(cost * (taxes / 100));
}
total.value = parseInt(taxes * 10) + parseInt(price) || parseInt(price); //No NaNs
}
call updateInput whenever the input changes uses jQuery... jQuery is very simple to use, and learn, and every JavaScript programmer should know how to use it.
In jquery... invoke the change callback:
$("#inputFieldIdHere").change(updateInput())
What will this do?
This will do several things. It will:
Wait until the input field has changed whatever is inside
When the contents of the input field changes it will call the function: updateInput()

i need to calculate grand total from sub total,

I'm using table for invoice, dynamically adding new row and deleting row option, my code work well for calculation of "quantity * productprice =tcost" each row, but I need to calculate grand total from subtotal, can anyone suggest me how to write code.
This is my script:
<script>
(function() {
"use strict";
$("table").on("change", "input", function() {
var row = $(this).closest("tr");
var qty = parseFloat(row.find(".quantity").val());
var price = parseFloat(row.find(".productprice").val());
var tcost = qty * price;
row.find(".tcost").val(isNaN(tcost) ? "" : tcost);
});
})();
</script>
my table:
<table class="table table-bordered inventory" style="width:95%;float:right;">
<thead>
<tr>
<th><input class='check_all' type='checkbox' onclick="select_all()"/></th>
<th>S. No</th>
<th>Product Name</th>
<th>Item Code</th>
<th>Quantity</th>
<th>Price per Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr for="input01">
<td><input type='checkbox' class='case'/></td>
<td><span id='snum'>1.</span></td>
<td><input type='text' id='productname_1' name='productname[]' required/></td>
<td><input type='text' id='itemcode_1' name='itemcode[]' required/></td>
<td><input type='text' class="quantity" id='quantity_1' name='quantity[]' style="width:165px;"required/></td>
<td><input type='text' class="productprice" id='productprice_1' name='productprice[]'style="width:165px;" required/></td>
<td><input type='text' class="tcost" id='tcost_1' name='tcost[]'style="width:165px;" /> </td>
</tr>
</tbody>
</table>
<input type='text' id='total' name='total' placeholder="Total amount" class="total" id="total"style="margin-left: 51px;"/>
I made this JSFIDDLE for you. Is that what you are asking for?
var totalValue = 0;
$(document).find(".tcost").each(function(){
totalValue += parseFloat($(this).val());
});
$("#total").val(totalValue);
JSFIDDLE
<script>
(function() {
function summarize() {
var total = 0;
$(".tcost").each(function() {
total += parseFloat($(this).val());
});
$("#total").val(total);
}
"use strict";
$("table").on("change", "input", function() {
var row = $(this).closest("tr");
var qty = parseFloat(row.find(".quantity").val());
var price = parseFloat(row.find(".productprice").val());
var tcost = qty * price;
row.find(".tcost").val(isNaN(tcost) ? "" : tcost);
summarize();
});
})();
</script>

Calculate cheaper price by more quantity in javascript

I have created a form to calculate the price times the quantity of a item. It had more choices but I narrowed it down to one choice. But now I can't figure out how give price breaks for more quantity. Basically there are price breaks as follows:
Item A is 4.60 for 1+ item. For 10+ items 3.40, 25+ 2.68 and so on until it hits 5000+ items. This is the same for items, B and C except they are priced different.
How can I calculate this using the method below:
Html Form:
<form action="#" id="price-quote" onsubmit="return false">
<table width="501" border="0" cellpadding="10" cellspacing="20" style="padding- top:30px;">
<tr>
<th width="67" scope="row">Size:</th>
<td width="273" class="select-box"> <select id="size" name="size">
<option value="None">Select Size</option>
<option value="2.5 inches">2.5 inches</option>
<option value="3 inches">3 inches</option>
<option value="Oval">Oval</option>
</select>
</td>
</tr>
<tr>
<th scope="row">Quanitity:</th>
<td><input type="text" name="quantity" id="quantity" /></td>
</tr>
<tr>
<th scope="row"> </th>
<td><input class="button" type="button" value="Update" onmousedown="getTotal()"/></td>
</tr>
<tr>
<th> Price:</th>
<td><div id="totalPrice" style="float:right;"></div></td>
</tr>
</table>
</form>
Javascript:
var size_prices= new Array();
size_prices["None"]=0;
size_prices["2.5 inches"]=4.60;
size_prices["3 inches"]=4.90;
size_prices["Oval"]=5.10;
function getSizePrice()
{
var sizePrice;
var theForm = document.forms["price-quote"];
var selectedSize = theForm.elements["size"];
sizePrice = size_prices[selectedSize.value];
return sizePrice;
}
function getQuantity()
{
var theForm = document.forms["price-quote"];
//Get a reference to the TextBox
var quantity = theForm.elements["quantity"];
var howmany =0;
//If the textbox is not blank
if(quantity.value!="")
{
howmany = parseInt(quantity.value);
}
return howmany;
}
function getTotal()
{
var instantPrice = getSizePrice() * getQuantity();
document.getElementById('totalPrice').innerHTML =
"$"+instantPrice.toFixed(2);
}
Could someone please point me in the right direction. Thank you
function getTotal()
{
var q = getQuantity();
var unitPrice = 4.60;
if(q >= 10){
unitPrice = 3.40;
} else if (q >= 25){
unitPrice = 2.68;
}
var instantPrice = unitPrice * q;
document.getElementById('totalPrice').innerHTML =
"$"+instantPrice.toFixed(2);
}

Categories