Does the beforeinput
event provide a convenient way to preview the result of a proposed modification so that it can be blocked if necessary for validation purposes?
I'm not looking for alternative ways to do input validation; I'm already well-aware of methods involving the keypress
and input
events, as well as HTML5 validation, etc.. Right now, I'm specifically looking into the beforeinput
event to see what it offers.
So far, this is the best I've e up with:
document.getElementById("phone").addEventListener("beforeinput", function(e) {
if(!/^(\d{0,7}|\d{3}-\d{0,4}|)$/.test(e.target.value + (e.data ?? ""))) {
e.preventDefault();
}
return;
});
<input id="phone">
Does the beforeinput
event provide a convenient way to preview the result of a proposed modification so that it can be blocked if necessary for validation purposes?
I'm not looking for alternative ways to do input validation; I'm already well-aware of methods involving the keypress
and input
events, as well as HTML5 validation, etc.. Right now, I'm specifically looking into the beforeinput
event to see what it offers.
So far, this is the best I've e up with:
document.getElementById("phone").addEventListener("beforeinput", function(e) {
if(!/^(\d{0,7}|\d{3}-\d{0,4}|)$/.test(e.target.value + (e.data ?? ""))) {
e.preventDefault();
}
return;
});
<input id="phone">
The text field in the above snippet should accept a simple 7-digit phone number with optional dash after the 3rd digit.
Notice that I'm appending the event's data
property to the input's current value to create a preview of the modified value. This works fine if you only enter input sequentially. But if, for example, you type in all 7 digits and then arrow back to just after the 3rd and try to insert the dash, you can't do it, because the validation assumes you're at the end where a dash would be invalid. Other problems arise if you try to replace or delete a selection.
An accurate preview will be required to solve these problems. Is there a simple way to get one from the beforeinput
event?
1 Answer
Reset to default 14You'd have to get the selectionStart
and selectionEnd
to figure out how many characters were removed / replaced / etc, but yeah, pretty simple:
document.getElementById("phone").addEventListener("beforeinput", function(e) {
const nextVal =
e.target.value.substring(0, e.target.selectionStart) +
(e.data ?? '') +
e.target.value.substring(e.target.selectionEnd)
;
console.log(nextVal)
if(!/^(\d{0,7}|\d{3}-?\d{0,4}|)$/.test(nextVal)) {
e.preventDefault();
}
return;
});
<input id="phone">