DEV Community

Cover image for How To Create a Javascript Calculator
Snevy1
Snevy1

Posted on • Edited on

How To Create a Javascript Calculator

Javascript calculator image

One of the basic and best ways of learning Javascript is by building a simple calculator. In this tutorial, you will learn how to build a Javascript calculator.

Prerequisites

  • HTML
  • CSS
  • Basic DOM manipulation with javascript.

Abilities your project should have:

Try to implement these conditions on your own, then come back to follow along

1. Your calculator is going to have html file. This is the skeleton of the project.
  • Set up buttons for numbers(0-9), operators(x, /, -, +), equals(=), a clear and a delete button.

  • Set up two display inputs. For previous values and current values.

2. It must have a CSS file to style up the buttons and the whole project so it looks nice.
3. It must have a JAVASCRIPT file to add interactivity to the calculator.
4. On Javascript, you should have the following conditions and functions in your file:
  • Your file is going to have functions for basic math operations i.e add, subtract, divide, and multiply

  • An operation will consist of the first number, the operator, and a second number ie 6(first number) x (operator) 7(second number);

  • Create three variables for each of the parts above

  • Create a function that takes in the first number, operator and second number then calls each of the basic math operations. You can call it operatorFunc

  • Create a function that adds the clicked button’s value and the result after computation on the display in HTML.

  • You should find a way to store the numbers input from the html into the first and second number variables then call operateFunc() utilizing the operator that the user selected.

  • Ensure to display the result of the calculation after the user clicks equals.

5. This is the hardest part of the project, you need to find a way to store values from the DOM and then call the operatorFunc with them.

These are the most basic conditions that your project should meet. Try to implement them on your own and if you feel lost come back we work through it together.

HTML

Now it is the time to get into it!
Let’s start by setting up our html file. Call it index.html
Link it to both CSS (in the header) and JavaScript files (in the body below the footer).
This is the code for that:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Javascript calculator Project</title>
    <link rel="stylesheet" href="index.css" />
  </head>
<body>
  <script src="index.js"></script>
</body>
</html>



Enter fullscreen mode Exit fullscreen mode

Set up the body

a. Add buttons: numbers(0-9), operators(X, /, -, +), equals(=), clear(AC) and delete button(Delete).

b. Make sure to add ids and classes appropriately as they will be used in css to style up.

c. Add two display inputs.

N/B. You are at liberty to use buttons, in our code below we used input elements with the type of button

<body>
    <h1>Javascript Calculator</h1>
    <div class="calc-container">
      <div class="display_container">
        <div id="displayPrev" class="display"></div>
        <div id="displayCurr" class="display">0</div>
      </div>
      <div class="clear-and-delete-container">
        <input type="button" value="Delete" id="delete" class="remove-btn" />
        <input type="button" value="AC" id="AC" class="remove-btn" />
      </div>

      <div class="btn-container">
        <input type="button" value="7" class="btn" id="7" />
        <input type="button" value="8" class="btn" id="8" />
        <input type="button" value="9" class="btn" id="9" />
        <input type="button" value="÷" class="operant divide" id="/" />
        <input type="button" value="4" class="btn" id="4" />
        <input type="button" value="5" class="btn" id="5" />
        <input type="button" value="6" class="btn" id="6" />
        <input type="button" value="x" class="operant multiply" id="x" />
        <input type="button" value="1" class="btn" id="1" />
        <input type="button" value="2" class="btn" id="2" />
        <input type="button" value="3" class="btn" id="3" />
        <input type="button" value="-" class="operant subtraction" id="-" />
        <input type="button" value="." class="btn period" id="period" />
        <input type="button" value="0" class="btn" id="1" />
        <input type="button" value="=" class="equals" id="equals" />
        <!-- operants -->

        <input type="button" value="+" class="operant add" id="+" />
      </div>

      <div class="operants"></div>
    </div>

    <script src="index.js"></script>
  </body>
Enter fullscreen mode Exit fullscreen mode

Our project now looks like this:

html-image

CSS

It is time to style the HTML. You may want to make sure operator buttons have different colors. Also, make sure to use layout styling, that is, either implement a grid or a flexbox layout. This will make sure that the buttons are arranged well and all fit in the space available. In our code below, we used both.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  overflow-x: hidden;
}

body {
  background: #f0ffff;
  display: grid;
  justify-content: center;
  align-content: center;
  margin: 0 auto;
  overflow-x: hidden;
}

