How I Built the Frontend Mentor Tip Calculator Application

How I Built the Frontend Mentor Tip Calculator Application

One of the best platforms to practice your Frontend skills is Frontend Mentor. It is a website/platform that provides various front-end development challenges, both free and premium, for developers to practice and improve their skills. One of my favourite aspects of Frontend mentor is that it provides web and mobile designs.

In the quest to improve and practice my skills, I hopped on Frontend Mentor to look for a project that would allow me to practice my HTML, CSS, and JavaScript skills. The Tip Calculator Challenge was my perfect project.

N.B: For this particular project, I created the web version of the application.

Setting up my project for development

After successfully downloading the start-up files, I reviewed the project design in detail to create a plan for the project, that is the required HTML, CSS and JavaScript files.

HTML Section

The HTML body consists of:

Input Sections:

  • Form input to enter the total bill in USD (United States Dollars)
<form class="numbers">
      <label for="bill">Bill</label>
      <br>
      <input type="number" name="bill" id="total-bill" placeholder="$0" min="0" oninput="this.value = 
       Math.abs(this.value)">
 </form>
  • 5 buttons with the various tip percentages i.e. 5%, 10%, 15%, 25% and 50% and a custom input form to enter a custom tip percentage
<div id="tip-percent">
<p id="select-tip">Select Tip %</p>
<div>
       <div class="row" >
             <div class="col-md-4">
                   <button class="tips" value="5" type="button" onclick="getTip(this)">5%</button>
             </div>
             <div class="col-md-4">
                    <button class="tips" value="10" onclick="getTip(this)">10%</button>
             </div>
             <div class="col-md-4">
                    <button class="tips" value="15" onclick="getTip(this)">15%</button>
             </div>
       </div>
       <div class="row">
             <div class="col-md-4">
                   <button class="tips" value="25" onclick="getTip(this)">25%</button>
              </div>
              <div class="col-md-4">
                     <button class="tips" value="50" onclick="getTip(this)">50%</button>
               </div>
               <div class="col-md-4">
                     <input id="custom-input" class="tips" name="custom-input" type="text" 
                         placeholder="Custom" onclick="getTip(this)">
                </div>
        </div>
</div>
</div>
  • Form input to enter the number of people at the party.
  <form class="numbers">
             <label for="number-of-people">Number of People</label>
             <input id="num-of-people" name="number-of-people" min="0" required=True type="number" 
               oninput="this.value = Math.abs(this.value)">
 </form>

Output Sections:

  • Tip Amount payable per person,
  • total amount payable per person and the
  • reset button to reset all the form values to zero
  <div class="col-md-6" id="second-col">
           <p><strong class="str">Tip Amount</strong><br>/person<span id="amount-per- 
                         person">$0.00</span></p>
           <p><strong class="str">Total</strong><br>/person<span id="total-per- 
                    person">$0.00</span</p>
            <button type="button" class="btn btn-block" id="reset-button" 
                    onclick="resetApp()">RESET</button>
  </div>

JavaScript - To create the interactivity of the application

I created the variables that I required from the HTML file which are:

const totalBill=document.getElementById("total-bill");
const tipPercent=document.querySelectorAll('.tips');
const numOfPeople=document.getElementById("num-of-people");
let amountPerPerson=document.getElementById("amount-per-person");
let totalPerPerson=document.getElementById("total-per-person")
let reset=document.getElementById("reset-button")

let bill=parseFloat(totalBill.value);
let tip=parseInt(tipPercent.value);
let number=parseInt(numOfPeople.value);

Explanation

The values:

  • the totalBill variable represents the input value of the total bill
  • the tipPercent variable represents the buttons and input form with the class of tips
  • the numOfPeople variable represents the input value of the total number of people who will be paying the bill
  • the amountPerPerson variable will allow us to display the output of the total tip amount due per person
  • the totalPerPerson variable will allow us to display the output of the total bill amount due per person
  • the reset variable represents the button that resets all input and output values to 0

Extracting the above values from the HTML body allows us to manipulate these values. This is known as DOM (Document Object Manipulation). You can find attached resources on Document Object Manipulation below.

I created a function named getTotalCost that calculates the total amount payable per person and the total tip payable per person.

function getTotalCost(){

    total=(((1+tip)*bill)/number).toFixed(2)
    if (isNaN(total)=== true){
        return "$0.00"
    }
    else{
        totalPerPerson.innerHTML= "$" + total
    }

    amountPerPerson.innerHTML= "$" + ((tip * bill)/number).toFixed(2)
}

The function above calculates the total bill due per person and sets it to 2 decimal places from the .toFixed(2) method. I used an if statement to check if the input value for the total amount is a number. If the input value is not a number, the function will return a value of 0. If it is a number, I made use of .innerHTML to display the total amount due per person and the tip amount due per person.

I made use of eventlisteners to “listen” when the total bill amount is changed and when the total number of people at the party is changed.

totalBill.addEventListener("change", function(event){

    bill=parseFloat(event.target.value)
    console.log(bill)

    getTotalCost()
})
numOfPeople.addEventListener("change", function(event){
    event.preventDefault()

    number=parseInt(event.target.value)
    console.log(number)

    getTotalCost()
})

I created a function getTip() that gets the value of the tip value/percentage i.e. 5%, 10% or a custom tip value.

function getTip(e){

    tip=parseInt(e.value)
    tip=tip/100
    console.log(tip)

    getTotalCost()
}

The getTip() function is then called in the HTML file where the tip amount buttons and the custom tip input form are. When any of the buttons is clicked or a tip percent is entered into the form, the function getTip() gets called and the tip amount is divided by 100 and the function getTotalCost() is called.

See example code below where the getTip() function has been called. This is done for all the tips buttons and the custom tip percent input form:

<div class="col-md-4">
       <button class="tips" value="50" onclick="getTip(this)">50%</button>
</div>
<div class="col-md-4">
       <input id="custom-input" class="tips" name="custom-input" type="text" placeholder="Custom" 
         onclick="getTip(this)">
</div>

I created a function named resetApp() that resets all the input and output values to 0 when it is clicked. This function is called in the RESET button.

function resetApp(){
    document.getElementById("total-bill").value=0;
    document.querySelectorAll('.tips').value=0;
    document.getElementById("num-of-people").value=0;       
    totalPerPerson.innerHTML="$0.00";
    amountPerPerson.innerHTML="$0.00"
}
<button type="button" class="btn btn-block" id="reset-button" onclick="resetApp()">RESET</button>

Conclusion

I had so much fun and learnt some new concepts when creating this project. I hope you also get to do it and submit it to Frontend Mentor for review by other developers.

Here is the link to the Frontend Mentor Challenge: [Tip Calculator Challenge on Frontend Mentor (frontendmentor.io/challenges/tip-calculator..)

If you find this tutorial helpful in any way, kindly leave a comment below. I would love to hear from you.

You can also look at some of the DOM resources below if you are looking to improve your understanding.

Some Document Object Manipulation (DOM) resources: