multiply two decimals - javascript

Im trying to add a tax field. I have this working for whole numbers but i need to be able to enter ".5"
I have no clue haw to solve this problem maybe its because of the isNAN but i thought this would be ok here.
http://jsfiddle.net/thetylercox/eeMva/3/
My current code
$(document).ready(function() {
calculateSum();
$(".txt").keyup(function() {
$(".txt").each(function() {
calculateSum();
});
});
});
$("#tax").keyup(function() {
$('#total1').val(parseInt($(this).val()) * parseInt($('#subtotal').val()));
);
function calculateSum() {
var sum = 0;
$("#sum").val(sum.toFixed(2));
//iterate through each textboxes and add the values
$(".txt").each(function() {
//add only if the value is number
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#sum").html(sum.toFixed(2));
var subtotal = document.getElementById("subtotal").value == "";
var subtotal = document.getElementById("subtotal").value = sum;
function getTax(tax) {
var taxFloat = parseFloat(tax)
if (isNaN(taxFloat)) {
return 1;
} else {
return taxFloat;
}
}
var total = getTax($('#tax').val()) * sum;
var total1 = document.getElementById("total1").value = total;
} ​
Thanks

Try this:
Put all code including functions inside your $(document).ready(function(){...}) structure.
Perform all calculations, including tax, inside calculateSum().
Use jQuery all through, in particular '$(...)' in preference to .getelementById(...).
Attach calculateSum as the 'keyup' handler for all the user-enterable fields.
Purge all sorts of junk from the code
It should look like this :
$(document).ready(function(){
function getTax() {
var taxFloat = parseFloat($("#tax").val());
return isNaN(taxFloat) ? 1 : taxFloat;
}
function calculateSum() {
var sum = 0;
$(".txt").each(function() {
if (this.value && !isNaN(this.value)) {
sum += parseFloat(this.value);
}
});
$("#subtotal").val(sum.toFixed(2));
$("#total1").val((getTax()*sum).toFixed(2));
}
$(".txt, #tax").keyup(calculateSum);
});
DEMO
You probably want to change the tax algorithm to something more logical. eg. for an entered value of 5(%), the multiplier should be 1.05 .

Taxes are based on percentages. Do the following changes:
$("#tax").keyup(function() {
//$('#total1').val(parseInt($(this).val()) * parseInt($('#subtotal').val()));
calculateSum();
});
...
function getTax(tax) {
var taxFloat = parseFloat(tax)
if (isNaN(taxFloat)) {
return 1;
} else {
// 1(subtotal) + ?(tax%) -> total = (1 + tax%) * subtotal
return 1 + (taxFloat/100);
}
}
var total = getTax($('#tax').val()) * sum;
// round to 2 decimal digits
total = Math.round(total * Math.pow(10, 2)) / Math.pow(10, 2);
var total1 = document.getElementById("total1").value = total;
So for 5% you enter 5 for 0.5% you enter .5
UPDATE: (Not really an update) As I see more answers coming in, I repeat the logical error for tax field usage. Taxes are percentages worldwide, Meaning that the problem was not only the keyup handling, but also the way tax value was used.

Found your error:
$("#tax").keyup(function() {
$('#total1').val(parseInt($(this).val()) * parseInt($('#subtotal').val()));
});
Here, you parse the tax with parseInt instead of parseFloat, as you do in the function getTax. parseInt(".5") gives NaN. Try to insert values in the .txt inputs after having inserted a tax, and it would work when invoking the calculateSum function.
I can't understand why you would use a different computation when pressing keys in the #tax field than on normal keypresses in other fields. Just use the same listener function, or, if you want to divide the functionality, invoke the function to display the tax both from the #tax keyhandler and the calculateSum function.
Also, there is no need to execute calculateSum() four times when one of the inputs is updated.
See better structured source code in updated fiddle. The maths to calculate taxes and totals was not corrected.

Related

Why does if statement not work and make my element disappear using display: none?

I am building a tip calculator and I couldn't make the if statement in my function work it just skips to calculating.
function calculate() {
var bill = parseInt(document.getElementById("bill").value);
var tip = parseInt(document.getElementById("tip").value) * .01;
var persons = parseInt(document.getElementById("persons").value);
if (bill == "" || tip == "") {
alert("Please enter value");
return;
};
if (persons == "" || persons <= 1) {
persons = 1;
document.getElementById("perPerson").style.display = "none";
} else {
}
let totalTipPer = (bill * tip) / persons;
let totalPer = (bill + (tip * 100)) / persons;
let totalTip = bill * tip;
let total = bill + (tip * 100);
totalTipPer = totalTipPer.toFixed(2);
totalPer = totalPer.toFixed(2);
total = total.toFixed(2);
totalTip = totalTip.toFixed(2);
document.getElementById("total-tip/person").innerHTML = totalTipPer;
document.getElementById("total-price/person").innerHTML = totalPer;
document.getElementById("total-tip").innerHTML = totalTip;
document.getElementById("total-price").innerHTML = total;
}
document.getElementById("calculate").onclick = function () {
calculate();
document.getElementById('results').style.display = 'block';
}
I expect the div encapsulating Tip Amount per person and total per person and to not appear when the input value of persons is empty.
Function parseInt returns 'An integer number parsed from the given string. If the first character cannot be converted to a number, NaN is returned.'
if you rpovide an empty value ('') it will return
NaN which is not equal to anything, even itself.
there are several ways to fix this:
check if it is a NaN with Number.isNaN(var)
use an intermediate value like var personsValue and check if it is equal to empty string ''.
use Hybrid suggested solution and assign a 0
value for falsy value('', undefined, n
ull etc...)
The issue is that persons becomes NaN, since if the value is left blank, "" becomes NaN when it is run through parseInt().
The way to fix this is by defaulting it to 0 if the field is left blank.
var persons = parseInt(document.getElementById("persons").value || 0);
as others pointed out parseInt is returning NaN if the field is blank, but this will also happen if the user inputs $5.00 for example.
Here's one way to make sure the value can be converted to a number before doing so.
// This function determines if a JavaScript String can be converted into a number
function is_numeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function calculate() {
// first put the input values into separate variables
billValue = document.getElementById("bill").value;
tipValue = document.getElementById("tip").value;
personsValue = document.getElementById("persons").value;
// use the is_numeric() function above to check if the values can be converted to numeric
if (!is_numeric(billValue) || !is_numeric(tipValue)) {
alert("Please enter values for bill and tip");
return;
}
// the rest of your code here
}
Hope this helps.

Javascript restrict input once 2 decimal places have been reached

I currently have a number input script that behaves similar to a calculator with the way numbers are displayed, but I want to stop the adding of additional numbers to the series after two numbers past the decimal point.
Here is what I have so far, though the limiting doesn't occur correctly.
It should work like this:
1.25 - Allowed
12.5 - Allowed
125.5 - Allowed
125.55 - Allowed
123.555 - Not Allowed
rText = document.getElementById("resultText");
function selectNumber(num) {
if (!rText.value || rText.value == "0") {
rText.value = num;
}
else {
this part works...
rText.value += num;
}
}
}
but this part doesn't work... Any ideas???
if (rText.value.length - (rText.value.indexOf(".") + 1) > 2) {
return false;
} else {
rText.value += num;
}
}
}
var validate = function(e) {
var t = e.value;
e.value = (t.indexOf(".") >= 0) ? (t.substr(0, t.indexOf(".")) + t.substr(t.indexOf("."), 3)) : t;
}
<input type="text" id="resultText" oninput="validate(this)" />
Save the previous value in some data attribute and if it exceeds 2 decimal places then restore the previous value
The 2 decimal places can be checked using Math.round(tis.value*100)/100!=tis.value
Note:
I have used oninputto validate even in copy paste scenarios
function restrict(tis) {
var prev = tis.getAttribute("data-prev");
prev = (prev != '') ? prev : '';
if (Math.round(tis.value*100)/100!=tis.value)
tis.value=prev;
tis.setAttribute("data-prev",tis.value)
}
<input type="number" id="rText" oninput="restrict(this);" />
I love to use Math.floor and toFixed() to resolve my decimal issues.
Here is a example:
var value = 123.5555
var roundedNumber = (Math.floor(value * 100) / 100).toFixed(2)
roundedNumber will be "123.55" as a string. So if you want as a number just add:
var value = 123.5555
var roundedNumber = Number((Math.floor(value * 100) / 100).toFixed(2))
and now you have value as a number and fixed to up 2 decimal places.
Just copy paste this method and call this method on your respective button on which button you have to check this decimal validation.
function CheckDecimal(inputtxt)
{
var decimal= /^[-+]?[0-9]+\.[0-9]+$/;
if(inputtxt.value.match(decimal))
{
alert('Correct, try another...')
return true;
}
else
{
alert('Wrong...!')
return false;
}
}

