-
Notifications
You must be signed in to change notification settings - Fork 183
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #416 from thevijayshankersharma/Calculator-extension
Fix calculator extension: UI enhancements and calculation errors reso…
- Loading branch information
Showing
5 changed files
with
244 additions
and
97 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,168 @@ | ||
let output = document.getElementById('output'); | ||
const output = document.getElementById('output'); | ||
|
||
// Define references to buttons | ||
const buttons = { | ||
clear: document.getElementById('clear'), | ||
delete: document.getElementById('delete'), | ||
percentage: document.getElementById('percentage'), | ||
divide: document.getElementById('divide'), | ||
seven: document.getElementById('seven'), | ||
eight: document.getElementById('eight'), | ||
nine: document.getElementById('nine'), | ||
add: document.getElementById('add'), | ||
four: document.getElementById('four'), | ||
five: document.getElementById('five'), | ||
six: document.getElementById('six'), | ||
subtract: document.getElementById('subtract'), | ||
one: document.getElementById('one'), | ||
two: document.getElementById('two'), | ||
three: document.getElementById('three'), | ||
multiply: document.getElementById('multiply'), | ||
zero: document.getElementById('zero'), | ||
doubleZero: document.getElementById('double-zero'), | ||
equals: document.getElementById('equals'), | ||
}; | ||
|
||
// Add event listeners to the buttons | ||
Object.values(buttons).forEach(button => { | ||
button.addEventListener('click', handleClick); | ||
}); | ||
|
||
// Function to handle button clicks | ||
function handleClick(event) { | ||
const buttonValue = event.target.textContent; | ||
switch (buttonValue) { | ||
case 'C': | ||
Clear(); | ||
break; | ||
case 'DEL': | ||
del(); | ||
break; | ||
case '%': | ||
case '/': | ||
case '*': | ||
case '-': | ||
case '+': | ||
display(` ${buttonValue} `); | ||
break; | ||
case '=': | ||
calculate(); | ||
break; | ||
default: | ||
display(buttonValue); | ||
break; | ||
} | ||
} | ||
|
||
// Function to display numbers and operators | ||
function display(num) { | ||
output.value += num; | ||
} | ||
|
||
// Function to calculate the expression | ||
function calculate() { | ||
const expression = output.value.trim(); // Trim whitespace | ||
if (!isValidExpression(expression)) { | ||
output.value = "Invalid expression"; | ||
return; | ||
} | ||
|
||
try { | ||
output.value = eval(output.value); | ||
const result = evaluateExpression(expression); | ||
output.value = result; | ||
} catch (err) { | ||
output.value = "Invalid expression"; | ||
} | ||
catch (err) { | ||
alert('Invalid'); | ||
} | ||
|
||
// Function to check if the expression contains only valid characters and ends with a digit | ||
function isValidExpression(expression) { | ||
// Regular expression to match valid characters: digits, operators (+, -, *, /, %), and whitespace | ||
const validCharactersRegex = /^[0-9+\-*/%\s.]+$/; | ||
|
||
// Check if the expression ends with a digit | ||
const endsWithDigit = /\d$/.test(expression); | ||
|
||
// Split the expression into tokens | ||
const tokens = expression.trim().split(/\s+/); | ||
|
||
// Check for consecutive operators | ||
for (let i = 0; i < tokens.length - 1; i++) { | ||
if (tokens[i].match(/[+\-*/%]/) && tokens[i + 1].match(/[+\-*/%]/)) { | ||
return false; // Consecutive operators found, invalid expression | ||
} | ||
} | ||
|
||
return validCharactersRegex.test(expression) && endsWithDigit; | ||
} | ||
|
||
|
||
// Function to evaluate the expression without using eval() | ||
function evaluateExpression(expression) { | ||
const tokens = expression.split(/\s+/); // Split expression by whitespace | ||
const stack = []; | ||
|
||
let currentOperator = '+'; | ||
|
||
for (let token of tokens) { | ||
if (!isNaN(token)) { | ||
const number = parseFloat(token); | ||
switch (currentOperator) { | ||
case '+': | ||
stack.push(number); | ||
break; | ||
case '-': | ||
stack.push(-number); | ||
break; | ||
case '*': | ||
stack.push(stack.pop() * number); | ||
break; | ||
case '/': | ||
stack.push(stack.pop() / number); | ||
break; | ||
case '%': | ||
stack.push(stack.pop() % number); | ||
break; | ||
} | ||
} else { | ||
currentOperator = token; | ||
} | ||
} | ||
|
||
return stack.reduce((acc, num) => acc + num, 0); | ||
} | ||
|
||
// Function to clear the input | ||
function Clear() { | ||
output.value = ""; | ||
} | ||
|
||
// Function to delete the last character | ||
function del() { | ||
output.value = output.value.slice(0, -1); | ||
} | ||
|
||
document.addEventListener('keypress', (e) => { | ||
if (e.key == 'Enter') { | ||
calculate(); | ||
} | ||
}); | ||
|
||
// Event listener for keyboard input | ||
document.addEventListener('keydown', (e) => { | ||
if(e.key == 'numbers') { | ||
display(num); | ||
const key = e.key; | ||
if (key >= '0' && key <= '9') { | ||
display(key); // Display the numeric key | ||
} else if (['+', '-', '*', '/', '%'].includes(key)) { | ||
display(' ' + key + ' '); // Display operators with spaces around them | ||
} else if (key === 'Enter') { | ||
e.preventDefault(); // Prevent the default action of Enter key (usually form submission) | ||
calculate(); // Calculate when Enter key is pressed | ||
} else if (key === 'Delete') { | ||
Clear(); // Clear the input when Delete key is pressed | ||
} else if (key === 'Backspace') { | ||
del(); // Delete the last character when Backspace key is pressed | ||
} | ||
}); | ||
|
||
// Event listener for Delete key | ||
document.addEventListener('keydown', (e) => { | ||
if (e.key == 'Delete') { | ||
if (e.key === 'Delete') { | ||
Clear(); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,82 @@ | ||
body{ | ||
background-color: aliceblue; | ||
body { | ||
background-color: #f0f4f8; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
margin: 0; | ||
font-family: 'Roboto', sans-serif; | ||
} | ||
*{ | ||
margin:0; | ||
padding:0; | ||
box-sizing:border-box; | ||
background-color: #ecf0f3; | ||
font-family: sans-serif; | ||
outline:none; | ||
|
||
.container { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
/* width: 100%; */ | ||
width: 400px; | ||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||
border-radius: 20px; | ||
overflow: hidden; | ||
} | ||
.container{ | ||
height:100vh; | ||
display:flex; | ||
justify-content:center; | ||
align-items:center; | ||
|
||
.calci { | ||
width: 100%; | ||
background-color: #fff; | ||
padding: 20px; | ||
border-radius: 20px; | ||
} | ||
.calci{ | ||
padding:15px; | ||
border-radius:30px; | ||
display:grid; | ||
grid-template-columns: repeat(4,68px); | ||
box-shadow: inset 5px 5px 12px #ffffff, | ||
5px 5px 12px rgba(0,0,0,.16); | ||
|
||
input#output { | ||
width: 100%; | ||
height: 60px; | ||
border: none; | ||
border-radius: 10px; | ||
margin-bottom: 20px; | ||
text-align: right; | ||
padding: 10px 3px; | ||
font-size: 2rem; | ||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); | ||
background-color: #e9eef2; | ||
color: #333; | ||
} | ||
input{ | ||
grid-column:span 4 ; | ||
height:60px; | ||
width:250px; | ||
background-color: #ecf0f3; | ||
box-shadow: inset -5px -5px 12px #ffffff, | ||
5px 5px 12px rgba(0,0,0,.16); | ||
border:none; | ||
border-radius:30px; | ||
font-size: 50px; | ||
text-align: end; | ||
margin:auto; | ||
margin-top:40px; | ||
margin-bottom:30px; | ||
padding:20px; | ||
color:rgba(70,70,70); | ||
|
||
.buttons { | ||
display: grid; | ||
grid-template-columns: repeat(4, 1fr); | ||
gap: 10px; | ||
} | ||
input:hover{ | ||
background-color: aqua; | ||
|
||
button { | ||
height: 60px; | ||
border: none; | ||
border-radius: 10px; | ||
font-size: 1.5rem; | ||
transition: all 0.2s ease; | ||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
background-color: #e9eef2; | ||
color: #333; | ||
cursor: pointer; | ||
} | ||
button{ | ||
height:48px; | ||
width:48px; | ||
background-color: #ecf0f3; | ||
box-shadow: inset -5px -5px 12px #ffffff, | ||
5px 5px 12px rgba(0,0,0,.16); | ||
border:none; | ||
border-radius:30px; | ||
margin:8px; | ||
font-size: 15px; | ||
|
||
button:active { | ||
transform: scale(0.95); | ||
} | ||
.equal{ | ||
width:115px; | ||
border-radius: 40px; | ||
background-color:#ecf0f3; | ||
box-shadow: inset -5px -5px 12px #ffffff, | ||
5px 5px 12px rgba(0,0,0,.16); | ||
|
||
button.function { | ||
background-color: #ffcc00; | ||
} | ||
button:hover{ | ||
background-color:aqua; | ||
|
||
button.operator { | ||
background-color: #4caf50; | ||
color: #fff; | ||
} | ||
|
||
button.equal { | ||
grid-column: span 2; | ||
background-color: #f44336; | ||
color: #fff; | ||
} | ||
|
||
button:hover { | ||
opacity: 0.9; | ||
} | ||
|