Нужно валидировать input на лету, чтобы не давало вводить символ, если строка перестает соответствовать регулярному выражению.
В качестве примера возьму ввод месяца в формате «число и 3 символа месяца». В таком случае регулярка такая:
/^[\d]{1,2}[ ]{0,1}[а-я]{0,3}$/i
Если взять событие keydown и делать return false при несовпадении с регуляркой, то проверяется прошлое значение input-а. Если использовать keyup, то его уже не перехватить — return false не сработает.
Попробовал совместить и промежуточно запоминать строку при keydown и возвращать её, если после keyup строка не прошла проверку:
$strOld = '';
$reg = /^[\d]{1,2}[ ]{0,1}[а-я]{0,3}$/i;
$('.ok').on('keydown', function(e) {
$strOld = $(this).val();
});
$('.ok').on('keyup', function(e) {
$val = $(this).val();
$match = ($reg.test($val));
if (!$match)
{
$(this).val($strOld);
}
});
Но в таком случае можно нажать клавишу и держать. Проверка произойдет только в конце, на последнем символе.
Как решить такую проблему и сделать валидацию по регулярке на лету?
Для этого проверку стоит делать прямо в обработчике события keydown и проверять не только текущее значение input-а, но и вводимый символ. И, в зависимости от результата проверки, либо разрешать добавление символа в input, либо нет.
В простейшем случае это будет выглядеть так:
var reg = /^[\d]{1,2}[ ]{0,1}[а-я]{0,3}$/i;
$(".ok").on("keydown", function(e) {
var newValue = this.value + e.key;
return reg.test(newValue);
});
<input class="ok" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Дабы у пользователя был шанс исправить введённое значение, код можно усложнить (разрешить обработку backspace):
var reg = /^[\d]{1,2}[ ]{0,1}[а-я]{0,3}$/i;
$(".ok").on("keydown", function(e) {
if (e.which == 8)
return true;
var newValue = this.value + e.key;
return reg.test(newValue);
});
<input class="ok" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Если нужна обработка copy-paste, или возможности перемещаться по значению с помощью стрелок, или ещё что-то в том же духе, то проще и лучше воспользоваться какой-нибудь существующей библиотекой, чем, по сути, создавать свою.
Плагин jQuery Masked Input делает именно то, что вам нужно https://plugins.jquery.com/maskedinput/
Вы задаете маску и нельзя ввести ничего не соответствующего ей. Для вашего примера с датой можно так:
$.mask.definitions['m']='[а-я]';
$("#date").mask("99 mmm");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.maskedinput/1.4.1/jquery.maskedinput.min.js"></script>
<input type="text" id="date">
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости