JavaScript syntax problem - Tip Calculator - javascript

Please, could you guys explain this syntax/expression problem?
I was practicing and I tried to create a Tip Calculator which will give me a tip value according to the bill value and percentage.
I can not understand why the expression in the variable finalValues1 does not work.
JSFiddle code result. Thank you very much.
document.getElementById('myForm').addEventListener('submit', function (e) {
e.preventDefault();
var bill, tip, percentage, finalValues1, finalValues2;
bill = document.getElementById('bills').value;
if (bill < 50) { // if bill less $50, give tip of 20%.
percentage = .2;
} else if (bill > 50 && bill < 200) { // if bill greater $50 and less than $200, give tip of 15%.
percentage = .15;
} else {
percentage = .1; // if bill greater than $200, give tip of 10%.
}
tip = bill * percentage;
// I want also to display the final value bills plus tip
finalValues1 = bill + tip; // This code does not work, it is concatenating bills and tip.
finalValues2 = bill * 1 + tip; // this code works and it sums bill plus tip. WHY is that?
document.getElementById('demo').innerHTML = "Tip: " + tip + " and total bill plus tip test1: " + finalValues1 + " test2: " + finalValues2 ;
});

bills.value is a string , not a number
if you want to get a number use bills.valueAsNumber
code:
const myForm = document.getElementById('my-form')
myForm.onsubmit=e=>
{
e.preventDefault()
let bill = myForm.bills.valueAsNumber
, percentage = (bill < 50) ? 0.2 : (bill < 200) ? 0.15 : 0.1
, tip = bill * percentage
;
myForm.demo.textContent = `Tip: ${tip.toFixed(2) } ___ total (bill + tip): ${(bill + tip).toFixed(2)}`
}
<form id="my-form" >
<output name="demo">???</output>
<br>
<br>
<label for="bills">Bill Value :</label>
<input name="bills" autocomplete="off" type="number" required step="0.01">
<br>
<br>
<button type="submit">submit</button>
</form>
as you see it is more easy to use form names instead of elements ID

Use this instead finalValues1 = Math.parseFloat(bill) + Math.parseFloat(tip);
It'll force your code to treat both variables as floats (decimal numbers), rather than strings.

Here is what I would do:
function TipCalc(percent = 20){
this.percent = percent; this.tip = this.total = 0;
this.calc = bill=>{
let t = this.percent/100*bill;
this.tip = t.toFixed(2); this.total = (bill+t).toFixed(2);
return this;
}
}
const tc = new TipCalc;
function billTest(bill){
let p;
if(bill < 50){
p = 20;
}
else if(bill < 200){
p = 15;
}
else{
p = 10;
}
tc.percent = p; tc.calc(bill);
console.log({percent:p, tip:tc.tip, total:tc.total});
}
billTest(15.72); billTest(200.01); billTest(50.01);
Note that tipCalcInstance.tip and tipCalcInstance.total are Strings.

You need to parse the value as a float bill = parseFloat(document.getElementById('bills').value);
And you really should have 0's at the start of your decimals.
You also need to check your order of operations finalValues2 = bill * 1 + tip;
Since multiplication is applied first, this will always just be (bill * 1) + tip.
Change it to bill * (1 + tip)

Related

How can I display addition operation? [duplicate]

I am creating an seat booking page with html/javascript.
This is part of the criteria I am working on:
When Passengers 1 to 4, Add £0.10 to Fare per mile
When number of miles is less than or equal to 10, then Fare per mile is £1.-
The problem is, is that when I try to add together the total cost + cost for passengers, it concatenates the variable (tried it both ways).
Any help would be greatly appreciated.
function MyFunction() {
var x, text, passengers, passengerresponse, cost;
miles = document.getElementById("miles").value;
if (isNaN(miles) || miles < 1) {
text = "Input not valid";
} else if (miles <= 10) {
cost = miles;
}
document.getElementById("miles2").innerHTML = miles;
passengers = document.getElementById("passengers").value;
if (passengers >= 1 && passengers <= 4) {
passengerresponse = "OK";
cost += passengers / 10;
}
document.getElementById("passengers2").innerHTML = passengers;
document.getElementById("totalcost").innerHTML = cost;
}
Journey in miles:
<input id="miles" type="number">
<p id="miles2"></p>
Number of passengers:
<input id="passengers" type="number">
<p id="passengers2"></p>
<button type="button" onclick="MyFunction()">Submit</button>
Total cost:
<p id="totalcost"></p>
passengers is a string, not a number. You're doing the same thing as saying cost = 'Santa' + 'Claus'; The fact that it's cost = '1' + '4'; doesn't change the '1' and '4' to a 1 and 4.
The solution is to use parseInt, Number, or one of the method from this answer.
You should convert passengers to numerical value.
Method 1 + unary oprerator
passengers = +document.getElementById("passengers").value;
Method 2 parseInt()
passengers = +document.getElementById("passengers").value;
passengers = parseInt(passengers, 10);
Cost is undefined if you put any miles in greater than 10. When you add undefined to the number of passengers, the result is Not a Number (NaN).
Also, I would recommend you use parseInt on the data you're retrieving from the inputs. Right now you're pulling them in as strings and doing math on them, which only works because Javascript has been smart enough to implicitly cast them as numeric where necessary.
function MyFunction()
{
var x, text, passengers, passengerresponse, cost;
miles = document.getElementById("miles").value; // miles is a string
miles = parseInt(miles, 10); // convert to numeric base 10
if (isNaN(miles) || miles < 1)
{
text = "Input not valid";
}
else if (miles <= 10)
{
cost = miles;
}
// if miles > 10, cost is undefined
if(!cost) cost = 0;
document.getElementById("miles2").innerHTML = miles;
passengers = document.getElementById("passengers").value; // passengers is a string
passengers = parseInt(passengers, 10); // convert passengers to a number
if (passengers >= 1 && passengers <= 4 )
{
passengerresponse = "OK";
console.log(cost, passengers);
cost += passengers / 10;
}
document.getElementById("passengers2").innerHTML = passengers;
document.getElementById("totalcost").innerHTML = cost;
}

