简体   繁体   中英

Tip calculator keeps returning Nan. How do I fix it?

I am trying to do my first JS app and unfortunately JS returns NaN value instead of desired amount. I bet solution is quite simple, although I kept trying to resolve problem on my own for past 2 hours and nothing works...

 function calculateTip () { var cost = document.querySelector('.amount').value; var service = document.querySelector('.service').value; var people = document.querySelector('.numOfPeo').value; var tip = (cost * service) / people; if (cost === "" || service === 0) { alert("Please enter values"); } if (people === "" || people <= 1) { people = 1; } document.getElementById('totalTip').style.display = "block"; document.getElementById('tip').innerHTML = tip; } btn.addEventListener('click', calculateTip);
 <div class="container"> <h1>Tip Calculator</h1> <div class="descr-1"><p>How Much was your bill?</p></div> <div class="input-1 amount"><input type="text" placeholder="Bill Amount in £"></div> <div class=descr-2><p>How was your service?</p></div> <div class="select"> <select class="service"> <option disabled selected value="0">Choose an Option</option> <option value="30">Extraordinary! - 30%</option> <option value="20">Amazing! - 20%</option> <option value="15">Good - 15%</option> <option value="10">Was Ok - 10%</option> <option value="5">Awful! - 5%</option> </select></div> <div class="descr-3">How many people sharing a bill?</div> <div class="people numOfPeo"> <input type="text" placeholder="Number of People"></div> <button id="btn">Calculate!</button> <div class="total"> <div id="totalTip"> <sup>$</sup><span id="tip">0.00</span> <small id="each">each</small> </div> </div>

You just have a small issue with the class, it should be on the inputs and not on the div. I have fixed it here, on my jsfiddle:

 <div class="container">
  <h1>Tip Calculator</h1>
  <div class="descr-1"><p>How Much was your bill?</p></div>
  <div class="input-1"><input type="text" placeholder="Bill Amount in £" class="amount"></div>
  <div class=descr-2><p>How was your service?</p></div>
  <div class="select"> <select class="service">
      <option disabled selected value="0">Choose an Option</option>
      <option value="30">Extraordinary! - 30%</option>
      <option value="20">Amazing! - 20%</option>
      <option value="15">Good - 15%</option>
      <option value="10">Was Ok - 10%</option>
      <option value="5">Awful! - 5%</option>
  </select></div>
  <div class="descr-3">How many people sharing a bill?</div>
  <div class="people"> <input type="text" placeholder="Number of People" class="numOfPeo"></div>
  <button id="btn">Calculate!</button>
  <div class="total">
      <div id="totalTip">
          <sup>$</sup><span id="tip">0.00</span>
          <small id="each">each</small>
        </div>

and you should move the validation before the calculation of the tip:

function calculateTip () {
var cost = document.querySelector('.amount').value;
var service = document.querySelector('.service').value;
var people = document.querySelector('.numOfPeo').value;


if (cost === "" || service === 0) {
    alert("Please enter values");
  }
  if (people === "" || people <= 1) {
    people = 1;
  }
  var tip = cost * service/ people;

  document.getElementById('totalTip').style.display = "block";
  document.getElementById('tip').innerHTML = tip;
}

btn.addEventListener('click', calculateTip);

https://jsfiddle.net/arielbo/qaf6eygc/13/

The first element with the class amount in your HTML is a div , not an input . The input is inside the div . So cost is undefined , since div s don't have a value . The same problem occurs with people , because again the .numOfPeo is on the div , not the input .

You need to target your inputs. Without changing your HTML, you can use a descendant child selector:

var cost = document.querySelector('.amount input').value;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^
var service = document.querySelector('.service').value;
var people = document.querySelector('.numOfPeo input').value;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^

Live Example:

 function calculateTip () { var cost = document.querySelector('.amount input').value; var service = document.querySelector('.service').value; var people = document.querySelector('.numOfPeo input').value; var tip = (cost * service) / people; if (cost === "" || service === 0) { alert("Please enter values"); } if (people === "" || people <= 1) { people = 1; } document.getElementById('totalTip').style.display = "block"; document.getElementById('tip').innerHTML = tip; } btn.addEventListener('click', calculateTip);
 <div class="container"> <h1>Tip Calculator</h1> <div class="descr-1"><p>How Much was your bill?</p></div> <div class="input-1 amount"><input type="text" placeholder="Bill Amount in £"></div> <div class=descr-2><p>How was your service?</p></div> <div class="select"> <select class="service"> <option disabled selected value="0">Choose an Option</option> <option value="30">Extraordinary! - 30%</option> <option value="20">Amazing! - 20%</option> <option value="15">Good - 15%</option> <option value="10">Was Ok - 10%</option> <option value="5">Awful! - 5%</option> </select></div> <div class="descr-3">How many people sharing a bill?</div> <div class="people numOfPeo"> <input type="text" placeholder="Number of People"></div> <button id="btn">Calculate!</button> <div class="total"> <div id="totalTip"> <sup>$</sup><span id="tip">0.00</span> <small id="each">each</small> </div> </div>

...but I'd probably change the HTML instead.


I'd also recommend explicitly converting cost , service , and people to numbers rather than relying on implicit conversion. My answer here outlines your various options for doing that and their tradeoffs.

Also note that you need to divide service by 100 to make it a percentage ("percent" literally "for each hundred"). Otherwise, these tips are going to be massive . ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM