jQuery: calculate price, total, shipping and vat in a cart system - javascript

Case:
I'm trying to create a Cart system that will Calculate the price based on the quantity of ordered items, then will be sum with the shipping amount and finally calculate the grand total adding VAT price.
Code:
$(document).ready(function(){
update_amounts();
$('.qty').change(function() {
update_amounts();
});
});
function update_amounts()
{
var sum = 0.0;
$('#myTable > tbody > tr').each(function() {
var qty = $(this).find('option:selected').val();
var price = $(this).find('.price').val();
var amount = (qty*price)
sum+=amount;
$(this).find('.amount').text(''+amount);
});
//calculate the total to sum
$('.total').val(sum);
//calculate total + shipping and add VAT
var shipping = $(this).find('.shipping').val();
var total = $(this).find('.total').val();
var vat = $(this).find('.vat').val();
//calculate vat
var vat_amount = ((total, 10) * 100);
//calculate grand total
var total_shipping = (total+shipping);
var ship_amount = (total_shipping+vat_amount);
sum+=ship_amount;
$('.grandTotal').val(sum);
}
Behaviour:
This don't work even if I've taken the first part of a working fiddle, can't see data changing on item total price, and can't calculate the grand total too.
Expected Behaviour:
When an user click on the Q.ty select:
- total of the row must to be updated calculating price * qty
- total of rows price must to be updated
- the sum of total of row price must to be added to shipping price
- finally the vat, calculated on sum of total row must return the grand total.
Fiddle:
Here is a full fiddle with the html part adapted (I'm using a PHP script to populate the table) https://jsfiddle.net/a1o2nmw8/1/
Thanks to all who can collaborate.

$(document).ready(function(){
update_amounts();
$('.qty').change(function() {
update_amounts();
});
});
function update_amounts()
{
var sum = 0.0;
$('#myTable > tbody > tr').each(function() {
var qty = $(this).find('option:selected').val();
var price = $(this).find('.price').text();
var amount = (qty*price)
sum+=amount;
$(this).find('.amount').text(''+amount);
});
//calculate the total to sum
$('.total').val(sum);
//calculate total + shipping and add VAT
var shipping = $('.shipping').val();
var total = $('.total').val();
var vat = $('.vat').val();
//calculate vat
var vat_value = ((total*vat)/100);
//calculate grand total
sub_total = (parseFloat(total)+parseFloat(shipping)).toFixed(1);
var grand_total = (parseFloat(sub_total)+parseFloat(vat_value )).toFixed(1);
$('.grandTotal').val(grand_total);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table class="table table-striped" id="myTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Desc</th>
<th>Q.ty</th>
<th>Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>product</td>
<td>description</td>
<td><select class="qty" value="500">
<option value="500">500</option>
<option value="1000">1000</option>
</select></td>
<td><span class="price">50.0</span></td>
<td><span class="total">0.0</span></td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-sm-3 col-sm-offset-9">
<table class="table table-striped">
<tr>
<td>Total</td>
<td><input type="text" class="total input" value="0.0" > €</td>
</tr>
<tr>
<td>Shipping</td>
<td><input type="text" class="shipping input" value="30.0" > €</td>
</tr>
<tr>
<td>VAT</td>
<td><input type="text" class="vat input" value="22" disabled> %</td>
</tr>
<tr>
<td><strong>Grand Total</strong></td>
<td><strong><input type="text" class="grandTotal input" value="0.0" disabled> €</strong></td>
</tr>
</table>
</div>

On the Example you posted you are not using any library. Try this one, it changes for me.
UPDATED: also added .toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}); for the Grand Total.
$(document).ready(function(){
update_amounts();
$('.qty').change(function() {
update_amounts();
});
});
function update_amounts()
{
var sum = 0.0;
$('#myTable > tbody > tr').each(function() {
var qty = $(this).find('option:selected').val();
var price = $(this).find('.price').text();
var amount = (qty*price)
sum+=amount;
$(this).find('.amount').html(''+amount);
});
//calculate the total to sum
$('.total').val(sum);
//calculate total + shipping and add VAT
var shipping = $('.shipping').val();
var total = $('.total').val();
var vat = $('.vat').val();
//calculate vat
var vat_amount = ((total*vat)/100);
//calculate grand total
var total_shipping = (parseFloat(total)+parseFloat(shipping));
var grand_total = (parseFloat(total_shipping)+parseFloat(vat_amount)).toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});;
$('.grandTotal').val(grand_total);
}
https://jsfiddle.net/a1o2nmw8/10/