Need help making a tip calculator

I need to make a program that will take a number and multiply it by .15 so you know how much of a tip you need to leave.
I tried to put my bill input into a new variable in my function because I would get the tip total when I took the number () out of my new variable, but doing this lead to nothing happening as JavaScript doesn't know it's a number
<body>
<input id="bill" placeholder ="How much was you meal?" />
<button onclick ="tip()"> submit</button>
<script> let bill = document.querySelector("#bill")
function tip(){
let yourTip = number( bill.value * .15)
let total = yourTip * bill
console.log ("Your tip is $" + yourTip)
console.log ("Your total after the tip is $" + total)
}
</script>
</body>
I don't need to print it on the screen just in the console and the tip % does not need to change.
try this
<input id="bill" type="number" placeholder="How much was you meal?" />
<button onclick="tip()">submit</button>
<script>
function tip() {
var bill = parseInt(document.getElementById("bill").value);
console.log(bill);
let yourTip = bill * 0.15;
let total = yourTip + bill;
console.log("Your tip is $" + yourTip);
console.log("Your total after the tip is $" + total);
}
</script>
Try this:
<style>
body {
text-align: center;
}
</style>
<body>
<input id="bill" placeholder ="How much was you meal?" />
<button onclick ="tip()">Calculate</button>
<h1 id="tip">Tip: $0</h1>
<h1 id="total">Total: $0</h1>
<script> let bill = document.querySelector("#bill")
function tip(){
let bill = document.getElementById('bill').value;
let billNum = parseInt(bill);
let yourTip = billNum * .15;
let total = yourTip + billNum;
document.getElementById('tip').innerHTML = "Tip: $" + yourTip;
document.getElementById('total').innerHTML = "Total: $" + total;
}
</script>
</body>
Let's break it down:
When you get the value of an input field, without specifying the type, JavaScript stores the value as a string. To turn that string into a number, you need to use parseInt(x), which tells the browser that the string is now a number, as you can't multiply a piece of text by a number. You can then multiply that number by the tip percentage.
Additionally, you also multiplied the tip by the bill. I added some styling, as well as using innerHTML instead of console.log() to display the tip and the total bill.
in python, you can do like this
print('Welcome to the tip calculator')
total_bill = float(input("What was the total bill? "))
what_percentage = float(input("What percentage tip would you like to give? "))
tip_percentage = (total_bill * what_percentage) / 100
total_cost = total_bill + tip_percentage
people = int(input("How many people to split the bill? "))
split_value = round(total_cost / people, 2)
print('Each person should pay' + str(split_value))

How to get if/else statement to work inside function

