I've read several questions [1], [2], [3] regarding this topic, but none seems to provide a general solution to this problem. All answers seems to be directed to some specific cases.
I have this simple input field
<input type="number" id="inputBox" min="0" max="255" step="1" />
and I do a strict input validation on it:
inputBox.addEventListener("input", function () {
validateInput(this);
});
inputBox.addEventListener("keydown", function (e) {
validateInput(this, e);
});
function validateInput(elm, e) {
// handle keydown event
if (e) {
// do not allow floating-point numbers, if it's not expected
if (!isFloat(elm.step)) {
if (e.key == ".") {
e.preventDefault();
}
}
}
// handle input event
else {
// do not allow leading zeros
while (elm.value.length > 1 && elm.value[0] === "0") {
elm.value = elm.value.toString().slice(1);
}
// input should be between min and max
if (elm.validity.rangeUnderflow) {
elm.value = elm.min;
}
else if (elm.validity.rangeOverflow) {
elm.value = elm.max;
}
}
}
All this seems to be working fine for user input.
var inputBox = document.getElementById("inputBox");
inputBox.addEventListener("input", function() {
validateInput(this);
});
inputBox.addEventListener("keydown", function(e) {
validateInput(this, e);
});
function validateInput(elm, e) {
// handle keydown event
if (e) {
// do not allow floating-point numbers, if it's not expected
if (!isFloat(elm.step)) {
if (e.key == ".") {
e.preventDefault();
}
}
}
// handle input event
else {
// do not allow leading zeros
while (elm.value.length > 1 && elm.value[0] === "0") {
elm.value = elm.value.toString().slice(1);
}
// input should be between min and max
if (elm.validity.rangeUnderflow) {
elm.value = elm.min;
} else if (elm.validity.rangeOverflow) {
elm.value = elm.max;
}
}
}
function isFloat(f) {
var f = parseFloat(f);
var floor = Math.floor(f);
var fraction = f - floor;
if (fraction > 0) {
return true;
}
return false;
}
<input type="number" id="inputBox" min="0" max="255" step="1" />
But the user can still modify the input field value programmatically. The user can enter the following values through the console to bypass the validation and these are invalid/unexpected values:
inputBox.value = "005";
inputBox.value = "2.5"
inputBox.value = "-05.5";
An ideal solution to this would be to call a function (e.g. validateProgrammaticInput()
) if the user changes the field value using inputBox.value
.
inputBox.value = -10; // magically call validateProgrammaticInput()
Note: I'm not using a form. There's no submit button. This will not be sent to a server. This is a client application. Value should be validated in real-time. If I want to modify the field value programmatically, I can trigger a custom event in my code to validate the input, but that's not the case. What I want is to validate the input, if the user enters it programmatically. So my use case is irrelevant to the problem. Thought I should point these out before a confusion.