Я пытаюсь проверить десятичное число из 13 цифр до и 4 цифр после десятичного числа при нажатии клавиши, исключая запятую, т.е. запятая не должна считаться цифрой.
Действительные случаи
1,234,567,890,123.1234
1234567890123.1234
123456789012.1234
1234567890123.123
12345.123
1.2
0
В действительных случаях
12345abc.23 // string or special characters not allowed
1,234,567,890,1231.1234
1,234,567,890,123.12341
12345678901231.1234
1234567890123.12341
Текущее регулярное выражение
^[0-9]{0,13}.?[0-9]{0,4}$
Код
$("#Price").keydown(function (e) {
var userVal = $("#Price").val().replace(/,/g, ""); // remove commas
var validValue = userVal.search(/^[0-9]{0,13}.?[0-9]{0,4}$/) == 0 ? true : false;
if (userVal !== "" && !validValue && e.keyCode !== 46 && e.keyCode !== 8) {
e.preventDefault();
}
else {
return true;
}
});
Приведенный выше код regex
отлично работает в консоли браузера:
var userVal = "1234567890123.1234";
var validValue = userVal.search(/^[0-9]{0,13}.?[0-9]{0,4}$/) == 0 ? true : false;
console.info(validValue);
Но используя события keypress
, keydown
и keyup
, пользователь по-прежнему может ввести 1 дополнительную цифру до и после десятичного числа.
Как я могу запретить пользователю вводить недопустимые регистры?
@ Ян, спасибо, а можешь сказать, что это за персонажи?
В некоторых странах они перевернуты. Например в Германии это: 1.000.000,00€
@stom toLocaleString() и Международный ФорматЧисла могут помочь. Поэтому, если вы хотите поддерживать локализацию, ваш код должен настроить фильтры в зависимости от локали. Например, оператор switch с идентификаторами локалей в качестве случаев для использования регулярным выражением.
Поскольку keydown
запускается до, символ фактически вводится на входе. Посмотрите на эту скрипту, где я добавил выходные данные: https://jsfiddle.net/n56k0ve3/
<input id='price' type='text' value='0'></input>
<hr>
<span id='userVal'></span>
<br>
<span id='validValue'></span>
$("#price").keydown(function(e) {
var userVal = $(this).val().replace(/,/g, ""); // remove commas
var validValue = userVal.search(/^[0-9]{0,13}\.?[0-9]{0,4}$/) == 0 ? true : false;
$("#userVal").text(userVal);
$("#validValue").text(validValue);
if (userVal !== "" && !validValue && e.keyCode !== 46 && e.keyCode !== 8) {
e.preventDefault();
} else {
return true;
}
});
Вместо этого используйте событие, которое проверяет значение после его изменения. keyup
работает, но не срабатывает до тех пор, пока символ не отобразится во вводе, а также срабатывает без необходимости, например, на Shift или Ctrl. Вместо этого мы можем использовать событие input
. См. эту скрипку: https://jsfiddle.net/2b6pc1hu/
var prevVal = $("#price").val();
$("#price").on('input', function(e) {
var val = $(this).val();
var userVal = val.replace(/,/g, ""); // remove commas
var validValue = userVal.search(/^[0-9]{0,13}\.?[0-9]{0,4}$/) == 0 ? true : false;
$("#userVal").text(userVal);
$("#validValue").text(validValue);
if (userVal !== "" && !validValue && e.keyCode !== 46 && e.keyCode !== 8) {
$(this).val(prevVal);
} else {
prevVal = val;
}
});
Кроме того, в регулярных выражениях .
является подстановочным знаком. Этого следует экранировать, если вы хотите, чтобы он потреблял только точку/десятичное число.
Блестящий ответ. На самом деле я думал получить предыдущее значение и установить его, но не пробовал. Но это решило проблему. Ценить :)
Я бы предложил использовать событие «input», а не событие «keyup», поскольку keyup обнаруживает любую клавишу (даже если вы нажмете Shit, Ctrl или Alt, событие будет запущено). Событие «input» срабатывает только тогда, когда значение элемента фактически изменяется нажатием клавиши.
Просто примечание: в некоторых странах в качестве десятичного разделителя используются разные символы.