Simple Javascript Tip Calculator





Hey guys in this post, we will create a simple Javascript Tip Calculator. Follow this tutorial, we will create the project step by step. The project is already live on the internet, you can click here to see the final version of the application.

Topics covered


This application involves the following topics –

  • DOM Manipulation
  • Control Structures
  • Array.forEach()
  • JavaScript CSS Manipulation
  • eventListeners
  • setTimeout()
  • Immediately Invoked Function Expressions

Complete source code


The below image shows you the project structure –

Screenshot-2021-06-04-at-7-42-32-PM

Add styles to the application


Create a main.css file and add the following content –

.max-height {
  min-height: 100vh;
}
:root {
  --lightBlue: #86bbd8;
  --darkBlue: #336699;
  --mainWhite: #f5f5f5;
  --mainDark: #333333;
}

body {
  background: var(--lightBlue);
}
.card-title {
  background: var(--darkBlue);
  border-top-right-radius: 0.5rem;
  border-top-left-radius: 0.5rem;
  color: var(--mainWhite);
}
.card {
  border: none !important;
  border-radius: 0.5rem !important;
}

.bill-icon,
.user-icon {
  background: var(--darkBlue) !important;
  color: var(--mainWhite);
}
.submitBtn {
  background: var(--darkBlue);
  font-size: 1.2rem;
  color: var(--mainWhite);
}

.submitBtn:hover {
  background: var(--lightBlue);
  color: var(--mainDark);
}
/* feedback */
.feedback {
  display: none;
}
.loader {
  display: none;
}

.results {
  display: none;
}

.showItem {
  display: block;
}

Add scripts to the application


Create an app.js file and add the following content –

(function(){
  
//Set up a service array
const services = [{
  value: 1,
  title: "great - 20%"
},{
  value: 2,
  title: "good - 10%"
},{
  value: 3,
  title: "bad - 2%"
}]


  
  const validateInput = function(billAmount, numUsers, selectedService){
    
   let isFeedback = false;
   const feedback = document.querySelector('.feedback');
    feedback.innerHTML = '';

     if  (billAmount === "" || billAmount <="0"){
        feedback.classList.add('showItem', 'alert-danger');
        feedback.innerHTML += `<p>Bill amount cannot be blank</p>`
        isFeedback = true;
    }
    
    if (numUsers <= "0"){
      feedback.classList.add('showItem', 'alert-danger');
      feedback.innerHTML += `<p>Number of users must be greater than zero</p>`;
       isFeedback = true;
    } 
    
   if (selectedService === "0"){
     feedback.classList.add('showItem', 'alert-danger');
     feedback.innerHTML += `<p>You must select a Service</p>`
      isFeedback = true;
   }
    
    setTimeout(function(){
      feedback.classList.remove('showItem', 'alert-danger');
    }, 10000);
    
    return isFeedback;
      
  }; // end validateInput
  
  const calculateTip = function(billAmount, numUsers, selectedService) {
   
    let percentTip = '';
    if (selectedService === "1"){
      percentTip = 0.2;
    } else if (selectedService === "2"){
      percentTip = 0.1;
    } else {
      percentTip = 0.02;
    }
    
    const tipAmount = Number(billAmount)*percentTip;
    const totalAmount = Number(billAmount) + Number(tipAmount);
    const eachPerson = Number(totalAmount) / Number(numUsers);
    
    return [tipAmount, totalAmount, eachPerson];
   
    
  };
  
 //FORM SETUP - ADD SERVICES
services.forEach(function(service){
  //create the option element
  const option = document.createElement('option');
  option.textContent = service.title;
  option.value = service.value;
  //select the select element from the DOM
  const select = document.querySelector('#input-service');
  select.appendChild(option);
})
  
 //FORM SETUP - ADD EVENT LISTENER AND FUNCTION CALLS
  const inputForm = document.querySelector('form');
  inputForm.addEventListener('submit', function(e){
    
  e.preventDefault();
   
  //grab elements from the DOM
  const inputBill = document.querySelector('#input-bill');
  const inputUsers = document.querySelector('#input-users');
  const serviceValue = document.querySelector('#input-service');
 
   //get values from DOM elements
  let billAmount = inputBill.value;
  let  numUsers = inputUsers.value;
  let selectedService = serviceValue.value;
    
  //get feedback if info is not validated  
  const isFeedback = validateInput(billAmount, numUsers, selectedService);
    
    
    
   //calculated tip if info was validated
    if (!isFeedback){
        const loader = document.querySelector('.loader');
        const resultsDOM = document.querySelector('.results');
        const tipResultsDOM = document.querySelector('#tip-amount');
        const totalAmountDOM = document.querySelector('#total-amount');
        const eachPersonDOM = document.querySelector('#person-amount');
      
       //calculate results
        const results = calculateTip(billAmount, numUsers, selectedService);
       //show loader  
       loader.classList.add('showItem');
       // show results after 2 seconds
       setTimeout(function(){
        loader.classList.remove('showItem');
        tipResultsDOM.textContent= `${results[0].toFixed(2)}`
        totalAmountDOM.textContent= `${results[1].toFixed(2)}`
        eachPersonDOM.textContent= `${results[2].toFixed(2)}`
        resultsDOM.classList.add('showItem');
      },2000)
      
      //clear values from DOM elements after 5 seconds
      setTimeout(function(){
        inputBill.value = '';
        inputUsers.value = '';
        serviceValue.value = 0;
        resultsDOM.classList.remove('showItem');
      }, 10000)


    } //end isFeedback statement
  
  }); //end eventListener for form
  
  
})();

