JavaScript Calculator - Beginner Project


In this tutorial, we are going to create a simple JavaScript calculator. The calculator is able to perform addition, subtraction, multiplication, and division on 2 or more than 2 numbers.

Calculator can come out to be a very useful application in day-to-day life. You can use a calculator to calculate your shopping bill, calculate your loan, perform simple mathematical calculations, etc.

We are going to create a simple calculator in this article prerequisites for this tutorial are:

Prerequisites

  1. HTML
  2. CSS
  3. JavaScript

Before proceeding further let's have a look at what we are going to build.

javascript calculator
Test the app

Simple JavaScript Calculator

A simple calculator is used to perform simple mathematical calculations like addition, subtraction, multiplication, and division.

Let's start creating our simple calculator. We are going to use:

  1. HTML (index.html) - To create the structure of the calculator
  2. CSS (style.css) - To style the calculator
  3. JavaScript (script.js) - To create the logic of the calculator

We will start building our calculator step by step. First, the structure of the calculator will be created (using HTML), then we will style it (using CSS), and finally, we will create the logic of the calculator (using JavaScript).


1. HTML - Creating the structure of the calculator

When you create the structure of anything in HTML, the structure need not be perfect in the first attempt. You can always modify the structure later. So, let's start creating the structure of our calculator.

To start with first create a container (a div element with a class container) and inside it create another div element with a class calculator. This div element will be our calculator container.

<div class="container">
  <div class="calculator">
  </div>
</div>

Now, inside the calculator container, create 2 div elements one to display the result and another to display the input.

<div class="calculator">
  <div class="output">
  </div>
  <div class="input">
  </div>
</div>

The output element will further contain 2 pre elements. The first one is called upper output, which displays the expression, and the second one is called lower output, which displays the result.

<div class="output">
  <pre class="upper"></pre>
  <pre class="lower">0</pre>
</div>

The input element will contain all kinds of input buttons we can have like, numbers, operators, clear, brackets, etc. Also, attach onclick event to all these buttons with a javascript function.

<div class="input">
  <button onclick="pressAllClear()">AC</button>
  <button onclick="pressNum(this)">0</button>
  <button onclick="pressClear()"><i class="fas fa-backspace"></i></button>
  <button onclick="pressOperator(this)">+</button>
  <button onclick="pressNum(this)">1</button>
  <button onclick="pressNum(this)">2</button>
  <button onclick="pressNum(this)">3</button>
  <button onclick="pressOperator(this)">-</button>
  <button onclick="pressNum(this)">4</button>
  <button onclick="pressNum(this)">5</button>
  <button onclick="pressNum(this)">6</button>
  <button onclick="pressOperator(this)">&times;</button>
  <button onclick="pressNum(this)">7</button>
  <button onclick="pressNum(this)">8</button>
  <button onclick="pressNum(this)">9</button>
  <button onclick="pressOperator(this)">&div;</button>
  <button onclick="pressDot()">.</button>
  <button onclick="pressBracket(this)">(</button>
  <button onclick="pressBracket(this)">)</button>
  <button onclick="pressEqual()">=</button>
</div>

In the above code, you can see the buttons are in a certain order because we want our buttons to be in specific places. With different orders, we can create different layouts of the calculator.

Finally, connect the CSS and Javascript files to the HTML file. Also, add font-awesome icons to the HTML file.

Here is the complete HTML code of the calculator. Save it as index.html file.

Complete HTML Code

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  <link rel="stylesheet" href="./style.css">
  <title>Javascript Calculator</title>
</head>

