The addEventListener
passes only the event that triggered it to the passed callback so in your case txt
is holding the event and evt
is undefined.
You can extract the txt
value of the input by using evt.target.value
.
document.getElementById("dzCalculator").addEventListener("keydown", isNumberKey);
function isNumberKey(evt) {
let txt = evt.target.value;
//...
As for the rest of your logic, there are some good answers already available:
HTML text input allow only numeric input
Since you are still looking for a solution to limit input I will offer this. Instead of controlling the keys allowed, you can validate the value after keyup. Using an input
listener we can watch for changes and validate without seeing invalid characters show while also solving the overarching problem of maintaining expected functionality and accessibility without having to specify all key responses.
This snippet listens for changes using input
. When triggered it extracts the current value using event.target.value
and stores the current cursor position. It then recasts the string to an array using destructuring [...value]
. This array is then filtered using filter()
so that it only contains characters that appear in the validKeys
string. It is then reduced back to a string using reduce()
at which time it accounts for duplicate decimal points. If the resulting editedValue
is different than the initial value
the evt.target.value
is updated and the cursor is set back to where it was (minus one because we have removed a character);
document.getElementById("dzCalculator").addEventListener("input", isNumberKey);
function isNumberKey(evt) {
const validKeys = '1234567890.';
const cursorLocation = evt.target.selectionStart;
const value = evt.target.value;
let editedValue = [...value]
.filter(char => validKeys.includes(char))
.reduce((acc, char) => { return acc.includes('.') && char === '.' ? acc : acc + char}, '');
if (editedValue !== value) {
evt.target.value = editedValue;
evt.target.selectionStart = cursorLocation-1;
evt.target.selectionEnd = cursorLocation-1;
}
}
<input id="dzCalculator" value="" />
To accomodate negative values you can adjust validKeys
and the reduce()
callback thus:
const validKeys = '-1234567890.';
let editedValue = [...value]
.filter(char => validKeys.includes(char))
.reduce((acc, char, i) => {
if (acc.includes('.') && char === '.' || char === '-' && i !== 0) {
return acc
} else {
return acc + char
}
}, '');