Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found

Submitted

Tip Calculator App with Vanilla JavaScript

#accessibility#sass/scss
kxnzx 870

@kxnzx

Desktop design screenshot for the Tip calculator app coding challenge

This is a solution for...

  • HTML
  • CSS
  • JS
2junior
View challenge

Design comparison


SolutionDesign

Solution retrospective


Hello Frontend Mentor Gang!

It took me some time to finish this challenge. The calculator works, however the form does not function the way I want it to. Here are some of the issues:

  • The error message "Can't be zero" is displayed by default.
  • After the reset button has been clicked the value "0" stays set in place after typing in a new value.

My Questions:

  • How can I make the error message and the red focus on the input visible only after the tip percentage button or custom input have been filled in?
  • How do I make the value "0" dissapear when a new value is typed in after the reset button has been clicked?

Feel free to leave a comment if you've noticed some other issues. Much Appreciated!

Community feedback

P

@joshdail

Posted

I would suggest having the code for the error message in a separate function outside of your calculateAndDisplayValues function. That way calculateAndDisplayValues is focused just on the math, and you have another function focused just on the error message.

So you could pull your error handling code outside of calculateAndDisplayValues and put it inside an event listener, something like this:

document.getElementById("people").addEventListener("click",() => {
let people = document.getElementById("people").value;
  // Convert the number of people to a number:
  /* If you want to treat the value as a number, 
  you can use the parseInt() or parseFloat() functions to convert it to a number. */
  people = parseInt(people, 10);
  // Check if the number of people is a valid number:
  if (isNaN(people) || people <= 0) {
    // Display an error message if the value is not valid:
    document.getElementById("error").innerHTML = "Can't be zero";
document.getElementById("people").classList.add("invalid");
    return;
  } else  {
    document.getElementById("error").innerHTML = "";
document.getElementById("people").classList.remove("invalid");
  } 
})

Then in calculateAndDisplayValues, you would still need to make sure that there is a valid input for number of people so you don't get NaN or divide by zero errors. You could have a line of code that checks to make sure there is a valid value before the function does the math, like this:

if (people <= 0 || isNaN(people) {
return;
}
  let tipAmountPerPerson = (billAmount * tipPercentage) / 100 / people;

Since the error message is taken care of by a separate function, you don't have to worry about it here in calculateAndDisplayValues. Here you're just concerned with making sure the math part of it works.

I hope this is helpful.

Marked as helpful

0

kxnzx 870

@kxnzx

Posted

@joshdail Yes great! It is working now. Thank you so much! I still have one little issue though....the outline stays red after typing in a number greater > than 0, or in other words the classlist invalid is not being removed.

document.getElementById("people").addEventListener("click", () => {
  let people = document.getElementById("people").value;
  // Convert the number of people to a number:
  /* If you want to treat the value as a number, 
    you can use the parseInt() or parseFloat() functions to convert it to a number. */
  people = parseInt(people, 10);
  // Check if the number of people is a valid number:
  if (isNaN(people) || people <= 0) {
    // Display an error message if the value is not valid:
    document.getElementById("error").innerHTML = "Can't be zero";
    // Make the outline red if the value is not valid:
    document.getElementById("people").classList.add("invalid");
    return;
  } else {
    document.getElementById("error").innerHTML = "";
    document.getElementById("people").classList.remove("invalid");
    return;
  }
});
0
P

@joshdail

Posted

@kxnzx Ok so I looked at your solution code and I think I figured it out. I had a few errors in my code from my earlier comment. I put "click" instead of "input" for the event listener, and I forgot about checking for an empty string. Here's a version of your event listener with the bug fixes:

document.getElementById("people").addEventListener("input", () => {
  let people = document.getElementById("people").value

  if (people === "") {
// If the input is empty, remove the error message and return out of the function
    removeError()
    return
  }
  // Convert the number of people to a number:
  /* If you want to treat the value as a number, 
    you can use the parseInt() or parseFloat() functions to convert it to a number. */
  people = Number(people)
  // Check if the number of people is a valid number:
  if (isNaN(people) || people <= 0) {
    // Display an error message if the value is not valid:
    document.getElementById("error").innerHTML = "Can't be zero"
    // Make the outline red if the value is not valid:
    document.getElementById("people").classList.add("invalid")
    return
  } else {
// If there is a valid number, remove the error message
    removeError()
    return
  }
})

function removeError() {
  document.getElementById("error").innerHTML = ""
  document.getElementById("people").classList.remove("invalid")
}

In the code above I made a separate function that gets called by the event handler to remove the error messages, either if the input value is empty or if there is a valid number. I find breaking the code into smaller functions can help a lot either with finding where errors are coming from, or if you need to update or change the code later.

Marked as helpful

0
kxnzx 870

@kxnzx

Posted

@joshdail Hello Joshua, yes now it functions correctly :) I have also incorporated the removeError function inside the reset button, otherwise the error would stay active. Thank you so much for your help! I appreciated! ;)

0
P

@joshdail

Posted

Nice job!

Looking at your solution, your form is not far off from working the way you want, just needs a few small tweaks to the code.

For the error message: What you could do is have the HTML start off as an empty tag, with no text, like this:

<small id="error" class="error"></small>

and then have the event listener in your JS script add the error message to the element's innerText only if the error condition is met. Same with the red outline, you can have a CSS class, for example like this:

.input.invalid {
  border: none;
  outline: 2px solid hsl(9, 31%, 58%);
}

And in your event listener, when you add in the error text, you can use <element>.classList.add (or remove) to add/remove the red background, like this:

peopleInput.addEventListener("input", e => {

  const inputValue = peopleInput.value
  const peopleCount = Number(inputValue)

  if (peopleCount === 0 && peopleInput.value !== "") {
    peopleInput.classList.add(classInvalid)
  peopleErrorAlert.innerText = "Can't be zero"
    return
  }
/* If no error make sure error message is not displayed */
  peopleInput.classList.remove(classInvalid)
  peopleErrorAlert.innerText = ""
})

For getting rid of "0", just set the value of the inputs to "" instead of "0" when the reset button is clicked. If you want it to show 0 as a placeholder, you could set the placeholder to 0 instead of the value, then the 0 will disappear as soon as a value is entered.

Marked as helpful

0

kxnzx 870

@kxnzx

Posted

@joshdail Thank you for your feedback!

I have changed the reset value to an empty "string" like you stated. Now it works how it should! I have also added the red outline class inside my css:

// Add class in JavaScript
.people.invalid {
  border: none;
  outline: 2px solid hsl(9, 31%, 58%);
}

However now I am stuck. Where exactly can I incorporate the addEventListner in my code? The code that you wrote is different than what I have. How can I make it work with the code that I have?

// Check if the number of people is a valid number:
  if (isNaN(people) || people <= 0) {
    // Display an error message if the value is not valid:
    document.getElementById("error").innerHTML = "Can't be zero";
    return;
  } else if (isNaN(people) || people >= 0) {
    document.getElementById("error").innerHTML = "";
  } else {
    removeError("error");
  }
0

Please log in to post a comment

Log in with GitHub
Discord logo

Join our Discord community

Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!

Join our Discord