Can you try this???
$(document).ready(function(){
update_amounts();
$('.qty').change(function() {
update_amounts();
});
});
function update_amounts()
{
var sum = 0.0;
$('#myTable > tbody > tr').each(function() {
var qty = $(this).find('option:selected').val();
var price = $(this).find('.price').html();
var amount = (qty*price)
sum+=amount;
console.log("sum"+sum)
$('.amount').html(''+amount);
});
//calculate the total to sum
$('.total').val(sum);
//calculate total + shipping and add VAT
var shipping = $('.shipping').val();
var total = $('.total').val();
var vat = $('.vat').val();
//calculate vat
var vat_amount = ((total, 10) * 100);
//calculate grand total
var total_shipping = (total+shipping);
var ship_amount = (total_shipping+vat_amount);
sum+=ship_amount;
$('.grandTotal').val(sum);
}

For select span value, you need to use "text()", then replace
var price = $(this).find('.price').val();
By :
var price = $(this).find('.price').text();
Then :
var shipping = $(this).find('.shipping').val();
var total = $(this).find('.total').val();
var vat = $(this).find('.vat').val();
You don't need to use $(this) here, just remove and use selector as follow :
var shipping = $('.shipping').val();
var total = $('.total').val();
var vat = $('.vat').val();
And at the end, add parseFloat :
var ship_amount = parseFloat(total_shipping+vat_amount);
otherwise he just concat as a string.
Working example

The only thing you need to do is change .val() function with .text().
.val() will work fine with combobox, textboxes etc. If you want to get the text use .text().
Before doing mathematical operations convert the text to number. For that you can use parsefloat() or parseInt() methods.

Related

How do I dynamically change the ID to do calculations?

I have the same form duplicated and triplicated, and depending on clicks on a button, they appear. What I want to do is to be able to make calculations, for example, of the cell Quantity and Unit_Price a multiplication and that the result is reflected in Total Price.
I need the Quantity and Unit_Price IDs to change dynamically so that the result is displayed per cell in their respective Total Price. I already wrote a piece of code that takes the number of each cell, the problem is that I don't know how to put it with the ID so that it is dynamic (the number should change depending on the cell it is in)
This is where I don't know how the code should be:
function multiplicar() {
let quantity = parseInt(document.getElementById('id__form-1-quantity').value);
let unit_price = document.getElementById('id__form-1-unit_price').value;
let total_price = document.getElementById('id__form-1-total_price');
total_price.value = quantity * unit_price;
}
function updateEmptyFormIDs(element, totalForms) {
var thisInput = element
var currentName = element.attr('name')
var newName = currentName.replace(/__prefix__/g, totalForms)
thisInput.attr('name', newName)
thisInput.attr('id', "id__" + newName)
var newFormRow = element.closest(".part-form");
var newRowId = "row_id_" + newName
newFormRow.attr("id", newRowId)
newFormRow.addClass("new-parent-row")
var parentDiv = element.parent();
parentDiv.attr("id", "parent_id_" + newName)
var inputLabel = parentDiv.find("label")
inputLabel.attr("for", "id_" + newName)
return newFormRow
}
function addForm() {
//$('.add-new-form').click(function(e){
var formId = "id_form-TOTAL_FORMS"
var emptyRow = $("#empty-row").clone();
emptyRow.attr("id", null);
var totalForms = parseInt($('#' + formId).val());
var newFormRow;
emptyRow.find("input,select,textarea").each(function() {
newFormRow = updateEmptyFormIDs($(this), totalForms)
})
$(".part-form:last").after(newFormRow)
$('#' + formId).val(totalForms + 1);
}
<table>
<tr>
<td id="parent_id_form-1-quantity">
<input type="number" name="form-1-quantity" class="form-control" id="id__form-1-quantity">
</td>
<td id="parent_id_form-1-unit_price">
<input type="number" name="form-1-unit_price" class="form-control" onchange="multiplicar()" id="id__form-1-unit_price">
</td>
<td id="parent_id_form-1-total_price">
<input type="number" name="form-1-total_price" class="form-control" id="id__form-1-total_price">
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Trigger One Jquery Function With Another Jquery Function

