Pranav Borse
Pranav Borse

Reputation: 63

Where to reset the value of operator in calculator?

This is a live demo of my calculator: https://kepplin.github.io/odin-calculator/

After the equals button is pressed and the calculation is displayed, if a number button is pressed, then instead of starting a new calculation, the calculator evaluates with the operator of the previous calculation.

I have 3 global variables: num1, num2, operator. As well as a previous display and current display.

Example of the problem (step-by-step):

12

console.log(num1) // 12
console.log(num2) // 
console.log(operator) //

12 +

console.log(num1) // 
console.log(num2) // 12
console.log(operator) // +

12 + 4

console.log(num1) // 4
console.log(num2) // 12
console.log(operator) // +

After the '=' button is pressed, the calculator displays:

16

console.log(num1) // 
console.log(num2) // 16
console.log(operator) // +

The calculator immediately evaluates if there are values for num1, num2, and operator. The problem comes here, if the user wants to start a different calculation (e.g, 5 - 4):

5

console.log(num1) // 5
console.log(num2) // 16
console.log(operator) // +

5 -

console.log(num1) //
console.log(num2) // 21
console.log(operator) // -

The calculator did 5 + 16. I want the values of num1, num2 and operator to be reset back to ' ' if a number button is pressed after the calculator has evaluated (only for a number button not an operator button).

An example of the behaviour I want is this:

https://mike-monta.github.io/calculator-pro/

https://github.com/Mike-Monta/calculator-pro

Here's my 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">
    <title>Calculator</title>
    <link rel="stylesheet" href="style.css">
    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
</head>
<body>
    <div class="calcBody">
        <div class="calcDisplay">
            <div class="screenDisplay">
                <div class="prevDisplay"></div>
                <div class="currentDisplay">0</div>
            </div>
        </div>
        <div class="buttonsBody">
            <div class="numberButtons">
                <!--Row 1-->
                <button class="clearButton inputButton" data-all="AC"><span class="buttonsText">AC</span></button>
                <button class="deleteButton inputButton" data-all="C"><span class="buttonsText">C</span></button>
                <button class="percentButton inputButton" data-all="%" data-operator="%"><span class="buttonsText">%</span></button>
                <button class="divideButton inputButton" data-all="÷" data-operator="÷"><span class="buttonsText">÷</span></button>
                <!--Row 2-->
                <button class="sevenButton inputButton" data-all="7" data-num="7"><span class="buttonsText">7</span></button>
                <button class="eightButton inputButton" data-all="8" data-num="8"><span class="buttonsText">8</span></button>
                <button class="nineButton inputButton" data-all="9" data-num="9"><span class="buttonsText">9</span></button>
                <button class="multiplyButton inputButton" data-all="×" data-operator="×"><span class="buttonsText">×</span></button>
                <!--Row 3-->
                <button class="fourButton inputButton" data-all="4" data-num="4"><span class="buttonsText">4</span></button>
                <button class="fiveButton inputButton" data-all="5" data-num="5"><span class="buttonsText">5</span></button>
                <button class="sixButton inputButton" data-all="6" data-num="6"><span class="buttonsText">6</span></button>
                <button class="minusButton inputButton" data-all="-" data-operator="-"><span class="buttonsText">-</span></button>
                <!--Row 4-->
                <button class="oneButton inputButton" data-all="1" data-num="1"><span class="buttonsText">1</span></button>
                <button class="twoButton inputButton" data-all="2" data-num="2"><span class="buttonsText">2</span></button>
                <button class="threeButton inputButton" data-all="3" data-num="3"><span class="buttonsText">3</span></button>
                <button class="plusButton inputButton" data-all="+" data-operator="+"><span class="buttonsText">+</span></button>
                <!--Row 5 -->
                <button class="doubleZeroButton inputButton" data-all="00" data-num="00"><span class="buttonsText">00</span></button>
                <button class="zeroButton inputButton" data-all="0" data-num="0"><span class="buttonsText">0</span></button>
                <button class="decimalButton inputButton" data-all="."><span class="buttonsText">.</span></button>
                <button class="equalsButton inputButton" data-all="="><span class="buttonsText">=</span></button>
            </div>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>
