Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preview the result of a beforeinput event?

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 come 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?

like image 314
DoctorDestructo Avatar asked Dec 18 '25 02:12

DoctorDestructo


1 Answers

You'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">
like image 83
dave Avatar answered Dec 20 '25 14:12

dave



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!