JS calculation issue

I have a simple vat calculator, but there is something funny with one of the calculation. The problem is in the last column, saying moms. e=a + d * 0.25 is correct, but the code below is not. It shows a too big number when calculating.
JS Code:
$(document).ready(function() {
$('#submit').click(function() {
//get cost and check value
var cost = $('#cost').val();
var check = $('#checkBox');
if (cost != null && cost != "") {
if (cost < 350) {
//c = a * 1
$('#total').val(cost);
$('#toll').val("");
$('#moms').val("");
} else {
if (check.is(':checked')) {
//c = a* 1.107* 1.25
$('#total').val((cost * 1.107 * 1.25).toFixed(2));
//d = a * 0.107
$('#toll').val((cost * 0.107).toFixed(2));
} else {
$('#total').val((cost * 1.25).toFixed(2));
$('#toll').val("");
$('#moms').val("");
}
if ($('#toll').val() != null && $('#toll').val() != "") {
//e = (a + d) * 0.25
var moms = (cost + $('#toll').val()) * 0.25;
$('#moms').val(moms.toFixed(2));
}
}
}
})
});
The value of input elements will always be a string. In most of your code, you're using the "cost" value in such a way that it will be implicitly converted to a number. However, the + operator is different, and will preferentially perform string concatenation to addition.
If you explicitly force the cost to be a number when you initialize it, things should work better:
var cost = +$('#cost').val();
That leading unary + operator will force the string value to be treated as a number. Now, of course, if the string doesn't look like a good number, then cost will be set to NaN, so you should check for that:
if (!isNaN(cost)) {
That can replace your current check to see if cost is not empty.
edit Sorry, you'll also need to convert the value of $('#toll').val() so that line would look like:
var moms = (cost + +$('#toll').val()) * 0.25;
The JavaScript + operator really likes strings.

Keyup: add a value when a checkbox is checked

So I am using Keyup to calculate a total of input fields. So far so good.
But now I want to do this:
if checkbox #a is checked, add 12 to total amount. If not, add 0.
I based my code on this: http://jsfiddle.net/5xzSy/1/
$(document).keyup(function(){ // run anytime the value changes
var element1 = parseFloat($('#element1').val()) * 16.28 || 0; // get value of field and multiply by price
var total = 0+element1
});
How can I add the value of a checked checkbox and substract it if people uncheck it.
(Or even better: with a radiobutton?)
Thank you!
demo: http://jsfiddle.net/5xzSy/1079/ <-- updated (add 12 only if something is given, floatnumber)
btw: input is to be <input/> and not <input></input>
$('input').keyup(function(){ // run anytime the value changes
var firstValue = parseFloat($('#first').val()); // get value of field
var secondValue = parseFloat($('#second').val()); // convert it to a float
var thirdValue = parseFloat($('#third').val());
$('#added').html(firstValue + secondValue + thirdValue); // add them and output it
});
$('#check').on('change', function () {
var total = parseFloat($('#added').text()); // <-- update for float
if (total) {
if ($(this).is(':checked')) {
total = total + 12;
} else {
total = total - 12;
}
$('#added').text(total);
}
})
This should do it...
$(document).keyup(function(){ // run anytime the value changes
var element1 = parseFloat($('#element1').val()) * 16.28 || 0; // get value of field and multiply by price
var total = element1;
if ($('#a').is(':checked')) {
total = total + 12;
}
});

Calculation results not displaying in totals table javascript

I'm trying to create a paycheck calculator, but when I enter the hourly rate and number of hours and hit calculate, all I'm getting is undefined in my totals table. Here is my javascript:
var $ = function (id) {
return document.getElementById(id);
}
function updateTotal () {
var rate;
var hours = parseFloat( $("numHours").value);
var regularHours;
var overtime;
var doubletime;
//begin determine hourly rate
function checkJob () {
if ($('job').value == 'job0') {
rate = 0;
}
if ($('job').value == 'job1') {
rate = 12;
}
if ($('job').value == 'job2') {
rate = 10;
}
if ($('job').value == 'job3') {
rate = 11;
}
}
//calculate hours breakdown
function checkHours () {
if (hours.value <= 40) {
regularHours = hours.value;
overtime = 0;
doubletime = 0;
}
if (hours.value < 60) {
regularHours = 40;
overtime = hours.value-40;
doubletime=0;
}
if (hours.value >=60) {
regularHours = 40;
overtime = 20;
doubletime = hours.value-60;
}
}
checkJob();
checkHours();
var salary = (regularHours * rate) + (overtime * (rate * 1.5)) + (doubletime * (rate * 2))
//display amounts
$('regularHours').innerHTML = regularHours;
$('overtime').innerHTML = overtime;
$('doubletime').innerHTML = doubletime;
$('salary').innerHTML = "$ " + salary;
}
I'm sure I'm missing something silly, but I've been staring at this code for days and can't figure out what I'm doing wrong. Thanks for looking!
EDIT
The offending code is this:
hours.value
The problem with it is that hours is already a number, and number does not have the method value available to it. Changing all instances of hours.value to hours will solve the problem and properly output a calculated result.
See this demo: http://jsfiddle.net/gLthv/
The problem is the way you are implementing your jquery selectors. You should either use document.getElementById() instead, or remember that to select an id, you need to prefix the id name with a #
$("#id")
That is only the first part of the problem though. The next part is that you are using jquery, but expecting dom elements. To unwrap the jquery object, you need to use [0] with it to be able to access the contained dom element.
$("#id")[0]
Once you make these changes, you should be able to see the reflected calculations. For example, $('job').value should really be $('#job')[0].value or if you prefer to stick with jquery's implementation then you can use $('#job').val() to get the value.
Similar to this you may also access jquery's implementation of innerHTML. That would change this: $('overtime').innerHTML = overtime to $('#overtime').html(overtime)

Categories

Resources