<body>
  <div class="container">
    <div class="calculator">
      <div class="output">
        <pre id="upper"></pre>
        <pre id="lower">0</pre>
      </div>
      <div class="input">
        <button onclick="pressAllClear()">AC</button>
        <button onclick="pressNum(this)">0</button>
        <button onclick="pressClear()"><i class="fas fa-backspace"></i></button>
        <button onclick="pressOperator(this)">+</button>
        <button onclick="pressNum(this)">1</button>
        <button onclick="pressNum(this)">2</button>
        <button onclick="pressNum(this)">3</button>
        <button onclick="pressOperator(this)">-</button>
        <button onclick="pressNum(this)">4</button>
        <button onclick="pressNum(this)">5</button>
        <button onclick="pressNum(this)">6</button>
        <button onclick="pressOperator(this)">&times;</button>
        <button onclick="pressNum(this)">7</button>
        <button onclick="pressNum(this)">8</button>
        <button onclick="pressNum(this)">9</button>
        <button onclick="pressOperator(this)">&div;</button>
        <button onclick="pressDot()">.</button>
        <button onclick="pressBracket(this)">(</button>
        <button onclick="pressBracket(this)">)</button>
        <button onclick="pressEqual()">=</button>
      </div>
    </div>
  </div>

  <script src="./script.js"></script>
</body>

</html>

Here is how it looks:

HTML output javascript calculator

2. CSS - Styling the calculator

To style the calculator, you need to create a CSS file. In the CSS file, target the elements using the CSS selector and add the styles to them.:

For buttons direction and flow, you can use CSS flexbox.

Here is the complete CSS code of the calculator. Save it as a style.css file.

Complete CSS Code

/* Calculator CSS */
@import url('https://fonts.googleapis.com/css2?family=Orbitron&display=swap');

body {
  margin: 0;
  box-sizing: border-box;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #4e4e4e;
}

.calculator {
  background: #dd6f6f;
  border-radius: 5px;
  padding: 5px;
  width: 300px;
  min-width: 300px;
  box-shadow: inset 2px 2px 5px rgba(255, 255, 255, 0.4), 
                    4px 4px 10px rgba(0, 0, 0, 0.7);
}

.output {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  position: relative;
  background: #ffffff;
  min-height: 50px;
  padding: 5px;
  margin: 0 1px 10px;
  border-radius: 0.25rem;
  box-shadow: inset 1px 1px 5px rgba(0, 0, 0, 0.5);
}

.output pre {
  text-align: right;
  font-size: 25px;
  margin: 0;
  font-family: 'Orbitron', sans-serif;
  width: 288px;
  overflow-x: auto;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.output pre::-webkit-scrollbar {
  display: none;
}

.output #upper {
  color: #424242;
  font-size: 18px;
}