In the below I have a table row where a calculation happens upon input in .quantity and the result of that calculation is placed in .amount2. This works just fine and works as you see below.
<tr class="manifest-row">
<td width = 17.5% class="productCode" onchange="populateProduct(this)">{{form.ProductCode}}</td>
<td width = 32.5% class="description">{{form.DescriptionOfGoods}}</td>
<td width = 12.5% class="quantity" oninput="calculateUnit(this)">{{form.UnitQty}}</td>
<td width = 12.5% class="unitType">{{form.Type}}</td>
<td width = 10.5% class="price" oninput="calculate(this)">{{form.Price}}</td>
<td width = 12.5% class="amount2">{{form.Amount}}</td>
</tr>
JS
function calculateUnit(el) {
// Find the row containing this cell
var row = el.closest("tr");
// Get the quantity from the `input` in the `.quantity` cell in this row
var unitQty = el.querySelector('.quantity input').value;
// Get the price from the `input` in this cell (could use `e.target` instead)
var price = row.querySelector('.price input').value;
// Do the calculation, assign to the `input` in the `.amount` cell in this row
var lineTotal = unitQty * price;
row.querySelector('.amount2 input').value = lineTotal;
}
The issue is that there can be many rows, and I have a separate function which sums all the values in the inputs where class is .amount2 and places that sum in a field #id_InvoiceTotal. But this function below does not trigger properly on input because it is being filled instead by the function above. So how can I make the function above trigger the function below? I've seen .trigger() in my online searches but I don't understand how to apply it here.
<script>
$(document).on("input", ".amount2", function() {
var total = 0;
var i = 0;
$('#form_set .amount2').each(function() {
total += parseInt($('#id_form-'+(i)+'-Amount').val());
i++;
$('#id_InvoiceTotal').val(total);
})
});
</script>
You can do it in the same function with just two additional statements like this :
function calculateUnit(el) {
let total = 0;
var row = el.closest("tr");
var unitQty = el.querySelector('.quantity input').value;
var price = row.querySelector('.price input').value;
var lineTotal = unitQty * price;
row.querySelector('.amount2 input').value = lineTotal;
document.querySelectorAll(".amount2 input").forEach(function(item){
total += item.value / 1;
});
document.querySelector("#id_InvoiceTotal").value = total;
}

jquery calculate total amount of bill

