In this tutorial we are going to learn how to create a simple calculator with javascript.
By creating this you will learn.
- HTML:- How to place elements and structure it.
- Css:- Use reusable and minimal code to style the component.
- Javascript:- Handle different types of events and re-usability with functional programming.
We will complete development in three different parts.
- Create the layout.
- Add style code.
- Handle the functionality.
Creating the layout of the calculator.
If you see the above image you will realize that our calculator is composed of two different sections.
First, the calculate area where the input and calculation result are shown.
Second, the button area where the buttons are placed.
So we will create the structure accordingly.
<div id="calculator"> <section id="calc-area"> <span>Calculator</span> <textarea id="view" disabled></textarea> </section> <!-- Button Area --> <section id="buttons-area"> <div class="button-group"> <span class="opr">%</span> <span class="clear">C</span> <span class="delete"><</span> <span class="opr">/</span> </div> <div class="button-group"> <span class="num">7</span> <span class="num">8</span> <span class="num">9</span> <span class="opr">*</span> </div> <div class="button-group"> <span class="num">4</span> <span class="num">5</span> <span class="num">6</span> <span class="opr">-</span> </div> <div class="button-group"> <span class="num">1</span> <span class="num">2</span> <span class="num">3</span> <span class="opr">+</span> </div> <div class="button-group"> <span class="num">0</span> <span class="num">.</span> <span class="calc">=</span> </div> </section> </div>
If you see I have used the section
tags to create two different sections and have placed buttons in separate div
using class button-group
.
Each button has their own separate class which will help us to identify which type of button is clicked or pressed.
As our layout is ready now, let us style it.
Styling the calculator layout.
I have kept the style extremely simple and used flexbox to align the elements.
Each last button has different color, if you want you can use the classes to differentiate the numbers and operator buttons.
The equal to button has it own different color. Again feel free to explore things with your perspective.
#calculator { width: 300px; margin: 0 auto; padding: 10px; background: #eee; box-shadow: 0 0 3px; } /* Calculate Area Style */ #calc-area { display: flex; justify-content: center; align-items: center; flex-wrap: wrap; } #calc-area > span, #calc-area > textarea { display: inline-flex; flex: 100%; justify-content: center; margin-bottom: 20px; } #calc-area > textarea { border: 2px solid #eee; background: beige; box-shadow: 0 0 3px; min-height: 60px; resize: none; font-size: 1.8em; letter-spacing: 2.5px; } #calc-area > span { font-size: 2em; } /* Button area style */ #button-area { padding: 10px 0; } .button-group { display: flex; align-items: center; justify-content: center; } .button-group > span { display: inline-flex; flex: 1 1; padding: 15px 10px; justify-content: center; align-items: center; background: #ff9800; margin: 4px; border-radius: 50%; color: #fff; font-size: 2em; box-shadow: 0 0 3px #968585; transition: all 0.2s ease; opacity: 0.8; cursor: pointer; } .button-group > span.calc { flex: 2.5; border-radius: 7px; background: #f44336; } .button-group > span:hover { opacity: 1; }
We are ready with body of the calculator app, now it is time to give it life by adding user interaction with javascript.
Handling calculator functionality with javascript.
I think we can break down the functionalities in 5 different parts.
- Add numbers
- Add operators
- Delete inputs
- Clear all the inputs
- Calculate
So let us create separate functions for all of these parts, because this way we will be able to use them again.
All the inputs will be added to the calculate area so it better to fetch and store it in a variable so that we can reuse it wherever possible.
//Where inputs are displayed const calcArea = document.querySelector("textarea");
Adding numbers in calculator
The only thing we have to take care of while adding a number in the calculator is that dot .
cannot be added at the first place.
//Add input const addNums = text => { let { value } = calcArea; //Rules to add dot const ruleA = value.length === 0 && text === "."; //Add only if both rules apply if (!ruleA) { calcArea.value += text; } };
Adding operators in calculator
While adding operators we will have to make sure we don’t add multiple operators one after another, so check if last character is operator then replace it else add it.
//operators const oprList = ["+", "-", "*", "/", "%", "."]; //Add operators const addOpr = text => { const { value } = calcArea; const lastCharacter = value[value.length - 1]; //Don't add repeated operators and initially without numbers if (lastCharacter !== text) { if (value.length > 0) { calcArea.value += text; } } //If last character is operator then replace it with new operator if (oprList.includes(lastCharacter)) { calcArea.value = value.substr(0, value.length - 1) + text; } };
Delete inputs in calculator
To remove the inputs we just remove the last character from the input string.
//Delete inputs on backspace const del = () => { const { value } = calcArea; if (value.length > 0) { calcArea.value = value.substr(0, value.length - 1); } };
Clear the calculator
To clear the calculator just add empty string.
//Clear whole area const clear = () => { calcArea.value = ""; };
Calculate the input of the calculator
To perform the calculation we will use the eval function which basically evaluates any given string.
If the input string is not calculated properly and throws an error then alert error else show the result.
//Perform calculation const calc = () => { const { value } = calcArea; const result = eval(value); if (!isNaN(result)) { calcArea.value = result; } else { alert("Wrong expression, Please check your input"); } };
Now we have to call these functions appropriately based on which button is clicked on the calculator.
For this we will listen to the events on all the buttons and differentiate them based on the classes they have.
//Add event listeners to the button document.querySelectorAll(".button-group > span").forEach(e => { e.addEventListener("click", f => { const { classList, innerText } = f.target; if (classList.contains("num")) { //Number buttons clicked including . addNums(innerText); } else if (classList.contains("opr")) { //Opertor buttons clicked addOpr(innerText); } else if (classList.contains("calc")) { //Equal button clicked calc(); } else if (classList.contains("delete")) { //Backspace button clicked del(); } else if (classList.contains("clear")) { //Clear button clicked clear(); } }); });
This calculator can also be made accessible through keyboard by listening to keypress events and then calling the functions accordingly.
//Add key events document.addEventListener("keydown", e => { switch (e.key) { case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case "0": case ".": addNums(e.key); break; case "/": case "*": case "+": case "-": case "%": addOpr(e.key); break; case "Enter": calc(); break; case "Backspace": del(); break; case "c": clear(); default: } });