.calc-container {
  width: 350px;
  height: 485px;
  margin: 2rem auto;
  background: #aaaaaa;
  padding: 0.5rem;
  border: transparent;
  border-radius: 15px;
}
.display_container {
  display: grid;
  background-color: #f0ffff;
  border: transparent;
  border-radius: 15px;

  margin: 0.2rem 0;
}
.display {
  text-align: right;
  padding: 0.5rem;
  border: 0;
  color: black;
  outline: none;
  width: 100%;
  height: 40px;
  border-style: none;
  font-size: 30px;
}
.clear-and-delete-container {
  display: flex;
}
.clear-and-delete-container input {
  width: 100%;
  border: 1px solid black;
  border-radius: 10px;
}
.btn-container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: 0.2rem;
}

.btn,
.operant {
  width: 80px;
  margin: 0.1rem;
  height: 80px;
  border: 1px solid black;
  border-radius: 10px;
  background: #ffff;
  z-index: 0;
  transition: background-color 0.25s ease-in 0.09s;
}

.remove-btn:nth-child(2) {
  height: 45px;
  background: #9999ee;
}

.remove-btn:nth-child(1) {
  background: red;
}

.btn:hover {
  background-color: transparent;
  box-shadow: 0px 4px 5px rgba(0, 0, 0, 0.5);
}

.remove-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  color: black;
}

.equals {
  width: 80px;
  margin: 0.1rem;
  height: 80px;
  border: 1px solid black;
  border-radius: 10px;
  background: #49ca3e;
}

.equals:hover {
  background: #ffff;
}
.period {
  font-size: larger;
}

.divide {
  background: #b2b2d1;
}

.multiply {
  background: #00b1c5;
}
.subtraction {
  background: orange;
}
.add {
  background: #e15a46;
}

.operant:hover {
  background: #ffff;
}

Enter fullscreen mode Exit fullscreen mode

The above code may look a lot but actually it is not. Take your time to go through and understand what it is styling.Our project now looks nice as the image below:

Css-image

JAVASCRIPT

Now we come to the most important part. The logic part of the project.

To start, we will revisit the steps provided earlier.
It is good practice to put all initialized variables at the start of a javascript file.

The code below illustrates most of the variables we will need.

a. First, we initialize the first number and the second number to have a value of 0;
Then we initialize the operator to be empty so that when a user clicks on any of the operator buttons the value is updated and stored in this variable.

This is the same with the result and previousComput variables i.e. if a user clicks equals, we run the calculation, then the result is stored in the result variable and also in previousComput variable if they choose to continue with the operation.

let firstNumber = 0;
let secondNumber = 0;
let operator = "";
let previousComput = "";
let result = 0;


Enter fullscreen mode Exit fullscreen mode

b. Fetch data from the DOM and store them in variables. Here we use querySelector and querySelectorAll to select elements. Below are all the variables that we may need.

const calcValues = document.querySelectorAll(".btn");
let displayPrev = document.querySelector("#displayPrev");
let displayCurr = document.querySelector("#displayCurr");
const equals = document.querySelector(".equals");
const operants = document.querySelectorAll(".operant");
const clear = document.querySelector("#AC");
const deleteEl = document.querySelector("#delete");


Enter fullscreen mode Exit fullscreen mode

c. Set up functions to listen to DOM events.

The code below listens to click events on operants(X,/, -,+) buttons and responds accordingly i.e updates the display value, stores the clicked operant’s value to be used in the computation and so much more! Please take note of the if…else statements.


operants.forEach((operant) => {
  operant.addEventListener("click", () => {
    if (displayPrev.innerHTML == "") {
      firstNumber = displayCurr.innerHTML;
      displayPrev.innerHTML = `${displayCurr.innerHTML}  ${operant.value} `;
      displayCurr.innerHTML = "";
      operator = operant.value;
    } else {
      previousComput = concatFunc();
      displayPrev.innerHTML = previousComput + " " + operant.value + " ";
      operator = operant.value;
      firstNumber = previousComput;
      displayCurr.innerHTML = "";
    }
  });
});



Enter fullscreen mode Exit fullscreen mode

d. Next, set up a function that listens to click events of number buttons(0-9).

Below is such a function. It takes clicked values and stores them as either firstNumber or secondNumber. Note that a secondNumber is only updated after the firstNumber has been updated and the user has clicked an operant.
It also displays the values in the displayCurr element simply because this is the current operation that is taking place. Take note of the handleClick function. It is a callback function(…it has been passed as an argument inside another function)