const prevDisplay = document.querySelector('.prevDisplay');
const currentDisplay = document.querySelector('.currentDisplay');
const inputButton = document.querySelectorAll('.inputButton');
const divideButton = document.querySelector('.divideButton');
const equalsButton = document.querySelector('.equalsButton');
const operatorButton = document.querySelectorAll('[data-operator]');
const numberButton = document.querySelectorAll('[data-num]');
const clearButton = document.querySelector('.clearButton');
const deleteButton = document.querySelector('.deleteButton');
const decimalButton = document.querySelector('.decimalButton')
//Global variables
let num1 = ""; 
let operator = "";
let num2 = "";
let removeDot;
//Current display
numberButton.forEach((btn) => {
  btn.addEventListener('click', (e) => {
    handleNumber(e.target.textContent);
  })

}
)
function handleNumber(number){
  if (num1.length <= 21){
    num1 += number;
    currentDisplay.textContent = num1;
  }
}
//Previous display
operatorButton.forEach((btn) => {
  btn.addEventListener('click', (e) => {
    handleOperator(e.target.textContent);
  })
})
function handleOperator(op){
  if (num1 == '' && num2 == ''){
    num1 = '0';
  } 
  else if (operator == '' && num2 !== ''){
    num2 = ''
  }  
  else if (num2 === "") {
    num2 = num1;
    operatorCheck(op);
  } else if (num1 === "") {
    operatorCheck(op);
  } else {
    operate();
    operator = op;
    currentDisplay.textContent = "0";
    prevDisplay.textContent = num2 + " " + operator;
  }
}
function operatorCheck(text) {
  operator = text;
  prevDisplay.textContent = num2 + " " + operator;
  currentDisplay.textContent = "0";
  num1 = "";
}
//Clear button
function clearCalc(){
  prevDisplay.textContent = '';
  currentDisplay.textContent = '';
  num1 = '';
  num2 = '';
  operator = '';
}
clearButton.addEventListener('click', clearCalc)
//Delete button
function deleteCalc(){
  num1 = num1.slice(0, currentDisplay.textContent.length - 1)
  currentDisplay.textContent = currentDisplay.textContent.slice(0, currentDisplay.textContent.length - 1)
}
deleteButton.addEventListener('click', deleteCalc)
//Equals button
function equalsCalc(){
  if (num1 != '' && num2 != ''){
    operate()
  }
}
equalsButton.addEventListener('click', equalsCalc)
//Decimal button
function decimalCalc(){
  if (num1.includes('.') == false){
  currentDisplay.textContent = currentDisplay.textContent + '.'
  num1 = num1 + '.'
    }
}
decimalButton.addEventListener('click', decimalCalc)
//Doing the calculation
function calcPercent(num1, num2){
  return (num2 / 100) * num1
}
function calcDivide(num1, num2){
    return num2 / num1
}
function calcMultiply(num1, num2){
    return num1 * num2
}
function calcSubtract(num1, num2){
    return num2 - num1
}
function calcAdd(num1, num2){
    return num1 + num2
}
function operate() {
    num1 = Number(num1)
    num2 = Number(num2)

    switch (operator) {
      case '+':
        num2 = calcAdd(num1, num2)
        break
      case '-':
        num2 = calcSubtract(num1, num2)
        break
      case '×':
        num2 = calcMultiply(num1, num2)
        break
      case '%':
        num2 = calcPercent(num1, num2)
        break
      case '÷':
        num2 = num2.toString(); 
        if (num1 == 0){
          num2 = "Error, you can't divide by 0"
        } else{
          num2 = calcDivide(num1, num2);
        }
        break
    }
    num2 = roundNum(num2)
    prevDisplay.textContent = "";
    currentDisplay.textContent = num2;
    num1 = '';
  }
  //Round Number
  function roundNum(num){
    return Math.round(num * 1000000) / 1000000;
  }
  //Event listeners for key presses
  window.addEventListener('keydown', removeDot = function(e){
    switch (e.key){
      case "7":
        handleNumber(7)
        break
      case "8":
        handleNumber(8)
        break
      case "9":
        handleNumber(9)
        break
      case "4":
        handleNumber(4)
        break
      case "5":
        handleNumber(5)
        break
      case "6":
        handleNumber(6)
        break
      case "1":
        handleNumber(1)
        break
      case "2":
        handleNumber(2)
        break
      case "3":
        handleNumber(3)
        break
      case "0":
        handleNumber(0)
        break
      case ")":
        handleNumber(00)
        break
      case "Delete":
        clearCalc();
        break
      case "+":
        handleOperator('+')
        break
      case "-":
        handleOperator('-')
        break  
      case "*":
        handleOperator('×')
        break
      case "/":
        handleOperator('÷')
        break
      case "%":
        handleOperator('%')
        break
      case ".":
        decimalCalc();
        break  
      case "Backspace":
        deleteCalc();
        break
      case "Enter":
        e.preventDefault();
        equalsCalc();
        break
    }
  }, true)

