Subtract an integer from a calculated total - javascript

I've built a script to add quantities/units and generate a total that displays sales tax.
How can I get this calculator to recognise #discount and subtract it from the total before the GST (10% sales tax) is calculated and added?
Also, is it possible to generate the total when the page loads? Instead of a user having to press the 'Generate total' button?
HTML
<ul>
<li> Item 1 (<input type="text" name="others" size="4" value="5" readonly="readonly" class="readonly_field"/> units)</li>
<li> Item 2 (<input type="text" name="others" size="4" value="1" readonly="readonly" class="readonly_field"/> units)</li>
<li> Item 3 (<input type="text" name="others" size="4" value="3" readonly="readonly" class="readonly_field"/> units)</li>
</ul>
<input type="button" value="Generate Total" onclick="total()" /><br><br>
Discount <input type="text" id="discount" name="discount" value="500"/><br><br>
Total Units: <input type="text" id="units_total" name="units_total" readonly="readonly" /><br>
Sub Total: <input type="text" id="sub_total" name="sub_total" readonly="readonly" /><br>
Includes GST: <input type="text" id="gst_total" name="gst_total" readonly="readonly" /><br>
Total: <input type="text" id="g_total" name="g_total" readonly="readonly" />
JS
function total(){
var total_value = 0;
var all_others = document.getElementsByTagName("input");
for(var i=0; i<all_others.length; i++){
if(all_others[i].type!="text" || all_others[i].name!="others"){
continue;
}
total_value += parseFloat(all_others[i].value);
}
document.getElementById("units_total").value = (total_value).toFixed(1);
document.getElementById("sub_total").value = ((total_value) *100).toFixed(2);
document.getElementById("g_total").value = (((total_value * 10/100) + total_value) * 100).toFixed(2);
document.getElementById("gst_total").value = ((total_value * 10/100) * 100).toFixed(2);
}

Firstly, to get your function to execute on window load, wrap it in a load event:
window.onload = function() {
total();
}
Secondly, to get it to figure in discount, you just need to modify your variable a few times, but then when adding them together, make sure you parse them with .parseFloat():
if (document.getElementById('discount').value != '') {
var discount = document.getElementById('discount').value;
}
else {
var discount = 0;
}
var sub_total = (((total_value) * 100).toFixed(2) - discount).toFixed(2);
var gst = ((total_value * 10 / 100) * 100).toFixed(2);
document.getElementById("sub_total").value = sub_total;
document.getElementById("gst_total").value = gst;
document.getElementById("g_total").value = (parseFloat(sub_total) + parseFloat(gst)).toFixed(2);
DEMO

First of all, I suggest you to perform validation and computations both server side and client side. The first ensures security while the second improves the responsiveness of the UI.
Said that, you'd better introduce several support variables and perform computation on them. You should get the value from the elements you are interested into using getElementById and store it in variables.
Then you should perform computation on that variables and finally place the results in the elements you want to use to display them to the user.
To perform the operation when the page loads have a look at this.

Related

Percentage calculator outputting integer only