I'm trying to use an if/else statement inside a function to make it so that orders over 50 have free shipping (s = 0).
I previously had shipping equal 15% of the cost of the order, which is now commented out. The function did work before I tried to add the if/else statement.
There are no error codes showing.
function estcost() {
var p = document.getElementById("price").value; //gets price for plant as entered in box by user
var p = parseFloat(document.getElementById("price").value);
var t = 0.086 * p; //calculates arizona sales tax
//var s = 0.15*p;//calculates shipping cost based off of 15% of plant cost
var s;
if (p < 50) {
s = 0.15 * p; //shipping for orders under $50
} else {
s = 0; //shipping for orders $50 and over
}
return s;
var c = t + s + Number(p); //calculates final cost
var f = '$' + c.toFixed(2); //rounds cost to 2 decimal places
document.getElementById("result").innerHTML = f; //allows me to call f in html
}
You have a couple of issues:
You declare p twice. While this isn't completetly wrong, there is no need to do it. Remove the first var p = document....
You return s before you display your results. Using return will stop the function from running, thus making all the code below it not run. Either remove this (if your not doing anything with it) or move it to the bottom of your function.
Although it isn't a necessary change, you can instead declare var s to be var s = 0 and only change it if p < 50, allowing you to remove the else.
See working example below:
function estcost() {
var p = parseFloat(document.getElementById("price").value);
var t = 0.086 * p; //calculates arizona sales tax
var s = 0;
if (p < 50) {
s = 0.15 * p; //shipping for orders under $50
}
var c = t + s + Number(p); //calculates final cost
var f = '$' + c.toFixed(2); //rounds cost to 2 decimal places
document.getElementById("result").innerHTML = f; //allows me to call f in html
return s; // move to bottom
}
<input type="number" placeholder="price" id="price" />
<p>Result: <span id="result"></span></p>
<button onclick="estcost()">Estimate Cost</button>
The problem is your return statement is too soon in your function - it stops the rest of the function from executing. Placing the return statement at the bottom of the function should fix this problem:
function estcost() {
var p = document.getElementById("price").value; //gets price for plant as entered in box by user
var p = parseFloat(document.getElementById("price").value);
var t = 0.086 * p; //calculates arizona sales tax
//var s = 0.15*p;//calculates shipping cost based off of 15% of plant cost
var s;
if (p < 50) {
s = 0.15 * p; //shipping for orders under $50
} else {
s = 0; //shipping for orders $50 and over
}
var c = t + s + Number(p); //calculates final cost
var f = '$' + c.toFixed(2); //rounds cost to 2 decimal places
document.getElementById("result").innerHTML = f; //allows me to call f in html
return s;
}

JavaScript function "X - Y = Z" returns Y as Z value