Upvotes: 2

Views: 463

Answers (2)

dangarfield
dangarfield

Reputation: 2340

I think I would generally have a different approach BUT...

A simple solution would be to capture the = as an operator, and check for it's presence in the handleNumber method. If it is the current operator, just clear num2.

...

function handleNumber(number) {
  if (num1.length <= 21) {
    num1 += number;
    currentDisplay.textContent = num1;
  }
  if (operator === '=') { // <-- Added
    num2 = ''
  }
}

...

function equalsCalc() {
  if (num1 != '' && num2 != '') {
    operate()
    operator = '=' // <-- Added
  }
}

...

const prevDisplay = document.querySelector('.prevDisplay');
const currentDisplay = document.querySelector('.currentDisplay');
const inputButton = document.querySelectorAll('.inputButton');
const divideButton = document.querySelector('.divideButton');
const equalsButton = document.querySelector('.equalsButton');
const operatorButton = document.querySelectorAll('[data-operator]');
const numberButton = document.querySelectorAll('[data-num]');
const clearButton = document.querySelector('.clearButton');
const deleteButton = document.querySelector('.deleteButton');
const decimalButton = document.querySelector('.decimalButton')
//Global variables
let num1 = "";
let operator = "";
let num2 = "";
let removeDot;
//Current display
numberButton.forEach((btn) => {
  btn.addEventListener('click', (e) => {
    handleNumber(e.target.textContent);
  })
})

function handleNumber(number) {
  console.log('handleNumber', num1, operator, num2, '->', number)
  if (num1.length <= 21) {
    num1 += number;
    currentDisplay.textContent = num1;
  }
  if (operator === '=') {
    num2 = ''
  }
  console.log('handleNumber END', num1, operator, num2)
}
//Previous display
operatorButton.forEach((btn) => {
  btn.addEventListener('click', (e) => {
    handleOperator(e.target.textContent);
  })
})

function handleOperator(op) {
  console.log('handleOperator', num1, operator, num2, '->', op)
  if (num1 == '' && num2 == '') {
    num1 = '';
  } else if (operator == '' && num2 !== '') {
    num2 = ''
  } else if (num2 === "") {
    num2 = num1;
    operatorCheck(op);
  } else if (num1 === "") {
    operatorCheck(op);
  } else {
    operate();
    operator = op;
    currentDisplay.textContent = "0";
    prevDisplay.textContent = num2 + " " + operator;
  }
  console.log('handleOperator END', num1, operator, num2)
}

