Maybe this jQuery Codepen snipet will be helpful for someone.
It's for type="number" (not "text"):
with [0-9] allowed inputs only. In the input will printed/pasted only numbers [0-9] with an min-max range (optional).
Some explanations: The code displays only numbers at the input stage, and does not reset the value to "" (empty) in case of inputting not valid number values like it does by default for type="number". And you can't use the attribute pattern="/^[0-9]*$/" for an input type="number".
var $inputAbsint = $('.js-input-absint');
if ($inputAbsint.length) {
$(document).on('keypress', '.js-input-absint', function (event) {
var allowed = /^[0-9]|Arrow(Left|Right)|Backspace|Home|End|Delete$/;
return allowed.test(event.key);
}).on('focusout paste', '.js-input-absint', function () {
var $input = $(this);
var defaultValue = this.defaultValue || $input.attr('min');
// Important(!): Timeout for the updated value
setTimeout(function () {
var current = $input.val();
var regexNumbers = new RegExp(/^[0-9]*$/, 'g');
var isNumbersOnly = regexNumbers.test(current);
// Clear wrong value (not numbers)
if ((current === '' || !isNumbersOnly) && defaultValue.length) {
$input.val(defaultValue);
current = defaultValue;
}
// Min/Max
var min = parseInt($input.attr('min'), 10);
var max = parseInt($input.attr('max'), 10);
var currentInt = parseInt(current, 10);
if (!isNaN(min) && !isNaN(currentInt) && currentInt < min) {
$input.val(min);
}
if (!isNaN(max) && !isNaN(currentInt) && currentInt > max) {
$input.val(max);
}
}, 100);
});
}