Как разрешить в инпут ввод только цифр и подставлять пробел после каждых 4-ех символов
Можете подсказать, имеется инпут необходимо запретить ввод любых символов кроме цифр и после каждой 4-ой цифры ставить автоматически пробел - "1234 5678 9012 3456". maxlength поставил с учетом пробелов(16 цифр, 3 пробела)
<input type="cardnumber" id="clientInputCardnum" maxlength="19">
Как запрещать ввод символов знаю. Проблема с подстановкой пробела.
Ответы (2 шт):
Никогда такое не делал, но, может, поможет. Один обработчик — на проверку что вводятся цифры. Другой — на форматирование введенного по шаблону.
const input = document.querySelector('#clientInputCardnum');
/** Валидация цифр при вводе*/
input.addEventListener('keypress', function (evt) {
if (evt.keyCode < 48 || evt.keyCode > 57) evt.preventDefault();
});
/** Оформление вывода по шаблону */
input.addEventListener('input', function (evt) {
const pattern = '**** **** **** ****';
let value = input.value;
value = getCleanValue(value);
value = getPatternedValue(value, pattern);
input.value = value;
});
/** Возвращает очищенную строку (только цифры)*/
function getCleanValue (string) {
let newString = '';
for (let i = 0; i < string.length; i++) {
if ( +string[i] ) newString += string[i];
}
return newString;
}
/** Возвращает оформленную по шаблону строку*/
function getPatternedValue (string, pattern) {
let newString = '';
let counter = 0;
for (let i = 0; i < pattern.length; i++) {
if ( !string[counter] ) continue;
if (pattern[i] === '*') {
newString += string[counter];
counter++;
continue;
}
newString += pattern[i];
}
return newString;
}
<input type="cardnumber" id="clientInputCardnum">
Сразу уточню, что не разбираюсь в JS, код был взять из ответам @novvember и немного изменен.
В основу взято регулярное выражение с негативным просмотром вперед, для установки после каждых 4 цифр символа пробела.
//Скопированная функция
const input = document.querySelector('#InputCardnum1');
input.addEventListener('input', function (evt) {
input.value = input.value
.replace(/(\d{4})(?!\s|$)/gm, `$1 `)
.match(/(?:\d{4} ?){0,3}(?:\d{0,4})?/)
});
//Вариант №2, не используем константу
//На сколько я понял принципиальной разницы нет между querySelector
//и getElementById. Хотя querySelector как я понял при нескольких
//одиннаковых id может получить массив данных
document.getElementById('InputCardnum2')
.addEventListener('input', function (event) {
event.target.value = event.target.value
.replace(/(\d{4})(?!\s|$)/gm, `$1 `)
.match(/(?:\d{4} ?){0,3}(?:\d{0,4})?/)
})
<p><b>Copy:</b><br>
<input type="cardnumber" placeholder="Card Number" id="InputCardnum1">
<br>
<p><b>Способ 2:</b><br>
<input type="cardnumber" placeholder="Card Number" id="InputCardnum2">
UPD: убрал проверку ввода в регулярное выражение
Подробнее о рег. выражениях:
replace(/(\d{4})(?!\s|$)/gm, `$1 `)
Выполняет функцию добавления пробела после каждых 4х идущих подряд цифр
\d - диапазон цифр, эквивалентно [0-9]
{4} - квантификатор, т.е. указано точное количество что 4 цифры идущие подряд
(...) - захватываемая группа, во втором значение $1 - ее возвращение и пробел
(?!...) - негативный просмотр вперед, для того, что бы если группа из 4-х цифр уже разделенная пробелом или является последней не разделялась дополнительно
...|... в группе | означает логическое или
\s - любой пробельный символ
$ - означает конец строки, нужен специальный параметр m - multiline
.match(/(?:\d{4} ?){0,3}(?:\d{0,4})?/)
Используем для ограничения количества вводимых символов и соблюдения порядка
(?:...) - не захватываемая группа, обычно используется для того, что бы установить квантификатор на группу символов в определенном порядке
? - означает 0 или 1 пробел
{0,3} - квантификатор группы, т.е. у нас может быть ноль, один, два или три блока разделенных пробелами цифр, не разделенные пробелом будут разделены replace
(?:\d{0,4})? - группа, в которой не жесткая привязка количества цифр, служит для того, что бы можно было вводить символы по одному, в ней отсутствует пробел и так как в предыдущей группе используется квантификатор на цифру равный четырем, то при начале ввода каждого из блока номера карты будет срабатывать именно эта часть, до указания четвертой цифры блока.
Предупреждение:
Использование регулярных выражений зачастую снижают скорость выполнения программы, поэтому при обработке больших массивов данных следует постараться избежать сложных конструкций либо регулярных выражений в целом.
Так же повторю, что с данным кодом я экспериментирую ввиду отсутствия необходимого количества знаний, поэтому тестируйте его вдруг решите использовать в проекте.