function operatorCheck(text) {
  operator = text;
  prevDisplay.textContent = num2 + " " + operator;
  currentDisplay.textContent = "0";
  num1 = "";
}
//Clear button
function clearCalc() {
  prevDisplay.textContent = '';
  currentDisplay.textContent = '';
  num1 = '';
  num2 = '';
  operator = '';
}
clearButton.addEventListener('click', clearCalc)
//Delete button
function deleteCalc() {
  num1 = num1.slice(0, currentDisplay.textContent.length - 1)
  currentDisplay.textContent = currentDisplay.textContent.slice(0, currentDisplay.textContent.length - 1)
}
deleteButton.addEventListener('click', deleteCalc)
//Equals button
function equalsCalc() {
  if (num1 != '' && num2 != '') {
    operate()
    console.log('equalsCalc END', num1, operator, num2)
    operator = '='
  }
}
equalsButton.addEventListener('click', equalsCalc)
//Decimal button
function decimalCalc() {
  if (num1.includes('.') == false) {
    currentDisplay.textContent = currentDisplay.textContent + '.'
    num1 = num1 + '.'
  }
}
decimalButton.addEventListener('click', decimalCalc)
//Doing the calculation
function calcPercent(num1, num2) {
  return (num2 / 100) * num1
}

function calcDivide(num1, num2) {
  return num2 / num1
}

function calcMultiply(num1, num2) {
  return num1 * num2
}

function calcSubtract(num1, num2) {
  return num2 - num1
}

function calcAdd(num1, num2) {
  return num1 + num2
}

function operate() {
  num1 = Number(num1)
  num2 = Number(num2)

  switch (operator) {
    case '+':
      num2 = calcAdd(num1, num2)
      break
    case '-':
      num2 = calcSubtract(num1, num2)
      break
    case '×':
      num2 = calcMultiply(num1, num2)
      break
    case '%':
      num2 = calcPercent(num1, num2)
      break
    case '÷':
      num2 = num2.toString();
      if (num1 == 0) {
        num2 = "Error, you can't divide by 0"
      } else {
        num2 = calcDivide(num1, num2);
      }
      break
  }
  num2 = roundNum(num2)
  prevDisplay.textContent = "";
  currentDisplay.textContent = num2;
  num1 = '';
}
//Round Number
function roundNum(num) {
  return Math.round(num * 1000000) / 1000000;
}
//Event listeners for key presses
window.addEventListener('keydown', removeDot = function(e) {
  switch (e.key) {
    case "7":
      handleNumber(7)
      break
    case "8":
      handleNumber(8)
      break
    case "9":
      handleNumber(9)
      break
    case "4":
      handleNumber(4)
      break
    case "5":
      handleNumber(5)
      break
    case "6":
      handleNumber(6)
      break
    case "1":
      handleNumber(1)
      break
    case "2":
      handleNumber(2)
      break
    case "3":
      handleNumber(3)
      break
    case "0":
      handleNumber(0)
      break
    case ")":
      handleNumber(00)
      break
    case "Delete":
      clearCalc();
      break
    case "+":
      handleOperator('+')
      break
    case "-":
      handleOperator('-')
      break
    case "*":
      handleOperator('×')
      break
    case "/":
      handleOperator('÷')
      break
    case "%":
      handleOperator('%')
      break
    case ".":
      decimalCalc();
      break
    case "Backspace":
      deleteCalc();
      break
    case "Enter":
      e.preventDefault();
      equalsCalc();
      break
  }
}, true)
html,
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  padding: 0;
  margin: 0;
}

.calcBody {
  display: flex;
  background-color: rgb(160, 160, 160);
  width: 500px;
  height: 700px;
  border: 2px solid black;
  border-radius: 35px;
  padding-bottom: 25px;
  transform: scale(0.95, 1);
}

.calcDisplay {
  display: flex;
  height: 200px;
  width: 500px;
  position: absolute;
  justify-content: center;
  border-radius: 30px;
}

.screenDisplay {
  display: flex;
  align-self: center;
  background-color: rgb(248, 248, 248);
  width: 450px;
  height: 150px;
  justify-content: flex-end;
  border-radius: 45px;
  border: 2px solid black;
}

.prevDisplay {
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  width: 85%;
  height: 50px;
  position: absolute;
  margin-top: 50px;
  margin-right: 25px;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  font-size: 20px;
  margin-bottom: 20px;
}