I have 3 text fields in my form. 1st one takes value of quantity in the bill 2nd one takes value of price of per unit item and 3rd one takes the value of applicable taxes. I am displaying the final bill amount in the 4th text field. I've tried the following code:
$(document).ready(function () {
$('#Quantity, #Rate, #TaxAmount').keyup(function () {
var total = 0.0;
var qty = $('#Quantity').val();
var rate = $('#Rate').val();
var tax = ('#TaxAmount').val();
var amount = (qty * rate);
total = tax + amount;
$('#TotalAmount').val(total);
});
});
after running the code nothing is being displayed in the 4th textbox with id of TotalAmount. Unable to figure out what is the problem. Somebody please guide.
Firstly, you were missing $ in the var tax line.
That aside, you'll need to use parseFloat to convert the strings you get from .val() to numbers, to be able to do arithmetic on them.
$(document).ready(function() {
var $fields = $('#Quantity, #Rate, #TaxAmount');
$fields.keyup(function() {
var qty = parseFloat($('#Quantity').val());
var rate = parseFloat($('#Rate').val());
var tax = parseFloat($('#TaxAmount').val());
var amount = (qty * rate);
var total = total = tax + amount;
$('#TotalAmount').val(total);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="Quantity" placeholder="Quantity"> *
<input id="Rate" placeholder="Rate"> +
<input id="TaxAmount" placeholder="Tax"> =
<input id="TotalAmount" readonly>
You forgot the $ sign before ('#TaxAmount'):
$(document).ready(function () {
$('#Quantity, #Rate, #TaxAmount').keyup(function () {
var total = 0;
var qty = $('#Quantity').val();
var rate = $('#Rate').val();
var tax = $('#TaxAmount').val(); // here
var amount = (qty * rate);
total = tax + amount;
$('#TotalAmount').val(total);
});
});

percentages when converting sterling to euro

Hi I am trying to convert Sterling to Euros. But I can't seem to get the percentages correct. I have tried it several ways without luck. The idea is to get 1% of the sterling price then multiply it by the conversion rate and add it to the sterling price to make the euro total, and then do the same with vat.
Hope someone can help, thanks!
Here is my code.
var input = document.querySelectorAll('input');
var conversionRate = input[0];
var sterling = input[1];
var vat = input[2];
var euro = input[3];
init();
function init() {
calculateKeyUp();
}
function calculateKeyUp() {
for (var i = 0; i < input.length; i++) {
input[i].addEventListener("keyup", function() {
//var totalLessVat = (sterling.value) + (conversionRate.value * (sterling.value / 100));
var sterling1Per = sterling.value / 100;
var convert = sterling1Per * conversionRate.value;
var totalLessVat = convert + sterling.value;
//var total = (totalLessVat) + (vat.value * (totalLessVat / 100));
var euro1Per = totalLessVat / 100;
var addVat = euro1Per * vat.value;
var total = addVat + totalLessVat;
euro.value = Math.floor(total);
});
}
}
<div id="calculator-form">
<table>
<tr>
<td>Conversion Rate: </td>
<td><input type="number" id="conversionRate"> %</td>
</tr>
<tr>
<td>Sterling Price: </td>
<td><input type="number" id="sterling"> £</td>
</tr>
<tr>
<td>Vat: </td>
<td><input type="number" id="vat"> %</td>
</tr>
<tr>
<td>Euro Price is </td>
<td><input type="number" id="euro" disabled> €</td>
</tr>
</table>
</div>
The .value of an input is going to be a String, so you will need to parse the number out of each input you are working with. If it's an int you can use:
var sterling1Per = parseInt(sterling.value, 10) / 100;
If it's a float, you can use:
var sterling1Per = parseFloat(sterling.value) / 100;
Anywhere that you use an input .value that needs to be a number needs to be parsed accordingly

Find element based on highest value of inputbox in same table row

I have a table with three columns.
Column 1 has inputboxes.
Column 2 contains a "conversion" number which multiplies it's value with the value in the inputbox (column 1)
and the result is outputted in column 3.
It would look something like this:
5 2 10
1 1 1
2 1 2
3 2 6
How can I get column 3's value based on the highest inputbox value in the same row?
My code so far:
HTML
<table border="1px">
<tbody id="mbtbody">
<tr>
<td><input class="weightinputclass" type="number" value="0"></td>
<td class="conversionclass">5</td>
<td class="totals"></td>
</tr>
<tr>
<td><input class="weightinputclass" type="number" value="0"></td>
<td class="conversionclass">1</td>
<td class="totals"></td></tr>
<tr>
<td><input class="weightinputclass" type="number" value="0"></td>
<td class="conversionclass">1</td>
<td class="totals"></td>
</tr>
</tbody>
</table>
jQuery
$("#btn").click(function(){
var rows = $("#mbtbody").children("tr");
var total = 0;
rows.each(function(idx, row) {
var $row = $(row);
total += parseInt($row.find('input.weightinputclass').val());
$("#totalweight").html(total);
});
})
$(document).on('input', '.weightinputclass', function () {
var $row = $(this).closest("tr");
var weight = $row.find("input.weightinputclass").val();
var conversion= $row.find(".conversionclass").html();
$row.find(".totals").text(weight*conversion);
})
Fiddle: https://jsfiddle.net/rdawkins/9fyLqfgr/16/
Here is a solution I found:
Javascript
$("#btn").click(function(){
var rows = $("#mbtbody").children("tr");
var total = 0;
rows.each(function(idx, row) {
var $row = $(row);
total += parseInt($row.find('input.weightinputclass').val());
$("#totalweight").html(total);
});
var currentMax = 0;
var currentMaxEl;
$('.weightinputclass').each(function (idx, element) {
var elVal = parseInt($(element).val());
if(elVal > currentMax) {
currentMax = elVal;
currentMaxEl = $(element);
}
});
var maxWeight = currentMaxEl.parent().parent().children('.totals').first().html();
$('#highestinput').html(2000 - maxWeight);
})
$(document).on('input', '.weightinputclass', function () {
var $row = $(this).closest("tr");
var weight = $row.find("input.weightinputclass").val();
var conversion= $row.find(".conversionclass").html();
$row.find(".totals").text(weight*conversion);
});
Fiddle
https://jsfiddle.net/9v6j8qub/2/

Categories

Resources