I'm working on a tip calculator in Javascript where the user should be able to type in the amount of the bill, push "calculate", and see both the tip and the total (which includes the bill and the tip).
I've been working at this for a while, but can't seem to make it work correctly.
<!DOCTYPE html>
<head>
<title>Tip Calculator</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="wrapper">
<header>
<h1>Tip Calculator</h1>
</header>
<form>
Amount: $<input id="bill" type="text">
<br>
<button onclick="calc()">Calculate</button>
<br>
Tip: <span id="tip"></span>
<br>
Total: <span id="total"></span>
</form>
</div>
<script>
function calc() {
var bill = document.getElementById('bill').value;
var tip = bill * .15;
var total = bill + tip;
document.getElementById("tip").innerHTML= "$"+(tip).toFixed(2);
document.getElementById("total").innerHTML= "$"+(total).toFixed(2);
}
</script>
</body>
Any suggestions?
I'm working on a tip calculator in Javascript where the user should be able to type in the amount of the bill, push "calculate", and see both the tip and the total (which includes the bill and the tip).
I've been working at this for a while, but can't seem to make it work correctly.
<!DOCTYPE html>
<head>
<title>Tip Calculator</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="wrapper">
<header>
<h1>Tip Calculator</h1>
</header>
<form>
Amount: $<input id="bill" type="text">
<br>
<button onclick="calc()">Calculate</button>
<br>
Tip: <span id="tip"></span>
<br>
Total: <span id="total"></span>
</form>
</div>
<script>
function calc() {
var bill = document.getElementById('bill').value;
var tip = bill * .15;
var total = bill + tip;
document.getElementById("tip").innerHTML= "$"+(tip).toFixed(2);
document.getElementById("total").innerHTML= "$"+(total).toFixed(2);
}
</script>
</body>
Any suggestions?
Share Improve this question edited Jul 14, 2018 at 18:00 Jonathan Hall 79.8k19 gold badges159 silver badges203 bronze badges asked Jan 22, 2014 at 1:51 user3221658user3221658 131 gold badge1 silver badge3 bronze badges 2- 2 "can't seem to make it work correctly" doesn't help. Describe in detail your problem. – danronmoon Commented Jan 22, 2014 at 1:57
- Using a debug tool such as Firebug for Firefox can make it much easier to identify issues in your javascript code. – sreisman Commented Jan 22, 2014 at 1:57
6 Answers
Reset to default 4You have a few problems. You need the event passed by the click function so that you can stop the form from submitting traditionally, which causes a page refresh. The best practice is to attach the click handler with javascript. You also need to convert the string value of the input into an actual number so that it can be used for addition.
Live demo (click).
// get element references - no need to keep repeating this in the function
var myBtn = document.getElementById('my-button');
var tipElem = document.getElementById("tip");
var totalElem = document.getElementById("total");
//attach click event listener
myBtn.addEventListener('click', calc);
//the event object is passed to this automatically - I'm assigning it to "e"
function calc(e) {
//prevent the default action - form submit / page refresh
e.preventDefault();
var input = document.getElementById('bill');
//convert string value to Number
var bill = parseFloat(input.value);
var tip = bill * 0.15;
var total = bill + tip;
//textContent is better than innerHTML for setting text
tipElem.textContent = "$"+(tip).toFixed(2);
totalElem.textContent = "$"+(total).toFixed(2);
}
Here is the markup I remend:
<form>
<p>Amount: $<input id="bill" type="number"></p>
<button id="my-button">Calculate</button>
<p>Tip: <span id="tip"></span></p>
<p>Total: <span id="total"></span></p>
</form>
<br>
should not be used for layout. Instead, you can use display: block
on the elements that should go to a new line. Many elements do this by default, such a <p>
. I also changed the input type to number
because that that seems more appropriate here.
Unfortunately, some people are going to suggest and argue that inline js (that's any kind of javascript in your html, like onclick
) is ok to use. It isn't. I hope you will read some of these results: Why is inline JS bad?
Forms are typically used to submit data to a server for various reasons. However, they have some benefits even when everything is being done on the same page (such as being able to press enter in any input and still have it submit without using extra code). What I did here was give it an action
of the function you wanted to use and then changed your button to a standard submit
.
There are various methods for taking a string and making it into a number, I used the simplest here: Number()
. I used it on bill
in order to make the total_bill
display properly (instead of adding two strings together which just places them side by side). I changed total
to total_bill
for the variable because it is just not a good idea to name multiple things the same (e.g. the id and the variable). I missed the bill/bill, but I'll leave it as is because it does usually still work (like here).
Lastly, toFixed()
takes a number and makes it a string. Which means you have to make sure it's a number and not already a string. This is why Number()
was used again before outputting.
Try this:
<!DOCTYPE html>
<head>
<title>Tip Calculator</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="wrapper">
<header>
<h1>Tip Calculator</h1>
</header>
<form action="javascript:void(calc())">
Amount: $<input id="bill" type="text">
<br>
<input type="submit" value="Calculate">
<br>
Tip: <span id="tip"></span>
<br>
Total: <span id="total"></span>
</form>
</div>
<script>
function calc() {
var bill = Number(document.getElementById('bill').value);
var tip = bill * .15;
var total_bill = bill + tip;
document.getElementById("tip").innerHTML= "$"+Number(tip).toFixed(2);
document.getElementById("total").innerHTML= "$"+Number(total_bill).toFixed(2);
}
</script>
</body>
Try a standard input button
<input type="button" onclick="calc()" value="Calculate">
Also, the toFixed() method doesn't necessarily exist on the var. In testing in Chrome, it will work however if you explicitly cast to number
document.getElementById("tip").innerHTML= "$"+(new Number(tip)).toFixed(2);
document.getElementById("total").innerHTML= "$"+(new Number(total)).toFixed(2);
Try to use this
function calc() {
var bill = $("#bill").value;
var tip = bill * .15;
var total = bill + tip;
document.getElementById("tip").innerHTML= "$"+(tip).toFixed(2);
document.getElementById("total").innerHTML= "$"+(total).toFixed(2);
}
Also try to create JSFIDDLE for you to create some demo.
Your form is being submitted hence it is losing values. There're many way to avoid this - one - define your form as
<form onsubmit="return false">
Your total won't calculate because bill is read as string. One way to force it into number is multiply by 1, so total will be
var total = bill*1 + tip;
Here's working demo: http://jsfiddle/5GQZ8/
<!DOCTYPE html>
<head>
<title>Tip Calculator</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="wrapper">
<header>
<h1>Tip Calculator</h1>
</header>
<form>
Amount: $<input id="bill" type="text">
<br>
<a onclick="calc()">Calculate</a>
<br>
Tip: <span id="tip"></span>
<br>
Total: <span id="total"></span>
</form>
</div>
<script>
function calc() {
var bill = document.getElementById('bill').value;
var tip = bill * .15;
var btotal = bill + tip;
document.getElementById("tip").innerHTML= "$"+Number(tip);
document.getElementById("total").innerHTML= "$"+Number(btotal);
}
</script>
</body>