I want to add keyboard support to my calculator. When i press operations with keyboard (i.e. +,-,* or /) js sees it as number, not as operation.
For example, when I com
Give this a shot. It's not got any functionality for delete key or arrow keys, but it will perhaps help move you forward more.
<!DOCTYPE html>
<html>
<head>
</head>
<script>
var values
var dp
function checkCalcKey(key) {
switch (key) {
case '.':
document.getElementById('dot').click();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
case '/':
case '*':
case '=':
document.getElementById(key).click();
break;
}
return false;
// TODO handle any of 'ArrowLeft', 'ArrowRight', 'Delete','Backspace'. I'll leave this as an exercise for you to complete!
}
function hardReset() {
values = [];
opcode = null;
clear = true;
reset();
}
function reset() {
newNumber = false;
if (opcode === null) {
clearDisplay()
}
}
function clearDisplay() {
dp = 0;
nc = 0;
document.getElementById('display').value = '';
}
function getValue() {
var value;
var s = '' + document.getElementById('display').value;
if (s === '') {
value = 0;
} else if (s.indexOf('.') === -1) {
value = Number(s);
} else {
value = parseFloat(s);
}
return value;
}
function performMaths() {
m = values.pop();
v = values.pop();
switch (opcode) {
case '+':
v += m;
break;
case '-':
v -= m;
break;
case '*':
v *= m;
break;
case '/':
if ( m=== 0) {
v = NaN;
} else {
v /= m;
}
break;
}
values = [v,m];
document.getElementById('display').value = v;
}
function init() {
clear = true;
hardReset();
document.querySelectorAll(".number").forEach((b) => {
b.addEventListener('click', (e) =>
{
newNumber = true;
if (clear) {
clearDisplay();
clear = false;
}
nc++;
display=document.getElementById('display');
if (dp === 0) {
var value = (10 * Number(display.value)) + Number(e.target.textContent);
display.value = value;
} else {
var f = Number(e.target.textContent) / Math.pow(10,dp);
var value = parseFloat(display.value);
var value = f + value;
var sv = '' + value
sv = sv.substring(0,nc);
display.value = sv;
dp++;
}
});
});
document.getElementById('dot').addEventListener('click', () => {
newNumber = true;
if (dp === 0) {
dp++;
nc++;
}
});
document.getElementById('c').addEventListener('click', () => {
hardReset();
});
document.getElementById('ce').addEventListener('click', () => {
reset();
});
document.querySelectorAll(".operator").forEach((b) => {
b.addEventListener('click', (e) =>
{
clear = true;
if (e.target.textContent != opcode) {
opcode = e.target.textContent;
}
if (document.getElementById('display').value != '') {
if (values.length === 2) {
values.shift();
}
values.unshift(getValue());
}
newNumber = false;
});
});
document.getElementById('=').addEventListener('click', () => {
if (values.length === 2) {
if (newNumber) {
values.pop();
values.push(getValue());
}
} else {
values.push(getValue());
}
performMaths();
newNumber = false;
});
}
</script>
<body onload="init()">
<div class="main">
<div id="output">
<input id="display" value="" onkeydown="return checkCalcKey(event.key)">
</div>
<button id="ce">CE</button>
<button id="c">C</button>
<button id="0" class="number">0</button>
<button id="1" class="number">1</button>
<button id="2" class="number">2</button>
<button id="3" class="number">3</button>
<button id="4" class="number">4</button>
<button id="5" class="number">5</button>
<button id="6" class="number">6</button>
<button id="7" class="number">7</button>
<button id="8" class="number">8</button>
<button id="9" class="number">9</button>
<button id="/" class="operator">/</button>
<button id="*" class="operator">*</button>
<button id="-" class="operator">-</button>
<button id="+" class="operator">+</button>
<button id="=">=</button>
<button id="dot">.</button>
</div>
</body>
</html>
An explanation of the code:
The getValue routine does the bulk of fixing things up, and answers the key points in your original question:
If a variable is being interpreted as of type string it can mess up the computation. So you can convert a variable you don't know the type of to string by combining an empty string with the variable itself.
There is code to check for the existence of a decimal point, then use either parseFloat or Number to cast the type of the variable (parseInt is a more verbose alternative, needing radix of 10 - for a base 10 number).
A couple of other key variables are:
There is also some funky stuff going on, mimicking a normal calculator. So that when computation goes on, you can do something like enter:
So the last number you enter becomes like a 'sticky' constant in memory. Whenever a new value gets entered, that becomes the new 'sticky' value. So:
So: - the values array is used to store both the sticky value and the total:
+
, -
, /
, *
or =
is pressed. checkCalcKey() is an event handler for onkeydown upon the input HTML control's. By returning false
, it prevents the character you type from build input. Instead it defers to the click handler of the corresponding button and any character entry into the input control value property gets performed via that handler instead. (More info here).