<!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="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <title>Calculator</title>
</head>

<body>
  <section class="calculator-grid">
    <div class="output">
      <div data-previous-operand class="previous"></div>
      <div data-current-operand class="current"></div>
    </div>
    <button data-all-clear class="span-two yellow">AC</button>
    <button data-delete class="yellow">DEL</button>
    <button data-operation class="light-purple">÷</button>
    <button data-number="7">7</button>
    <button data-number>8</button>
    <button data-number>9</button>
    <button data-operation class="light-purple">×</button>
    <button data-number>4</button>
    <button data-number>5</button>
    <button data-number>6</button>
    <button data-operation class="light-purple">-</button>
    <button data-number>1</button>
    <button data-number>2</button>
    <button data-number>3</button>
    <button data-operation class="light-purple">+</button>
    <button data-number class="span-two">0</button>
    <button data-number>.</button>
    <button data-equals class="dark-purple">=</button>
  </section>


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

</html>
* {
  font-family: "Roboto", sans-serif;
  margin: 0;
  padding: 0;
}

body {
  background-color: #fdfdfd;
}

button {
  border-radius: 50%;
  width: 70px;
  height: 70px;
  text-align: center;
  font-size: 1.5rem;
  border: 1px;
  background-image: linear-gradient(#e8e8e8 0%, #ddd 100%);
  text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.66);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5),
    0 2px 2px rgba(0, 0, 0, 0.19);
  border-bottom: solid 2px #b5b5b5;
}

button:active {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 2px 2px rgba(0, 0, 0, 0.19);
  border-bottom: none;
}

.span-two {
  grid-column: 1 / span 2;
  width: 160px;
  border-radius: 50px;
}

.calculator-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 6px;
  width: 350px;
  margin: 5rem auto;
  box-shadow: 5px 5px 15px 5px rgba(234, 232, 232, 0.25);
  border-radius: 10px;
  padding: 50px 20px;
}

.output {
  grid-column-start: span 4;
  font-size: 3rem;
  display: inline;
  vertical-align: bottom;
  text-align: right;
  padding-top: 50px;
  word-wrap: break-word;
  word-break: break-all;
}

.previous,
.current {
  padding: 5px 20px;
  height: 50px;
}

.previous {
  font-size: 1.5rem;
  color: #515050;
}

.light-purple {
  background-image: linear-gradient(#dccdff 0%, #b07ad5 100%);
  color: #8c00ff;
}

.dark-purple {
  background-image: linear-gradient(#7b43ff 0%, #660ea2 100%);
  color: #fff;
}

.yellow {
  background-image: linear-gradient(#fff8bd 0%, #f4db79 100%);
  color: #e9ab36;
}
class Calculator {
  constructor(previousOperationTextEl, currentOperationTextEl) {
    this.previousOperationTextEl = previousOperationTextEl;
    this.currentOperationTextEl = currentOperationTextEl;
    this.clear();
  }

  // functions
  clear() {
    this.currentOperand = "";
    this.previousOperand = "";
    this.operation = undefined;
  }

  delete() {
    this.currentOperand = this.currentOperand.toString().slice(0, -1);
  }

  appendNumber(number) {
    if (number === "." && this.currentOperand.includes(".")) return;
    this.currentOperand = this.currentOperand.toString() + number.toString();
  }

  chooseOperation(operation) {
    if (this.currentOperand === "") return; // if currentOperand is empty, exit the function now
    if (this.previousOperand !== "") {
      this.compute();
    }
    this.operation = operation;
    this.previousOperand = this.currentOperand;
    this.currentOperand = "";
  }

  compute() {
    let computation;
    const prev = parseFloat(this.previousOperand);
    const current = parseFloat(this.currentOperand);
    if (isNaN(prev) || isNaN(current)) return; // if the user click equals button with enpty numbers, cancel this function
    switch (this.operation) {
      case "+":
        computation = prev + current;
        break;
      case "-":
        computation = prev - current;
        break;
      case "÷":
        computation = prev / current;
        break;
      case "×":
        computation = prev * current;
        break;
      case "%":
        computation = prev / current;
        break;
      default:
        return;
    }

    this.currentOperand = computation;
    this.operation = undefined;
    this.previousOperand = "";
  }

  getDisplayNumber(number) {
    const stringNumber = number.toString();
    const integerDigits = parseFloat(stringNumber.split("."[0]));
    const decimalDigits = stringNumber.split(".")[1];
    let integerDisplay;
    if (isNaN(integerDigits)) {
      integerDisplay = "";
    } else {
      integerDisplay = integerDigits.toLocaleString("en", {
        maximamFractionDigits: 0,
      });
    }
    if (decimalDigits != null) {
      return `${integerDisplay}.${decimalDigits}`;
    } else {
      return integerDisplay;
    }
  }

  updateDisplay() {
    this.currentOperationTextEl.innerText = this.getDisplayNumber(
      this.currentOperand,
    );
    if (this.operation != null) {
      this.previousOperationTextEl.innerText = `${this.getDisplayNumber(
        this.previousOperand,
      )} ${this.operation}`;
    } else {
      this.previousOperationTextEl.innerText = "";
    }
  }
}

const numberButtons = document.querySelectorAll("[data-number]");
const operationButtons = document.querySelectorAll("[data-operation]");
const equalsButton = document.querySelector("[data-equals]");
const deleteButton = document.querySelector("[data-delete]");
const allClearButton = document.querySelector("[data-all-clear]");
const previousOperationTextEl = document.querySelector(
  "[data-previous-operand]",
);
const currentOperationTextEl = document.querySelector("[data-current-operand]");

const calculator = new Calculator(
  previousOperationTextEl,
  currentOperationTextEl,
);

numberButtons.forEach((button) => {
  button.addEventListener("click", () => {
    calculator.appendNumber(button.innerText);
    calculator.updateDisplay();
    console.log(calculator.currentOperand);
  });
});

operationButtons.forEach((button) => {
  button.addEventListener("click", () => {
    calculator.chooseOperation(button.innerText);
    calculator.updateDisplay();
  });
});

allClearButton.addEventListener("click", () => {
  calculator.clear();
  calculator.updateDisplay();
});

equalsButton.addEventListener("click", () => {
  calculator.compute();
  calculator.updateDisplay();
});

deleteButton.addEventListener("click", () => {
  calculator.delete();
  calculator.updateDisplay();
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.