I'm trying to apply a discount to a selection in JavaScript, but for some reason, my code is returning the total to subtract as the total price:
selectone = parseInt(selectone);
var textarea = document.getElementById('discount');
var word = '15off';
var textValue=textarea.value;
if (textValue.indexOf(word)!=-1)
{
var discval = parseFloat(selectone);
var num = parseInt(discval);
var retval = num - (num * .15);
} else {
var retval = 0
}
var total = selectone - retval;
document.getElementById("rettotal").innerHTML = "Price starts from £" + total;
}
For example, if something costs £100 and a 15% discount is applied, the total will be '£15' instead of '£100' ('retval' instead of 'total')
Is there something I've missed in this, or is something missing?
I've not done maths in JavaScript much so a bit over my head!
Many thanks
You've logic problem in math part.
You want to get amount after discount.
You're doing it:
var retval = num - (num * .15); // 100 - (100 * .15) = 85
But after You're removing discount from amount:
var total = selectone - retval; // 100 - 85 = 15
So here is the fix:
var price = parseFloat(selectone);
var discount = (textValue.indexOf('15off') != -1)?
price * .15
: 0;
var total = price - discount; // 100 - 15 = 85
or just be simple (if discount applies once):
var total = parseFloat(selectone);
if(textValue.indexOf('15off') != -1) {
total *= .85;
}
let's be flexible (applying multiple discounts to price):
var textValue = 'take this 15off and this 10off';
var price = parseFloat(1000);
var total = price;
total-= (textValue.indexOf('15off') != -1)?
price * .15
: 0;
console.log(total);
total-= (textValue.indexOf('10off') != -1)?
price * .15
: 0;
console.log(total);
Because... math.
selectone = parseInt(selectone);
...
var discval = parseFloat(selectone); // doesn't change the things, it's an int already
var num = parseInt(discval); // so num is essentially discval, which is selectone
var retval = num - (num * .15); // here you get 85% of num...
...
var total = selectone - retval; // here you get 15% back
The fix is to remove num - from retval, so as var retval = num * .15;
The code you've shown could be compressed to this:
var textarea = document.getElementById('discount');
var total = parseFloat(selectone)*(1-0.15*textarea.value.includes("15off"));
document.getElementById("rettotal").innerHTML = "Price starts from £" + total;
Or, if you have problems with includes() not being supported by your browser (in case it's IE), you could also use match():
var total = parseFloat(selectone)*(1-0.15*(textarea.value.match("15off")|0));
You have a JavaScript operator precedence and meaning problem there. That's syntax mistake on your part.
In an expression like this:
x - y = z
You are thinking that:
z = x - y //but it's not.
What you are really saying is:
y = z and x = x - z

JavaScript calculating wrong percentage in two inputs

I have the following inputs:
cost, where I type in a currency value, like 6,23, profit, where I type in a percentage value like 29,21 and value where the sum of the both values is show.
JavaScript does the math and returns me in value the value from cost + the currency value of the percentage typed in profit, in which case the result is 8,05 (6,23 + 29,21%).
But if try to do the same, but informing the value instead of profit, as the same 8,05, so JavaScript would return me the profit of 29,21, but it returns me 36,44.
Does anyone know what it can be?
Here is my code:
$(document).ready(function () {
$(".valor").on("input", function () {
// Margem
var valor = $(this).val();
var valorCorrigido = parseFloat(adicionarPontos(valor));
var valorFloat = parseFloat(valorCorrigido) || 0.0;
// Custo
var valorCusto = $('#custo').val();
var valorCustoCorrigido = parseFloat(removerPontos(valorCusto));
var valorCustoFloat = parseFloat(valorCustoCorrigido) || 0.0;
// Calculo
var calculo = (parseFloat(valorFloat) - parseFloat(valorCustoFloat)) / parseFloat(valorCustoFloat) * 100;
var inputMargem = $(this).attr("margem");
$("#" + inputMargem).val(calculo.toFixed(2)).trigger('blur');
});
// Faz o calculo do valor com base na margem
$(".margem").on("input", function () {
// Margem
var valorMargem = $(this).val();
var valorMargemCorrigido = parseFloat(adicionarPontos(valorMargem));
var valorMargemFloat = parseFloat(valorMargemCorrigido) || 0.0;
// Custo
var valorCusto = $('#custo').val();
var valorCustoCorrigido = parseFloat(removerPontos(valorCusto));
var valorCustoFloat = parseFloat(valorCustoCorrigido) || 0.0;
// Cálculo
var calculo = (parseFloat(valorCustoFloat) * parseFloat(valorMargemFloat) / 100) + parseFloat(valorCustoFloat);
var inputValor = $(this).attr("valor");
var resultadoMonetario = calculo.toFixed(2).toString();
resultadoMonetario = resultadoMonetario.replace(".", ",");
$("#" + inputValor).val(resultadoMonetario).trigger('blur');
});
function removerPontos(valor){
valor = valor.replace(".","");
valor = valor.replace(",",".");
return valor;
}
function adicionarPontos(valor){
if(valor.length == 1){
return valor;
}
else{
if(valor.length == 2){
return valor;
}
else{
// The problem was here
valor = valor.replace(",","");
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substr(2);
return inteiro + "." + decimal;
}
}
}
});
$('input').mask('00.000.000,00', {
reverse: true
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.13.4/jquery.mask.js"></script>
Custo:
<input type='text' id='custo' class='custo valores' name='custo'>
<br>
<br> Valor:
<input type='text' id='valor1' class='valor valores' name='valor1' margem='margem1'> Margem:
<input type='text' id='margem1' class='margem valores' name='margem1' valor="valor1">
<br> Valor:
<input type='text' id='valor2' class='valor valores' name='valor2' margem='margem2'> Margem:
<input type='text' id='margem2' class='margem valores' name='margem2' valor="valor2">
The calculations appear to be incorrect because decimal separators in JavaScript are not localized.
6,23 * 29,21 // 21
6.23 * 29.21 // 181.97830000000002
parseFloat(6,23); // 6
parseFloat(6.23); // 6.23
You can use Number.prototype.toLocaleString() or a currency formatting plugin to format the values for display, but your custo, valor, and margem values should be formatted with a . decimal separator when you do your calculations.
If your total profit equation is total = cost + (cost * profit).
Then your profit % equation should be profit = (total - cost) / cost.
Here are two functions that provide you with what you need. You might be interested to use them instead of calculating in line like how you do in your question.
function getProfitTotal(cost, profit) {
cost = parseFloat(cost, 10);
profit = parseFloat(profit, 10) / 100;
return cost + (cost * profit);
}
function getProfitMargin(cost, total) {
cost = parseFloat(cost, 10);
total = parseFloat(total, 10);
return (total - cost) / cost * 100;
}
Thus getProfitMargin(6.23, getProfitTotal(6.23, 21.23) ); will output 21.23. Just use .toFixed(2) before setting the value in your text field.
On a side note, you should only reset your field's value if the value is NaN. As of now, I am personally unable to write decimals in the example you provided because of this.
Also, all numbers have to be dot-separated. Just parse and format your numbers with a globalization library, as your current functions are not working correctly as described earlier.
So seems that the problem was in this part of the code:
valor = valor.replace(",","");
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substr(2);
return inteiro + "." + decimal;
After changing it to this worked fine:
var inteiro = valor.substring(0,valor.length - 2);
var decimal = valor.substring(valor.length - 2, valor.length);

Categories

Resources