const handleClick = (e) => {
  displayCurr.innerHTML === "0"
    ? (displayCurr.innerHTML = e.target.value)
    : (displayCurr.innerHTML += e.target.value);
};
calcValues.forEach((button) => {
  button.addEventListener("click", handleClick);
});

Enter fullscreen mode Exit fullscreen mode

It is time we set up the basic math operation functions. Add, subtract etc.
We will invoke these functions in the operateFunc later. These functions will only take two parameters, the firsNumber and the secondNumber then will do the operation depending on the operator that was chosen. The operator will be provided by operateFunc();
Please note:

  • The plus before a variable converts it to a number from a string
  • Also we want to prevent returning answers that have too long decimals.To do that we use toFixed();
//let result = 0;

const multiply = (firstNumber, secondNumber) => {
   //The plus before a number converts it to a number from being a string
   //Also We want to prevent returning answers that have too long decimals so to
  //Do that we use toFixed();
  result = +firstNumber * +secondNumber;
  if (!Number.isInteger(result)) {
    return result.toFixed(2);
  }
  return result;
};

const divide = (firstNumber, secondNumber) => {
  if (+secondNumber === 0) {
    alert("You can't divide a number by zero!");

    location.reload();
  } else {
    result = +firstNumber / +secondNumber;
    if (!Number.isInteger(result)) {
      return result.toFixed(2);
    }
    return result;
  }
};
const add = (firstNumber, secondNumber) => {
  result = +firstNumber + +secondNumber;
  if (!Number.isInteger(result)) {
    return result.toFixed(2);
  }
  return result;
};

const subtract = (firstNumber, secondNumber) => {
  result = +firstNumber - +secondNumber;

  if (!Number.isInteger(result)) {
    return result.toFixed(2);
  }
  return result;
};

Enter fullscreen mode Exit fullscreen mode

We want to make sure that a user is able to delete a number or clear the screen. The code below solves this issue.

Please refer to array methods to understand why we used .slice();

clear.addEventListener("click", () => {
  displayPrev.innerHTML = "";
  displayCurr.innerHTML = "";
});

deleteEl.addEventListener("click", () => {
  if (displayCurr.innerHTML !== "") {
    displayCurr.innerHTML = displayCurr.innerHTML.slice(0, -1);
  } else {
    displayPrev.innerHTML = displayPrev.innerHTML.slice(0, -1);
    displayCurr.innerHTML += displayCurr.innerHTML;
  }

});



Enter fullscreen mode Exit fullscreen mode

e. It is time to display results and make the calculator work!

Write a function that listens to a click event on the equals button and does stuff with it.

The code below does the following things:

  • Listens to click event and triggers the concatFunc()
  • The concatFunc is the heart of the project.It triggers the operateFunc which in turn invokes/calls the basic math operator functions and displays the result.

  • We use the if…else statements to add conditions as to when a certain function is invoked and also to issue warnings for unexpected behavior.

equals.addEventListener("click", concatFunc);

function concatFunc() {


  if (previousComput == "") {
    secondNumber = displayCurr.innerHTML;
  } else {
    secondNumber = displayCurr.innerHTML;
  }


  displayPrev.innerHTML += `${displayCurr.innerHTML} ${equals.value}`;

  const operatorFunc = (firstNumber, operator, secondNumber) => {
    if (operator == "x") {
      return multiply(firstNumber, secondNumber);

    } else if (operator == "+") {

      return add(firstNumber, secondNumber);
    } else if (operator == "-") {


      return subtract(firstNumber, secondNumber);
    } else if (operator == "÷") {
      return divide(firstNumber, secondNumber);
    }
  };
  displayCurr.innerHTML = operatorFunc(firstNumber, operator, secondNumber);

  return operatorFunc(firstNumber, operator, secondNumber);
}


Enter fullscreen mode Exit fullscreen mode

Congratulations!

You have created a javascript calculator. If you didn’t complete, don’t feel bad about it.It may take a while before most of the concepts make sense.

Conclusion

By completing this project, you have learn't alot including:

  • How to use CSS grid and flexbox
  • How to do variable declaration
  • How to fetch elements from the DOM and general DOM manipulation.You have learnt how methods such as querySelector, querySelectorAll and getElementById are useful in DOM manipulation.
  • How to use event-listeners especially "click" and subsequent chaining of callback functions
  • How to appropriately invoke functions
  • Finally, you have learnt how to effectively think logically when setting up a project.

I wish you well in your web development journey.

twitter
linkedin

Top comments (0)