.input {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.input button {
  width: calc(25% - 24px);
  height: 50px;
  margin: 8px 12px;
  border-radius: 50%;
  background-color: #c05d5d;
  box-shadow: inset 1px 1px 2px rgba(255, 255, 255, 0.3),
                    1px 1px 5px rgba(94, 31, 31, 0.7);
  color: white;
  font-size: 20px;
  font-weight: bold;
  cursor: pointer;
  outline: none;
  border: none;
}

.input button:hover {
  background-color: #b35555;
}

.input button:active {
  box-shadow: inset 1px 1px 5px rgba(94, 31, 31, 0.7),
              inset -1px -1px 2px rgba(255, 255, 255, 0.3);
  color: #642929;
}

We have completed the design of the calculator. Now, we need to create the JavaScript code to make the calculator work.


3. Javascript Calculator Code

Let's now write javascript code for the calculator.

I. Selecting the elements

In the HTML part, you can see there are 2 output elements. Select both of them using the querySelector method.

// Select the output elements
// upper output is for showing the expression
let outputUpper = document.querySelector('#upper');
// lower output is for showing the result
let outputLower = document.querySelector('#lower');

'outputLower' is a place where the expression given by the user and the output of the result will be shown.

'outputUpper' is a place where the expression given by the user will be shown in small size just above the result so that the user can see both their expression and result at the same time.

II. Now create a function to input the numbers

// function to get number input
function pressNum(e) {
  if (outputLower.innerHTML === '0') {
    outputLower.innerHTML = e.innerHTML;
  } else {
    outputLower.innerHTML += e.innerHTML;
  }
}

The above function will be called when any number button is pressed. It will check if the outputLower (expression) is 0 or not. If it is 0, then it will replace the 0 with the number pressed. If it is not 0, then it will add the number pressed to the outputLower.

The function is getting the number pressed by using this keyword.

III. Now create a function to input the operators

// function to get operator input
function pressOperator(e) {
  // check last operator
  let lastOperator = outputLower.innerHTML.slice(-1);
  if (lastOperator.includes('+', '-', '×', '÷')) {
    output.innerHTML = outputLower.innerHTML.slice(0, -1) + e.innerHTML;
  } else {
    outputLower.innerHTML += e.innerHTML;
  }
}

The above function will be called when any operator button is pressed. It will check if the last operator in the expression is +, -, ×, or ÷. If it is +, -, ×, or ÷, then it will replace the last operator with the operator pressed. If it is not +, -, × or ÷, then it will add the operator pressed to the outputLower.

We are checking and replacing the last operator because if someone presses + operator more than once then it becomes ++ or +++ which is not a valid operator. Or there could be a case of +*, +/+, etc. So we replace the last operator with the newly pressed operator.

IV. Now create a function to clear the calculator

We have 2 buttons to clear the calculator. One is clear button and other is clear all button.

// function to clear the calculator
// clear all
function pressAllClear() {
  outputUpper.innerHTML = '';
  outputLower.innerHTML = '0';
}

// clear one
function pressClear() {
  outputLower.innerHTML = outputLower.innerHTML.slice(0, -1);
}

To clear one number, we will use 'outputLower.innerHTML.slice(0, -1)' method. This will remove the last number from the expression. To clear all numbers, we will use 'outputLower.innerHTML = '0';' method. This will replace the expression with 0.

V. Create function for writing dot and brackets

// function to get dot and bracket input
function pressDot() {
  outputLower.innerHTML += '.';
}

function pressBracket(e) {
  outputLower.innerHTML += e.innerHTML;
} 

VI. Now create function to calculate the result

// function to calculate the result
function pressEqual() {
  let exp = outputLower.innerHTML;
  outputUpper.innerHTML = exp;
  exp = exp.replace(/×/g, '*').replace(/÷/g, '/');
  let result;
  try {
    result = eval(exp);
    // if decimal number more than 4 decimal places
    if (result.toString().indexOf('.') !== -1) {
      result = result.toFixed(4);
    }
  } catch (e) {
    result = 'Error';
  }
  outputLower.innerHTML = result;
}

The above function will be called when the equal button (=) is pressed. It will calculate the result of the expression and show it in the outputLower.

We are using the eval() method to calculate the result.

Here, we are executing the expression within the try and catch block. If there is any error in the expression, then it will show an error.

We are also checking if the result is a decimal number or not. If it is a decimal number, then we will show it with 4 decimal places.

Finally, the result is shown in the outputLower and the corresponding expression is shown in the outputUpper.

VII. Now create function to clear expression and all clear screen

// clear one
function pressClear() {
  outputLower.innerHTML = outputLower.innerHTML.slice(0, -1);
}

// clear all
function pressAllClear() {
  outputUpper.innerHTML = '';
  outputLower.innerHTML = '0';
}

To clear one number, we will use 'outputLower.innerHTML.slice(0, -1)' method. This will remove the last number from the expression. To clear all numbers, we will use 'outputLower.innerHTML = '0';' method. This will replace the expression with 0.

VIII. Now add event listeners for keyboard buttons

Finally, add an event listener for keyboard buttons, so that when any button is pressed, it will call the corresponding function and the user will be able to run the calculator from the keyboard itself.

// add event listeners for keyboard buttons
document.addEventListener('keydown', function (e) {
  switch (e.key) {
    case '0':
      pressNum(document.querySelector('button:nth-child(2)'));
      break;
    case '1':
      pressNum(document.querySelector('button:nth-child(5)'));
      break;
    case '2':
      pressNum(document.querySelector('button:nth-child(6)'));
      break;
    case '3':
      pressNum(document.querySelector('button:nth-child(7)'));
      break;
    case '4':
      pressNum(document.querySelector('button:nth-child(9)'));
      break;
    case '5':
      pressNum(document.querySelector('button:nth-child(10)'));
      break;
    case '6':
      pressNum(document.querySelector('button:nth-child(11)'));
      break;
    case '7':
      pressNum(document.querySelector('button:nth-child(13)'));
      break;
    case '8':
      pressNum(document.querySelector('button:nth-child(14)'));
      break;
    case '9':
      pressNum(document.querySelector('button:nth-child(15)'));
      break;
    case '+':
      pressOperator(document.querySelector('button:nth-child(4)'));
      break;
    case '-':
      pressOperator(document.querySelector('button:nth-child(8)'));
      break;
    case '*':
      pressOperator(document.querySelector('button:nth-child(12)'));
      break;
    case '/':
      pressOperator(document.querySelector('button:nth-child(16)'));
      break;
    case '.':
      pressDot();
      break;
    case '(':
      pressBracket(document.querySelector('button:nth-child(18)'));
      break;
    case ')':
      pressBracket(document.querySelector('button:nth-child(19)'));
      break;
    case 'Enter':
      // prevent default action
      e.preventDefault();
      pressEqual();
      break;
    case 'Backspace':
      pressClear();
      break;
    case 'Escape':
      pressAllClear();
      break;
  }
});

In the above code, you can see we are using a button position to get the button. We are using 'document.querySelector('button:nth-child(2)')' to get the button with position 2. This will get the button with the number 0. and so on.


Complete JavaScript Calculator Program

Here is the complete code for a simple calculator.

Example

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

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  <title>Javascript Calculator</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Orbitron&display=swap');

    body {
      margin: 0;
      box-sizing: border-box;
    }

    .container {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #4e4e4e;
    }

    .calculator {
      background: #dd6f6f;
      border-radius: 5px;
      padding: 5px;
      width: 300px;
      min-width: 300px;
      box-shadow: inset 2px 2px 5px rgba(255, 255, 255, 0.4),
                        4px 4px 10px rgba(0, 0, 0, 0.7);
    }

    .output {
      display: flex;
      flex-direction: column;
      align-items: flex-end;
      position: relative;
      background: #ffffff;
      min-height: 50px;
      padding: 5px;
      margin: 0 1px 10px;
      border-radius: 0.25rem;
      box-shadow: inset 1px 1px 5px rgba(0, 0, 0, 0.5);
    }

    .output pre {
      text-align: right;
      font-size: 25px;
      margin: 0;
      font-family: 'Orbitron', sans-serif;
      width: 288px;
      overflow-x: auto;
      -ms-overflow-style: none;
      scrollbar-width: none;
    }

    .output pre::-webkit-scrollbar {
      display: none;
    }

    .output #upper {
      color: #424242;
      font-size: 18px;
    }

    .input {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }

    .input button {
      width: calc(25% - 24px);
      height: 50px;
      margin: 8px 12px;
      border-radius: 50%;
      background-color: #c05d5d;
      box-shadow: inset 1px 1px 2px rgba(255, 255, 255, 0.3),
                        1px 1px 5px rgba(94, 31, 31, 0.7);
      color: white;
      font-size: 20px;
      font-weight: bold;
      cursor: pointer;
      outline: none;
      border: none;
    }

    .input button:hover {
      background-color: #b35555;
    }

    .input button:active {
      box-shadow: inset 1px 1px 5px rgba(94, 31, 31, 0.7),
                  inset -1px -1px 2px rgba(255, 255, 255, 0.3);
      color: #642929;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="calculator">
      <div class="output">
        <pre id="upper"></pre>
        <pre id="lower">0</pre>
      </div>
      <div class="input">
        <button onclick="pressAllClear()">AC</button>
        <button onclick="pressNum(this)">0</button>
        <button onclick="pressClear()"><i class="fas fa-backspace"></i></button>
        <button onclick="pressOperator(this)">+</button>
        <button onclick="pressNum(this)">1</button>
        <button onclick="pressNum(this)">2</button>
        <button onclick="pressNum(this)">3</button>
        <button onclick="pressOperator(this)">-</button>
        <button onclick="pressNum(this)">4</button>
        <button onclick="pressNum(this)">5</button>
        <button onclick="pressNum(this)">6</button>
        <button onclick="pressOperator(this)">&times;</button>
        <button onclick="pressNum(this)">7</button>
        <button onclick="pressNum(this)">8</button>
        <button onclick="pressNum(this)">9</button>
        <button onclick="pressOperator(this)">&div;</button>
        <button onclick="pressDot()">.</button>
        <button onclick="pressBracket(this)">(</button>
        <button onclick="pressBracket(this)">)</button>
        <button onclick="pressEqual()">=</button>
      </div>
    </div>
  </div>

  <script>
    // javascript calculator

    // upper output is for showing the expression
    let outputUpper = document.querySelector('#upper');
    // lower output is for showing the result
    let outputLower = document.querySelector('#lower');

    // function to get number input
    function pressNum(e) {
      if (outputLower.innerHTML === '0') {
        outputLower.innerHTML = e.innerHTML;
      } else {
        outputLower.innerHTML += e.innerHTML;
      }
    }

    // clear all
    function pressAllClear() {
      outputUpper.innerHTML = '';
      outputLower.innerHTML = '0';
    }

    // clear one
    function pressClear() {
      outputLower.innerHTML = outputLower.innerHTML.slice(0, -1);
    }

    // calculate button
    function pressEqual() {
      let exp = outputLower.innerHTML;
      outputUpper.innerHTML = exp;
      exp = exp.replace(/×/g, '*').replace(/÷/g, '/');
      let result;
      try {
        result = eval(exp);
        // if decimal number more than 4 decimal places
        if (result.toString().indexOf('.') !== -1) {
          result = result.toFixed(4);
        }
      } catch (e) {
        result = 'Error';
      }
      outputLower.innerHTML = result;
    }

    function pressOperator(e) {
      // check last operator
      let lastOperator = outputLower.innerHTML.slice(-1);
      if (lastOperator.includes('+', '-', '×', '÷')) {
        output.innerHTML = outputLower.innerHTML.slice(0, -1) + e.innerHTML;
      } else {
        outputLower.innerHTML += e.innerHTML;
      }
    }

    function pressDot() {
      outputLower.innerHTML += '.';
    }

    function pressBracket(e) {
      outputLower.innerHTML += e.innerHTML;
    }

    // attach keyboard event
    document.addEventListener('keydown', function (e) {
      switch (e.key) {
        case '0':
          pressNum(document.querySelector('button:nth-child(2)'));
          break;
        case '1':
          pressNum(document.querySelector('button:nth-child(5)'));
          break;
        case '2':
          pressNum(document.querySelector('button:nth-child(6)'));
          break;
        case '3':
          pressNum(document.querySelector('button:nth-child(7)'));
          break;
        case '4':
          pressNum(document.querySelector('button:nth-child(9)'));
          break;
        case '5':
          pressNum(document.querySelector('button:nth-child(10)'));
          break;
        case '6':
          pressNum(document.querySelector('button:nth-child(11)'));
          break;
        case '7':
          pressNum(document.querySelector('button:nth-child(13)'));
          break;
        case '8':
          pressNum(document.querySelector('button:nth-child(14)'));
          break;
        case '9':
          pressNum(document.querySelector('button:nth-child(15)'));
          break;
        case '+':
          pressOperator(document.querySelector('button:nth-child(4)'));
          break;
        case '-':
          pressOperator(document.querySelector('button:nth-child(8)'));
          break;
        case '*':
          pressOperator(document.querySelector('button:nth-child(12)'));
          break;
        case '/':
          pressOperator(document.querySelector('button:nth-child(16)'));
          break;
        case '.':
          pressDot();
          break;
        case '(':
          pressBracket(document.querySelector('button:nth-child(18)'));
          break;
        case ')':
          pressBracket(document.querySelector('button:nth-child(19)'));
          break;
        case 'Enter':
          // prevent default action
          e.preventDefault();
          pressEqual();
          break;
        case 'Backspace':
          pressClear();
          break;
        case 'Escape':
          pressAllClear();
          break;
      }
    });
  </script>
</body>

</html>

Conclusion

In this complete guide to JavaScript calculator, you have learned to create an awesome simple calculator. You can use it to calculate any mathematical expression. The keyboard event is also attached to the calculator. You can also use the calculator on your website or mobile app.