Add HTML to the application


Create an index.html file and add the following content –

 <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- bootstrap css -->
    <link rel="stylesheet" href="./css/bootstrap.min.css">
    <!-- main css -->
    <link rel="stylesheet" href="./css/main.css">
    <!-- google fonts -->
    <link href="https://fonts.googleapis.com/css?family=Courgette" rel="stylesheet">

    <!-- font awesome -->
    <link rel="stylesheet" href="./css/all.css">
    <title>Background Image Project</title>
    <style>
    </style>
</head>

<body>

    <div class="container">
        <div class="row max-height align-items-center">
            <div class="col-10 mx-auto col-md-8">
                <div class="card">
                    <div class="card-title p-2">
                        <h3 class="text-uppercase text-center">tip calculator</h3>
                    </div>
                    <div class="card-body">
                        <!-- end of  card title -->
                        <div class="feedback text-center alert  text-capitalize p-1">
                            your feedback
                        </div>
                        <form id='tip-form'>
                            <!-- single input -->
                            <div class="my-4">
                                <h5 class="text-capitalize mb-2">how much was your bill ?</h5>
                                <div class="input-group">
                                    <div class="input-group-prepend">
                                        <span class="input-group-text bill-icon"><i
                                                class="fas fa-dollar-sign fa-fw"></i></span>
                                    </div>
                                    <input type="number" class="form-control form-control-lg" id="input-bill"
                                        step=".01">
                                </div>
                            </div>
                            <!-- end of single input -->
                            <!-- single input -->
                            <div class="my-4">
                                <h5 class="text-capitalize mb-2">how many people sharing the bill ?</h5>
                                <div class="input-group">
                                    <div class="input-group-prepend">
                                        <span class="input-group-text user-icon"><i
                                                class="fas fa-user fa-fw"></i></span>
                                    </div>
                                    <input type="number" class="form-control form-control-lg" id="input-users">
                                </div>
                            </div>
                            <!-- end of single input -->
                            <!-- single input -->
                            <div class="my-4">

                                <h5 class="text-capitalize mb-2">how was your service</h5>
                                <div class="form-group">

                                    <select class="form-control form-control-lg text-capitalize" id="input-service">
                                        <option selected value="0">Choose...</option>

                                    </select>
                                </div>

                            </div>
                            <!-- end of single input -->

                            <input type="submit" class="d-block mx-auto text-capitalize btn submitBtn w-75"
                                value="calculate">
                        </form>
                        <div class="loader text-center">
                            <img src="img/Facebook-1s-200px.gif" alt="">
                        </div>
                        <!-- results -->
                        <div class="results text-center my-3">
                            <h3 class="text-capitalize">tip amount<span> $ </span><span id="tip-amount"></span></h3>
                            <h3 class="text-capitalize">total amount<span> $ </span><span id="total-amount"></span></h3>
                            <h3 class="text-capitalize">each person owes<span> $ </span><span id="person-amount"></span>
                            </h3>
                        </div>
                    </div>
                    <!--  -->
                </div>
            </div>
        </div>
    </div>
    <!-- jquery -->
    <script src="./js/jquery-3.3.1.min.js"></script>
    <!-- bootstrap js -->
    <script src="./js/bootstrap.bundle.min.js"></script>
    <!-- script js -->
    <script src="./js/app.js"></script>
</body>

</html>

Screenshots


Screenshot-2021-06-05-at-10-14-18-AM

Screenshot-2021-06-05-at-10-15-02-AM

Note: Make sure to download the bootstrap.css, bootstrap.js, and jquery.js library from the internet add them to the respective folders. You can download the images from the Github repository.

Download the complete source code from github repository

Original source https://jsbeginners.com/tip-form-javascript-project/




Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

Leave a Reply