.currentDisplay {
  display: flex;
  align-self: flex-end;
  justify-self: end;
  height: 50px;
  width: 100%;
  justify-content: flex-end;
  margin-right: 25px;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  font-size: 30px;
  margin-bottom: 20px;
}

.buttonsBody {
  display: flex;
  width: 100%;
  height: 500px;
  align-self: flex-end;
  justify-content: center;
}

.numberButtons {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
  width: 450px;
  height: 500px;
  gap: 5px;
}

.inputButton {
  padding: 0px;
  margin: 0px;
  border: 2px solid black;
  border-radius: 20px;
  transition: 200ms;
  background-color: rgb(231, 231, 231);
}

.buttonsText {
  padding: 0;
  margin: 0;
  font-size: 20px;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  transition: 150ms;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
}

.inputButton:hover {
  background-color: darkgray;
  cursor: pointer;
}

.buttonsText:hover {
  font-size: 30px;
}

.clearButton,
.deleteButton {
  background-color: rgb(223, 145, 145);
}

.equalsButton {
  background-color: rgb(187, 238, 110);
}
<div class="calcBody">
  <div class="calcDisplay">
    <div class="screenDisplay">
      <div class="prevDisplay"></div>
      <div class="currentDisplay"></div>
    </div>
  </div>
  <div class="buttonsBody">
    <div class="numberButtons">
      <!--Row 1-->
      <button class="clearButton inputButton" data-all="AC"><span class="buttonsText">AC</span></button>
      <button class="deleteButton inputButton" data-all="C"><span class="buttonsText">C</span></button>
      <button class="percentButton inputButton" data-all="%" data-operator="%"><span class="buttonsText">%</span></button>
      <button class="divideButton inputButton" data-all="÷" data-operator="÷"><span class="buttonsText">÷</span></button>
      <!--Row 2-->
      <button class="sevenButton inputButton" data-all="7" data-num="7"><span class="buttonsText">7</span></button>
      <button class="eightButton inputButton" data-all="8" data-num="8"><span class="buttonsText">8</span></button>
      <button class="nineButton inputButton" data-all="9" data-num="9"><span class="buttonsText">9</span></button>
      <button class="multiplyButton inputButton" data-all="×" data-operator="×"><span class="buttonsText">×</span></button>
      <!--Row 3-->
      <button class="fourButton inputButton" data-all="4" data-num="4"><span class="buttonsText">4</span></button>
      <button class="fiveButton inputButton" data-all="5" data-num="5"><span class="buttonsText">5</span></button>
      <button class="sixButton inputButton" data-all="6" data-num="6"><span class="buttonsText">6</span></button>
      <button class="minusButton inputButton" data-all="-" data-operator="-"><span class="buttonsText">-</span></button>
      <!--Row 4-->
      <button class="oneButton inputButton" data-all="1" data-num="1"><span class="buttonsText">1</span></button>
      <button class="twoButton inputButton" data-all="2" data-num="2"><span class="buttonsText">2</span></button>
      <button class="threeButton inputButton" data-all="3" data-num="3"><span class="buttonsText">3</span></button>
      <button class="plusButton inputButton" data-all="+" data-operator="+"><span class="buttonsText">+</span></button>
      <!--Row 5 -->
      <button class="doubleZeroButton inputButton" data-all="00" data-num="00"><span class="buttonsText">00</span></button>
      <button class="zeroButton inputButton" data-all="0" data-num="0"><span class="buttonsText">0</span></button>
      <button class="decimalButton inputButton" data-all="."><span class="buttonsText">.</span></button>
      <button class="equalsButton inputButton" data-all="="><span class="buttonsText">=</span></button>
    </div>
  </div>
</div>

Upvotes: 2

Alex Badea
Alex Badea

Reputation: 11

You can clear num2 after new number has been clicked. typeof num2 !== 'string' checks if it was operated before.

    function handleNumber(number) {
        if (typeof num2 !== 'string' && operator === '') num2 = ''; // Add this line
        if (num1.length <= 21) {
          num1 += number;
          currentDisplay.textContent = num1;
        }
    }

Upvotes: 0

Related Questions