Presumably you will want to use this in a form. If you're targeting modern browsers, the input field supports the pattern attribute which adds an extra layer of pattern enforcement (in case JavaScript is disabled).
If you're considering the best user experience, you'll also want to anticipate less common use cases. For example: if the user selects one of the digits and types another one, they are indicating they are replacing the selected digit with the new one.
The following code takes all of this into consideration:
<form> <input id="only_max_two_digits" type="text" pattern="^\d{1,2}$" /> <input type="submit" /> </form> <script type="text/javascript"> function remove_substr(s, src, dst) { return s.substr(0, src) + s.substr(dst); } document .querySelector("#only_max_two_digits") .addEventListener("keypress", (e) => { const { value, pattern, selectionStart, selectionEnd } = e.target; const next = remove_substr(value, selectionStart, selectionEnd) + e.key; if (!new RegExp(pattern).test(next)) { e.preventDefault(); } }); </script>
The function remove_substr removes a substring from a string between two given numerical bounds. In this case, we're using it to remove the selected text, because we know where the selection begins and ends.
The event listener:
- It is triggered by the
keypress event, meaning when the key is down, but the <input>'s value has not yet updated. - The
next variable contains the estimation of what the next value will be, by 1) removing the currently selected text (if any) and appending the value of the key that is being pressed. - If the value of the
next variable doesn't pass the Regex pattern test, <input> is prevented from updating.
Here's a working CodeSandbox example.
<input type="number" min="0" max="99">?