Let's Build a Calculator Web App

Let's Build a Calculator Web App

Using HTML5, CSS and JavaScript

Creating a calculator app is a fantastic project for beginners looking to practice their web development skills. In this tutorial, I’ll guide you through the steps to build a calculator on the web.

Project Setup

First, create a new project directory on your local machine. Inside this directory, create the following files:

  • index.html (The structure in HTML)

  • styles.css (The styling in CSS)

  • app.js (The functionality in JS)

HTML Structure:

Now, let’s build the HTML structure of our calculator. Open index.html and add the following code in your local preferred ide (VS code or ATOM):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"> <!-- The web standard for character encoding -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Ensures responsive design for various devices -->
    <title>Calculator</title> <!-- For browsers and search engines -->
    <link rel="stylesheet" href="styles.css"> <!-- Links your CSS styles file -->
</head>
<body>
    <div class="calculator"> <!-- Parent container element -->
        <input type="text" class="display" id="display" disabled /> <!-- Input for current number display -->
        <input type="text" id="equationDisplay" disabled /> <!-- Input for showing the equation -->

        <div class="buttons"> <!-- Child container element for buttons -->
            <button class="btn">1</button>
            <button class="btn">2</button>
            <button class="btn">3</button>
            <button class="btn">C</button>
            <button class="btn">4</button>
            <button class="btn">5</button>
            <button class="btn">6</button>
            <button class="btn">-</button>
            <button class="btn">7</button>
            <button class="btn">8</button>
            <button class="btn">9</button>
            <button class="btn">+</button>
            <button class="btn">=</button>
            <button class="btn">0</button>
            <button class="btn">*</button>
            <button class="btn">/</button>
        </div>
    </div>
    <script src="app.js"></script> <!-- Link for the functionality file -->
</body>
</html>

Styling with CSS

Next, let’s add some styles to make our calculator look nice. Open styles.css and add the following code:

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: #f0f0f0;
}

.calculator {
    background-color: #bebebe;
    border-radius: 10px;
    width: 300px;
    padding: 20px;
}

.display {
    width: 100%;
    height: 50px;
    font-size: 24px;
    text-align: center;
    border: none;
    margin-bottom: 10px;
    border-radius: 5px;
    background-color: #f9f9f9;
}

.buttons {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
}

.btn {
    padding: 20px;
    font-size: 18px;
    border: none;
    border-radius: 5px;
    background-color: #141c24;
    color: rgb(255, 255, 255);
    cursor: pointer;
    transition: background-color 0.3s;
}

.btn:hover {
    background-color: #25394f;
}

#equationDisplay {
    margin-bottom: 10px;
}

JavaScript Functionality

Now, let’s add some functionality to our calculator. Open app.js and add the following code: (This is streamlined and not following OOP best practices).

class Calculator {
    constructor(buttonsSelector, displaySelector, equationDisplaySelector) {
        // Select buttons and display elements
        this.buttons = document.querySelectorAll(buttonsSelector);
        this.display = document.getElementById(displaySelector);
        this.equationDisplay = document.getElementById(equationDisplaySelector);

        // Initialize variables
        this.currentInput = '';
        this.operator = '';
        this.firstOperand = null;
        this.equation = '';
        this.answerDisplayed = false; // Track if the answer has been displayed

        // Bind event listeners
        this.addEventListeners();
    }

    addEventListeners() {
        this.buttons.forEach(button => {
            button.addEventListener('click', () => this.handleButtonClick(button.textContent));
        });

        document.addEventListener('keydown', (event) => this.handleKeyboardInput(event.key));
    }

    handleButtonClick(value) {
        if (value === 'C') {
            this.clear();
        } else if (value === '=') {
            this.calculate();
        } else {
            this.appendValue(value);
        }
    }

    handleKeyboardInput(key) {
        if (key >= '0' && key <= '9' || ['+', '-', '*', '/'].includes(key)) {
            this.appendValue(key);
        } else if (key === 'Enter' || key === '=') {
            this.calculate();
        } else if (key.toLowerCase() === 'c') {
            this.clear();
        }
    }

    appendValue(value) {
        // Clear previous answer if a new button is pressed
        if (this.answerDisplayed) {
            this.clear(); // Clear the calculator state
        }

        if (['+', '-', '*', '/'].includes(value)) {
            if (this.currentInput) {
                this.firstOperand = parseFloat(this.currentInput);
                this.operator = value;
                this.equation += `${this.currentInput} ${this.operator} `;
                this.currentInput = '';
            }
        } else {
            if (value === '.' && this.currentInput.includes('.')) return; // Prevent multiple decimal points
            this.currentInput += value; // Append number
        }
        this.updateDisplay();
    }

    calculate() {
        if (this.firstOperand !== null && this.operator && this.currentInput) {
            const secondOperand = parseFloat(this.currentInput);
            let result;

            // Perform calculation
            switch (this.operator) {
                case '+':
                    result = this.firstOperand + secondOperand;
                    break;
                case '-':
                    result = this.firstOperand - secondOperand;
                    break;
                case '*':
                    result = this.firstOperand * secondOperand;
                    break;
                case '/':
                    if (secondOperand === 0) {
                        alert("Error: Division by zero");
                        return; // Prevent further calculations
                    }
                    result = this.firstOperand / secondOperand;
                    break;
                default:
                    return;
            }

            this.currentInput = result.toString();
            this.equation += `${secondOperand} = ${this.currentInput} `;
            this.updateDisplay();
            this.operator = ''; // Reset operator for next calculation
            this.firstOperand = null; // Reset first operand for new calculation
            this.answerDisplayed = true; // Set flag indicating the answer is displayed
        }
    }

    clear() {
        this.currentInput = '';
        this.operator = '';
        this.firstOperand = null;
        this.equation = '';
        this.answerDisplayed = false; // Reset the answer displayed flag
        this.updateDisplay();
    }

    updateDisplay() {
        this.display.value = this.currentInput || '0';
        this.equationDisplay.value = this.equation; // Update equation display
    }
}

// Initialize the calculator
const calculator = new Calculator('.btn', 'display', 'equationDisplay');

End Result:

Here is a flowchart created using “Mermaid” syntax that illustrates the flow of the calculator program.


Conclusion

This web app is a simple calculator that allows users to perform calculations using their keyboard and on-screen buttons. The answer clears automatically when a new number is entered after a calculation answer is shown.

Happy Coding!