Javascript Calculator with multiple example
JavaScript Calculator
This JavaScript calculator is a versatile web-based application designed for performing arithmetic calculations. With its user-friendly interface and efficient handling of user input, it allows users to perform calculations quickly and accurately.
Key Features:
Basic Arithmetic Operations:
- This calculator supports fundamental operations like addition (
+
), subtraction (-
), multiplication (*
), division (/
), and percentage (%
).
- This calculator supports fundamental operations like addition (
All Clear Functionality:
- The "AC" (All Clear) button let a user resets the calculator, clearing all input and setting the display back to zero. This features helps a user for starting fresh calculation.
Erase Functionality:
- The "C"(erase) button allows users to delete the last character entered from right .
- This feature helps a user in correcting mistakes without needing to clear the entire input.
Dynamic Input Handling:
- The calculator displays the current input string in real-time, allowing users to see their ongoing calculations.
- It prevents multiple leading zeros and avoids adding multiple operators consecutively, ensuring valid mathematical expressions.
Result Display Control:
- After pressing the equals button (
=
), the calculator evaluates the current expression and displays the result. - If the equals button is pressed without a valid operation or if the last character is an operator, the display remains unchanged or is cleared.
- After pressing the equals button (
Percentage Calculation:
- The calculator can convert the current input to a percentage when the ("%") button is pressed, making it convenient for financial calculations.
Error Handling:
- The calculator handles errors by catching invalid expressions (e.g., division by zero) and resetting the display.
- In cases of invalid input, the display is cleared to avoid confusion.
Responsive Design:
- The calculator is styled using CSS to provide an aesthetically pleasing and modern interface.
- It is responsive and adapts to different screen sizes, ensuring usability on both desktop and mobile devices.
How It Works:
- Input: Users can input numbers and select operations using the buttons on the calculator interface.
- Calculation: Pressing the equals button (
=
) evaluates the input expression using the( "eval")
function and updates the display with the result. - Clear and Erase: Users can reset or erase their input as needed, allowing for flexible and dynamic calculations.
- Continued Operations: After obtaining a result, users can continue to perform calculations by entering a new number or operation, maintaining the flow of their calculations.
Example 01:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container flex flex-col item-center">
<div class="row">
<!-- <input type="text" class="input-text" readonly placeholder="0"> -->
<div id="output_are">0</div>
</div>
<div class="row">
<button class="button operation" value="ac">AC</button>
<button class="button operation" value="%">%</button>
<button class="button operation" value="/">/</button>
<button class="button operation" value="er">
<svg pointer-events="none" class="erase_icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="#ffffff" d="M576 128c0-35.3-28.7-64-64-64L205.3 64c-17 0-33.3 6.7-45.3 18.7L9.4 233.4c-6 6-9.4 14.1-9.4 22.6s3.4 16.6 9.4 22.6L160 429.3c12 12 28.3 18.7 45.3 18.7L512 448c35.3 0 64-28.7 64-64l0-256zM271 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"/></svg>
</button>
</div>
<div class="row">
<button class="button" value="7">7</button>
<button class="button" value="8">8</button>
<button class="button" value="9">9</button>
<button class="button operation" value="*">x</button>
</div>
<div class="row">
<button class="button" value="4">4</button>
<button class="button" value="5">5</button>
<button class="button" value="6">6</button>
<button class="button operation" value="+">+</button>
</div>
<div class="row">
<button class="button" value="1">1</button>
<button class="button" value="2">2</button>
<button class="button" value="3">3</button>
<button class="button operation" value="-">-</button>
</div>
<div class="row">
<button class="button" value="0">0</button>
<button class="button" value="00">00</button>
<button class="button" value=".">.</button>
<button class="button equal" value="=">=</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
:root {
--background-color: #1e1e2f;
/* Dark background for the container */
--container-background: #2d2d44;
/* Darker background for the container */
--button-background: #4b4b6d;
/* Dark gray for buttons */
--button-hover-background: #666688;
/* Lighter gray for buttons on hover */
--operation-background: #ff6f61;
/* Coral for operations */
--operation-hover-background: #e95e50;
/* Darker coral on hover */
--equal-background: #00b894;
/* Teal for equal button */
--equal-hover-background: #009b77;
/* Darker teal on hover */
--input-background: #3a3b3c;
/* Darker input field */
--text-color: #ffffff;
/* White text for contrast */
}
html,
body {
height: 100%;
width: 100%;
font-family: 'Poppins', sans-serif;
display: flex;
justify-content: center;
align-items: center;
}
.container {
background-color: var(--container-background);
padding: 20px;
border-radius: 20px;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
width: 310px;
max-width: 100%;
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.button {
width: 60px;
/* padding: 18px; */
margin: 0 5px;
border: none;
border-radius: 50%;
cursor: pointer;
font-size: 18px;
background: linear-gradient(145deg, #3f3f5c, #1e1e2f);
color: var(--text-color);
transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5), inset 2px 2px 5px rgba(0, 0, 0, 0.3);
height: 60px;
line-height: 59px;
}
.erase_icon {
width: 20px;
}
.button:hover {
background: linear-gradient(145deg, #2b2b42, #4b4b6d);
transform: scale(1.1);
box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2);
}
.button:active {
transform: scale(0.95);
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
}
.row {
margin: 10px 0;
display: flex;
justify-content: space-between;
}
div#output_are {
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5);
min-height: 30px;
padding: 10px;
text-wrap: wrap;
width: 100%;
word-break: break-all;
border-radius: 20px;
border: none;
outline: none;
color: #fff;
text-align: right;
letter-spacing: 1px;
font-size: 17px;
line-height: 22px;
}
.button.operation {
background: linear-gradient(145deg, #ff7f7f, #ff6f61);
}
.button.operation:hover {
background: linear-gradient(145deg, #e95e50, #ff6f61);
transform: scale(1.1);
}
.button.equal {
background: linear-gradient(145deg, #00b894, #00a78e);
}
.button.equal:hover {
background: linear-gradient(145deg, #009b77, #00b894);
transform: scale(1.1);
}
let string = "";
let resultDisplayed = false;
let buttons = document.querySelectorAll('.button');
Array.from(buttons).forEach((button) => {
button.addEventListener('click', (e) => {
const inputField = document.querySelector('#output_are');
// Define a regex to match operator buttons
const operators = /[/*\-+%=]/;
switch (e.target.getAttribute('value')) {
case '=':
console.log(e.target.getAttribute('value'));
// Check if string has a valid expression
if (string && !operators.test(string.slice(-1))) {
try {
string = eval(string).toString();
inputField.innerHTML = string;
resultDisplayed = true;
} catch (error) {
string = "";
inputField.innerHTML = "";
}
} else {
inputField.innerHTML = "";
}
break;
case 'ac':
string = "";
inputField.innerHTML = string;
resultDisplayed = false;
break;
case 'er':
console.log("aa");
string = string.slice(0, -1);
inputField.innerHTML = string;
break;
default:
// Continue the operation if an operator is pressed after result is displayed
if (resultDisplayed && operators.test(e.target.getAttribute('value'))) {
resultDisplayed = false;
}
// Start fresh if a number is entered after the result is displayed
if (resultDisplayed && !operators.test(e.target.getAttribute('value'))) {
string = "";
resultDisplayed = false;
}
// Prevent multiple leading zeros
if (e.target.getAttribute('value') === '0' || e.target.getAttribute('value') === '00') {
if (string === "" || string === "0") {
// If string is empty or already '0', don't append more zeros
string = "";
} else {
string += e.target.getAttribute('value');
}
} else if (e.target.getAttribute('value') === '%') {
if (string && !operators.test(string.slice(-1))) {
// Convert the current number to percentage
try {
string = (eval(string) / 100).toString();
inputField.innerHTML = string;
resultDisplayed = true;
} catch (error) {
string = "";
inputField.innerHTML = "";
}
}
} else if (operators.test(e.target.getAttribute('value'))) {
// Allow operator if the string is not empty and the last character is not an operator
if (string && !operators.test(string.slice(-1))) {
string += e.target.getAttribute('value');
}
} else {
string += e.target.getAttribute('value');
}
inputField.innerHTML = string;
break;
}
});
});
Example 02:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container flex flex-col item-center">
<div class="row">
<!-- <input type="text" class="input-text" readonly placeholder="0"> -->
<div id="output_are">0</div>
</div>
<div class="row">
<button class="button operation" value="ac">AC</button>
<button class="button operation" value="%">%</button>
<button class="button operation" value="/">/</button>
<button class="button operation" value="er">
<svg pointer-events="none" class="erase_icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M576 128c0-35.3-28.7-64-64-64L205.3 64c-17 0-33.3 6.7-45.3 18.7L9.4 233.4c-6 6-9.4 14.1-9.4 22.6s3.4 16.6 9.4 22.6L160 429.3c12 12 28.3 18.7 45.3 18.7L512 448c35.3 0 64-28.7 64-64l0-256zM271 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"/></svg>
</button>
</div>
<div class="row">
<button class="button" value="7">7</button>
<button class="button" value="8">8</button>
<button class="button" value="9">9</button>
<button class="button operation" value="*">x</button>
</div>
<div class="row">
<button class="button" value="4">4</button>
<button class="button" value="5">5</button>
<button class="button" value="6">6</button>
<button class="button operation" value="+">+</button>
</div>
<div class="row">
<button class="button" value="1">1</button>
<button class="button" value="2">2</button>
<button class="button" value="3">3</button>
<button class="button operation" value="-">-</button>
</div>
<div class="row">
<button class="button" value="0">0</button>
<button class="button" value="00">00</button>
<button class="button" value=".">.</button>
<button class="button equal" value="=">=</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
:root {
--background-color: #e0e0e0;
/* Light gray background for the entire page */
--container-background: #ffffff;
/* White for the container */
--button-background: rgb(207, 216, 220);
/* Light gray for buttons */
--button-hover: rgb(176, 190, 197);
/* Slightly darker gray on hover */
--operation-background: rgb(144, 164, 174);
/* Gray for operations */
--operation-hover: #78909c;
/* Darker gray on hover */
--equal-background: #4caf50;
/* Green for equal button */
--equal-hover: #388e3c;
/* Darker green on hover */
--input-background: #ffffff;
/* White for input field */
--text-color: #000000;
/* Black text for contrast */
--shadow-color: rgba(0, 0, 0, 0.3);
/* Shadow color for depth */
}
html,
body {
height: 100%;
width: 100%;
font-family: 'Poppins', sans-serif;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--background-color);
}
.container {
background-color: var(--container-background);
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 20px var(--shadow-color);
border: 1px solid #bbb;
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.erase_icon {
width: 23px;
}
.button {
width: 60px;
padding: 15px;
margin: 8px;
border: none;
border-radius: 30px;
cursor: pointer;
font-size: 18px;
background: var(--button-background);
color: var(--text-color);
transition: background-color 0.2s ease, transform 0.1s ease;
box-shadow: 0 4px 10px var(--shadow-color);
}
.button:hover {
background: var(--button-hover);
transform: translateY(-2px);
}
.button:active {
transform: translateY(1px);
}
.row {
margin: 10px 0;
display: flex;
justify-content: space-between;
}
div#output_are {
min-height: 45px;
width: 100%;
font-size: 22px;
padding: 10px;
text-wrap: wrap;
word-break: break-all;
border: none;
outline: none;
border-radius: 10px;
line-height: 22px;
letter-spacing: 1px;
text-align: right;
box-sizing: border-box;
background-color: var(--input-background);
color: var(--text-color);
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.2);
}
.button.operation {
background: var(--operation-background);
}
.button.operation:hover {
background: var(--operation-hover);
}
.button.equal {
background: var(--equal-background);
font-weight: bold;
}
.button.equal:hover {
background: var(--equal-hover);
}
let string = "";
let resultDisplayed = false;
let buttons = document.querySelectorAll('.button');
Array.from(buttons).forEach((button) => {
button.addEventListener('click', (e) => {
const inputField = document.querySelector('#output_are');
// Define a regex to match operator buttons
const operators = /[/*\-+%=]/;
switch (e.target.getAttribute('value')) {
case '=':
console.log(e.target.getAttribute('value'));
// Check if string has a valid expression
if (string && !operators.test(string.slice(-1))) {
try {
string = eval(string).toString();
inputField.innerHTML = string;
resultDisplayed = true;
} catch (error) {
string = "";
inputField.innerHTML = "";
}
} else {
inputField.innerHTML = "";
}
break;
case 'ac':
string = "";
inputField.innerHTML = string;
resultDisplayed = false;
break;
case 'er':
console.log("aa");
string = string.slice(0, -1);
inputField.innerHTML = string;
break;
default:
// Continue the operation if an operator is pressed after result is displayed
if (resultDisplayed && operators.test(e.target.getAttribute('value'))) {
resultDisplayed = false;
}
// Start fresh if a number is entered after the result is displayed
if (resultDisplayed && !operators.test(e.target.getAttribute('value'))) {
string = "";
resultDisplayed = false;
}
// Prevent multiple leading zeros
if (e.target.getAttribute('value') === '0' || e.target.getAttribute('value') === '00') {
if (string === "" || string === "0") {
// If string is empty or already '0', don't append more zeros
string = "";
} else {
string += e.target.getAttribute('value');
}
} else if (e.target.getAttribute('value') === '%') {
if (string && !operators.test(string.slice(-1))) {
// Convert the current number to percentage
try {
string = (eval(string) / 100).toString();
inputField.innerHTML = string;
resultDisplayed = true;
} catch (error) {
string = "";
inputField.innerHTML = "";
}
}
} else if (operators.test(e.target.getAttribute('value'))) {
// Allow operator if the string is not empty and the last character is not an operator
if (string && !operators.test(string.slice(-1))) {
string += e.target.getAttribute('value');
}
} else {
string += e.target.getAttribute('value');
}
inputField.innerHTML = string;
break;
}
});
});