I have a working percentage calculator (As demonstrated below). The 1st Input is for the inital number, the 2nd input is for the percentage and the 3rd outputs the answer.
I am trying to get the answer displayed in the 3rd input field as an integer (whole number only). What JS is needed to achieve this and to show the value in the input field?
<input type="number" class="input" id="without-visitors">
<input type="number" class="input" id="without-conversion">
<input type="number" class="input" id="without-formfillenquiries" readonly>
<script>
$('#without-visitors, #without-conversion').change(function() {
var withoutvisitors = parseFloat($('#without-visitors').val())
var withoutconversion = parseFloat($('#without-conversion').val())
var withoutformfillenquiries = parseFloat($('#without-formfillenquiries').val())
$('#without-formfillenquiries').val(withoutvisitors * withoutconversion / 100);
});
</script>
I added the Math.round() function to the last line - $('#without-formfillenquiries').val(withoutvisitors * withoutconversion / 100); in order to round the result to the nearest whole integer.
$('#without-visitors, #without-conversion').change(function() {
var withoutvisitors = parseFloat($('#without-visitors').val())
var withoutconversion = parseFloat($('#without-conversion').val())
var withoutformfillenquiries = parseFloat($('#without-formfillenquiries').val())
$('#without-formfillenquiries').val(Math.round(withoutvisitors * withoutconversion / 100));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" class="input" id="without-visitors">
<input type="number" class="input" id="without-conversion">
<input type="number" class="input" id="without-formfillenquiries" readonly>

Third box locked value JS

I am using an javascript function script in html to get the product of two input boxes into third.
HTML:-
<input type="text" class="form-control" id="inputBuyPrice" placeholder="0.0" name="price" oninput="calculate()">
<input type="text" class="form-control" id="inputBuyAmount" placeholder="0.0" name="amount" oninput="calculate()">
<input type="text" class="form-control" id="inputBuyTotal" placeholder="0.0" name="total" oninput="calculate()">
And the javascript:-
<script>
function calculate() {
var myBox1 = document.getElementById('inputBuyAmount').value;
var myBox2 = document.getElementById('inputBuyPrice').value;
var result = document.getElementById('inputBuyTotal');
var numb = myBox1 * myBox2;
numb = numb.toFixed(8);
result.value = numb;
}
</script>
Now everything is working fine. But value of total gets locked by product of amount and price. I don't want it to be readonly but input that's value can be changed by user.
In a comment you've said:
Simple thing amount*price to be shown in total, but total can be changed manually and incase again price or amount change , product should be shown in total
If that's what you want, just remove the oninput="calculate()" on inputBuyTotal. That will allow the user to change it however they want, but then changing inputBuyPrice or inputBuyAmount will replace what they changed it to with the product of those fields.
(I wish the shops I buy from let me manually change the total amount to pay... 😉)
Change
oninput="calculate()"
to
oninput="calculateAmount()"
and add function calculateAmount()

Finding the value of multiple input boxes

I'm building a multiple quantity selector for my store. Image below:
On the site, the price of the product updates based on the quantity added. 10 products = 10% off etc. I'd like to be able to display this price change as and when the user edits any one of the input boxes in the quantity selector.
The input fields are built like this:
<div data-value="S" data-varientid="8195426353207" class="swatch-element swatch-element-2 size s available">
<input id="swatch-0-s" data-variant-id="variant_8195426353207" type="checkbox" name="option-0" value="S">
<label for="swatch-0-s">
S
<img class="crossed-out" src="//cdn.shopify.com/s/files/1/0020/2188/3959/t/2/assets/soldout.png?5180939831627851747" alt="">
</label>
<input id="qty" name="quantity" class="swatchinput" placeholder="0" value="0" type="text">
</div>
I'm able to watch the input boxes for change by doing the below:
var qty = $('.swatchinput');
$('.swatchinput').on('paste keyup', function() {
console.log(qty);
});
However, this returns the information about the element rather than the contents. I'm also unsure of the best way to then add the contents of the various input fields together to reach the total quantity.
You could also use the Array reduce method to do this. Select all the inputs, get the array, then reduce their values into the sum.
var total = $('.swatchinput').get().reduce(function(total, input){
return total + parseInt(input.value || '0');
}, 0);
console.log(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="quantity" class="swatchinput" placeholder="0" value="1" type="text">
<input name="quantity" class="swatchinput" placeholder="0" value="2" type="text">
<input name="quantity" class="swatchinput" placeholder="0" value="3" type="text">
<input name="quantity" class="swatchinput" placeholder="0" value="4" type="text">
This needs to be
var qty = $('.swatchinput').val();
not
var qty = $('.swatchinput');
As for your second question,
loop each of these inputs, getting the value, then add them up with a total. Initialize the total OUTSIDE of the loop also so it doesn't overwrite it.
Something like this?
var total = 0;
$('.switchinput').each(function(){
total += $(this).val();
});
console.log(total);
To get the value of an element in jQuery, use .val():
http://api.jquery.com/val/
.each loops through each matched element and runs a function on that element (accessible through 'this')
http://api.jquery.com/each/

how to multiply 2 text box values with javascript and ouput the answer to a 3rd textbox that is a ko.observable

I have a webpage that has multiple textboxes inside of a table. I need to take a value from one textbox and multiply it with another textbox then display that answer to a third text box that is a ko.observable. I have written the below javascript and I cannot get it to work at all. Absolutely nothing happens.
<script type="text/javascript">
function calculateLineTotal(numunit, rate, total) {
var rate = document.getElementById(rate).value;
var numunit = document.getElementById(numunit).value;
var sum = numunit * rate;
document.getElementById(total).value = sum;
}
and the corresponding HTML:
<td><input class="text" type="number" name="NumUnit1" id="NumUnit1" value="0.00" onchange="calculateLineTotal('NumUnit1','Rate1','Total1')"/></td>
<td><input class="text" type="number" name="Rate1" id="Rate1" value="0.00" onchange="calculateLineTotal('NumUnit1','Rate1','Total1')"/></td>
<td><input data-bind="value: total1" type="number" class="text" name="Total1" id="Total1" value="0.00"/></td>
I have tried single just simplifying the function to just throw an alert when the first textbox value is changed and nothing even happens then. Again I am a javascript newb so please be kind. Thank you in advance.
You say that the text box is bound to a ko.observable, i.e. you are using KnockoutJS. So a much cleaner way to do this would be:
<table>
<tr>
<td><input class="text" type="number" data-bind="value: numUnit1" /></td>
<td><input class="text" type="number" data-bind="value: rate1" /></td>
<td><input class="text" type="number" data-bind="value: total1" /></td>
</tr>
</table>
Then as the corresponding view model:
var ViewModel = function() {
var self = this;
self.numUnit1 = ko.observable('0.00');
self.rate1 = ko.observable('0.00');
self.total1 = ko.computed(function() {
var total = parseFloat(self.numUnit1()) * parseFloat(self.rate1());
return total.toFixed(2); // assuming you want to show to 2 decimal places
});
};
ko.applyBindings(new ViewModel());
JSFiddle: http://jsfiddle.net/mZk42/3/
See fiddle
Add class to select on using querySelectAll called "changes"
<td><input class="changes text" type="number" name="NumUnit1" id="NumUnit1" value="0.00" /></td>
<td><input class="changes text" type="number" name="Rate1" id="Rate1" value="0.00" /></td>
<td><input data-bind="value: total1" type="number" class="text" name="Total1" id="Total1" value="0.00"/></td>
Use addEventListener to bind changes. Run a forloop to add the callback, notice that the function bindCalculateTotal returns another function.
var inputs = document.querySelectorAll("input.changes");
var bindCalculateTotal = function (numunitId, rateId, totalId) {
return function(event) {
console.log(numunitId, rateId, totalId);
console.log( document.getElementById(totalId).value);
var rate = document.getElementById(rateId).value;
var numunit = document.getElementById(numunitId).value;
var total = document.getElementById(totalId).value;
var sum = numunit * rate;
document.getElementById(totalId).value = sum;
};
};
for (var ii = 0; ii < inputs.length; ii++) {
inputs[ii].addEventListener(
'change',
bindCalculateTotal("NumUnit1", "Rate1", "Total1"));
}
Also notice how we use "*Id" names to store the value. That fixes this line
document.getElementById(total).value = sum; // error: total is number, not the id
Use parseFloat(...), i.e.
var rate = parseFloat(document.getElementById(rate).value);
var numunit = parseFloat(document.getElementById(numunit).value));
var sum = numunit * rate;
Also there is a typo in one call to your function, i.e. "caclulateLineTotal" instead of "calculateLineTotal"
Also, don't set the total variable again, i.e. don't do
var total = parseFloat(document.getElementById(total).value);
Also, note that your second call to calculateLineTotal, i.e. for element Rate1 is missing a closing ' after Rate1
should be
<input class="text" type="number" name="Rate1" id="Rate1" value="0.00" onchange="calculateLineTotal('NumUnit1','Rate1','Total1');"/>

Using Javascript to calculate form fields -- get NaN as a result

I have created a short form that is supposed to calculate values based on user input. I've got most of it figured out but can't seem to get the results to show up in the totals field. Instead, I get NaN.
I'm trying to use parseInt but haven't had any luck yet.
Here is what I have so far:
The Javascript:
var AdPrice = document.getElementsByTagName('input') = 0;
var ColorCharge = document.getElementsByTagName('input') = 0;
var WebAd = document.getElementsByTagName('input') = 0;
var AdSubtotal = 0;
var DownPayment = document.getElementsByTagName('input') = 0;
var TotalPrice = 0;
var Payments = document.getElementsByTagName('input') = 0;
var TotalPayment = 0;
function updateTotal()
{
var subtotal = AdPrice + ColorCharge + WebAd;
var total = subtotal - DownPayment;
var totalmonthlypayment = total / Payments;
parseFloat(document.getElementById('AdSubtotal').value = subtotal);
parseFloat(document.getElementById('TotalPrice').value = total);
parseFloat(document.getElementById('Payment').value = totalmonthlypayment);
}
The HTML:
<fieldset>
<legend>Payment Details</legend>
Ad Charge $
<input type="text" name="AdPrice" id="AdPrice" class="medium" onChange="updateTotal()" /><br />
Color Charge +
<input type="text" name="ColorCharge" id="ColorCharge" class="medium" onChange="updateTotal()" /><br />
Web Ad +
<input type="text" name="WebAd" id="WebAd" class="medium" onChange="updateTotal()" /><br />
Subtotal =
<input type="text" name="AdSubtotal" id="AdSubtotal" readonly class="medium" /><br />
Down Payment -
<input type="text" name="DownPayment" id="DownPayment" class="medium" onChange="updateTotal()" /><br />
Total =
<input type="text" name="TotalPrice" id="TotalPrice" readonly class="medium" /><br /><br />
# Consec. Payments \
<input type="text" name="Payments" id="Payments" class="medium" onChange="updateTotal" /><br />
Amt Each Payment $
<input type="text" name="Payment" id="Payment" class="medium" readonly /><br /><br />
<input type="checkbox" name="ProratedCheck" id="ProratedCheck" /> <span style="margin-right:10px;">Prorated/Length</span><input type="text" name="ProratedLength" id="ProratedLength" />
</fieldset>
I also have a fiddle:
http://jsfiddle.net/kjetterman/eHQV4/10/
There were several errors on the javascript that you need to work on, as mentioned on the comments for your question you should use getElementById for retrieving DOM elements, other issue you had is that your code was running as soon as the browser gets the response which at the moment might not have the DOM ready for work so all your references were coming back as NULL. Here's the working version, you still need to add some validation for when the initial values are zeroes so you don't get NaN as result of operations.
http://jsfiddle.net/Wy7kE/2/
Division by zero (subtotal) at the beginning.
And:
Does this kind of binding work? I think not. Very new to me.......
What about placing the "getElements"-lines inside the method?

Categories

Resources