Я бы сделал это с помощью обработчика события keydown и отдельного для переформатирования, чтобы упростить его.Регулярное выражение /^([fF]{1}|\d{1}\.\d{1}|10\.00?)$/
на regex101.com показывает, как оно работает .Выражение allNumbersRe
просто ищет правильный шаблон для трех чисел.
Хитрость в том, что нет способа помешать им ввести значение> 10,0, если вы хотите, чтобы они могли разрешить имвведите 100 и отформатируйте его как 10.0, так как число 100> 10.0.Итак, я разделил форматирование из обработчика keydown
и добавил обработчик blur
для выполнения форматирования.Это также подтверждает, что форматированное число меньше или равно 10.0.Здесь я использую проверку HTML5-ограничения для простоты реализации.
Еще одно замечание, что я использую KeyboardEvent.key
, что является относительно новымдополнение к стандарту.Он вернет строки, такие как «Delete» и «Backspace» для ключей, которые выдают непечатные символы.В этом случае я предполагаю, что любые ключи, которые делают это, разрешают (вы, вероятно, хотите иметь возможность удалить значение).
document.querySelector('.grade').addEventListener('keydown', function (e) {
const char = e.key;
let newValue = e.target.value;
if (char.length > 1) {
return true;
} else {
newValue += char;
}
const perfectRegex = /^([fF]{1}|\d{1}\.\d{1,2}|10\.00?)$/;
const allNumbersRe = /^(\d{1})(\d{1,2})$/;
const numbersAndDecRe = /^[\d\.]{1,4}$/;
if (!perfectRegex.test(newValue) &&
!allNumbersRe.test(newValue) &&
!numbersAndDecRe.test(newValue) &&
newValue.length > 0) {
e.preventDefault();
}
});
document.querySelector('.grade').addEventListener('blur', function (e) {
const tenRe = /^100$/;
const allNumbersRe = /^(\d{1})(\d{1,2})$/;
const newValue = e.target.value;
e.target.setCustomValidity("");
if (tenRe.test(newValue)) {
e.target.value = "10.0";
} else if (allNumbersRe.test(newValue)) {
e.target.value = newValue.replace(allNumbersRe, "$1.$2");
}
if (parseFloat(e.target.value) > 10.0) {
e.target.setCustomValidity("The value cannot be more than 10.0");
e.preventDefault();
}
});
input:invalid { border-color: red; }
<input type="text" class="grade" maxlength="4">