Кредитные карты в пользовательских интерфейсах почти всегда требуют строгого форматирования ввода, поскольку номер карты должен соответствовать фиксированным отраслевым стандартам. Наиболее распространённая структура — последовательность цифр, разбитая на группы по 4 символа, либо специализированный формат 4–6–5 для отдельных платёжных систем. В JavaScript-библиотеках маскирования ввода, таких как Inputmask, эта задача решается через комбинацию шаблонов, правил и динамических масок.
Самый простой вариант реализации — фиксированный шаблон из 16 цифр, разделённых пробелами:
Inputmask("9999 9999 9999 9999").mask("#card");
В данном случае символ 9 обозначает обязательную цифру
от 0 до 9. Пробелы являются статическими символами-разделителями и
автоматически вставляются в соответствующих позициях.
Такой подход подходит для карт формата:
Для понимания гибкости кредитных масок важно учитывать базовые правила Inputmask:
9 — обязательная цифра0 — цифра или пробел (в зависимости от
конфигурации)# — цифровой символ с дополнительной логикой
(расширяемый)A — буквенный символ* — буквенно-цифровой символДля кредитных карт практически всегда используется только
9, так как формат строго цифровой.
Карты American Express отличаются длиной (15 цифр) и структурой группировки:
Inputmask("9999 999999 99999").mask("#card");
Здесь структура разбивается на:
Особенность такого формата — отсутствие универсальности. Маска должна выбираться динамически в зависимости от типа карты.
В реальных интерфейсах маска не является фиксированной, поскольку разные платёжные системы используют разные форматы. Поэтому применяется переключение масок:
const cardMask = Inputmask({
mask: [
"9999 9999 9999 9999",
"9999 999999 99999"
]
});
cardMask.mask("#card");
Inputmask автоматически выбирает подходящий вариант в зависимости от длины ввода и структуры.
BIN (Bank Identification Number) — первые 6 цифр номера карты. На основе BIN можно определить платёжную систему и применить соответствующую маску.
Пример логики:
function getCardMask(value) {
const firstDigit = value.charAt(0);
if (firstDigit === "3") {
return "9999 999999 99999"; // AmEx
}
return "9999 9999 9999 9999";
}
Более точная реализация использует регулярные выражения:
^4^5[1-5]^3[47]Inputmask позволяет обновлять конфигурацию без пересоздания элемента:
const im = new Inputmask("9999 9999 9999 9999");
im.mask("#card");
document.querySelector("#card").addEventListener("input", (e) => {
const value = e.target.value.replace(/\s/g, "");
const newMask =
value.startsWith("3") ? "9999 999999 99999"
: "9999 9999 9999 9999";
im.setOptions({ mask: newMask });
});
Такой подход обеспечивает адаптивное поведение интерфейса.
Плейсхолдеры играют важную роль в восприятии структуры номера карты:
Inputmask("9999 9999 9999 9999", {
placeholder: "____ ____ ____ ____"
}).mask("#card");
Плейсхолдер:
Кредитные карты не должны считаться валидными при неполном вводе. Для этого используется параметр:
Inputmask("9999 9999 9999 9999", {
clearIncomplete: true
}).mask("#card");
Поведение:
Для валидации используется событие завершения:
Inputmask("9999 9999 9999 9999", {
oncomplete: function () {
console.log("Номер карты введён полностью");
}
}).mask("#card");
Это событие полезно для:
В интерфейсах отображения часто требуется скрывать часть номера карты, оставляя только последние 4 цифры:
Inputmask("9999 9999 9999 9999", {
showMaskOnHover: false,
showMaskOnFocus: false
}).mask("#card");
Однако для задач отображения сохранённых карт чаще используется отдельная логика форматирования:
function maskCard(value) {
return value.replace(/\d(?=\d{4})/g, "*");
}
Результат:
**** **** **** 1234
Inputmask автоматически обрабатывает вставку, но при работе с кредитными картами важно учитывать:
Пример подготовки данных:
function normalizeCardInput(value) {
return value.replace(/\D/g, "").slice(0, 16);
}
Это позволяет избежать:
Inputmask поддерживает функциональные маски, возвращающие шаблон динамически:
Inputmask({
mask: function () {
return "9999 9999 9999 9999";
}
}).mask("#card");
Более сложный вариант:
Inputmask({
mask: function (value) {
if (value.startsWith("34") || value.startsWith("37")) {
return "9999 999999 99999";
}
return "9999 9999 9999 9999";
}
}).mask("#card");
Хотя маска контролирует формат, дополнительная проверка остаётся обязательной:
Пример:
function validateCard(value) {
const digits = value.replace(/\D/g, "");
if (digits.startsWith("3")) {
return digits.length === 15;
}
return digits.length === 16;
}
При проектировании ввода кредитной карты критичны следующие аспекты:
Inputmask обеспечивает эти свойства через внутренний механизм позиционирования и перерасчёта маски при каждом вводе символа.
Неправильная конфигурация часто приводит к проблемам:
* вместо 9 для цифрКорректная архитектура предполагает разделение: