В основе гибкости Inputmask лежит система определений (definitions), позволяющая расширять стандартный набор символов маски и задавать собственные правила ввода. Каждое определение представляет собой описание поведения одного символа маски: допустимые значения, способ валидации, правила отображения и преобразования.
Стандартные символы вроде 9 (цифра), a
(буква), * (любые символы) реализованы через тот же
механизм, что и пользовательские определения, что делает архитектуру
расширяемой без изменения ядра библиотеки.
Определение задаётся через объект, в котором ключом выступает символ маски, а значением — конфигурация поведения:
Inputmask.extendDefinitions({
'A': {
validator: "[A-Za-z]",
casing: "upper"
}
});
Каждое определение может включать несколько параметров, влияющих на обработку ввода.
validator Задает правило допустимого символа. Может быть строкой с регулярным выражением или функцией.
validator: "[0-9]"
или
validator: function (chrs, buffer, pos, strict, opts) {
return /[0-9]/.test(chrs);
}
cardinality Определяет количество символов, которое
занимает одно определение. Чаще всего используется значение
1, но возможны расширенные сценарии, где один символ маски
соответствует нескольким вводимым символам.
cardinality: 1
casing Управляет регистром вводимых символов.
"upper" — преобразование в верхний регистр"lower" — преобразование в нижний регистрcasing: "upper"
placeholder Задает символ-заполнитель для данного элемента маски.
placeholder: "#"
Механизм расширения позволяет добавлять новые семантические символы поверх существующей логики Inputmask. При этом сохраняется совместимость с базовым парсером маски.
Пример добавления символа, представляющего шестнадцатеричную цифру:
Inputmask.extendDefinitions({
'h': {
validator: "[0-9A-Fa-f]",
casing: "upper"
}
});
Использование в маске:
Inputmask("hhhh-hhhh").mask(element);
Такой подход позволяет формировать специализированные форматы данных без изменения ядра библиотеки.
Вместо регулярного выражения может использоваться функция, обеспечивающая более сложную логику проверки. Это особенно полезно при контекстной валидации.
Inputmask.extendDefinitions({
'X': {
validator: function (chrs, buffer, pos, strict, opts) {
const prev = buffer[pos - 1];
return prev !== chrs;
}
}
});
Функциональная форма предоставляет доступ к:
Это позволяет реализовывать зависимости между символами внутри одной маски.
Параметр cardinality определяет, сколько символов ввода
соответствует одному элементу маски. Это важно при работе с кодами
фиксированной структуры.
Пример определения блока из двух символов:
Inputmask.extendDefinitions({
'B': {
validator: "[0-9A-F]",
cardinality: 2
}
});
При такой конфигурации один символ маски обслуживает сразу два вводимых значения, что позволяет создавать компактные представления сложных данных.
Определения могут учитывать контекст соседних символов. Это используется при построении зависимых форматов, например серийных номеров, где часть структуры влияет на допустимость следующей.
Inputmask.extendDefinitions({
'D': {
validator: function (chrs, buffer, pos) {
const sum = buffer.reduce((acc, val) => acc + (parseInt(val) || 0), 0);
return (sum + parseInt(chrs)) % 2 === 0;
}
}
});
Подобные конструкции позволяют реализовывать контрольные суммы и простые алгоритмы валидации внутри маски.
Система definitions допускает переопределение стандартных символов, что изменяет поведение всей маски без изменения ее структуры.
Inputmask.extendDefinitions({
'9': {
validator: "[0-9]",
placeholder: "0"
}
});
При таком подходе стандартная логика числового ввода может быть адаптирована под конкретные требования интерфейса.
Пользовательские определения часто применяются совместно с alias-конфигурациями. Alias представляет собой именованную маску, внутри которой используются расширенные символы.
Inputmask.extendAliases({
'productCode': {
mask: "AA-9999-XX",
definitions: {
'A': { validator: "[A-Z]" },
'X': { validator: "[0-9A-Z]" }
}
}
});
Такой подход позволяет инкапсулировать бизнес-логику формата данных внутри одного alias.
В одной маске могут использоваться сразу несколько пользовательских символов, каждый из которых отвечает за свою часть структуры данных.
Inputmask.extendDefinitions({
'L': { validator: "[A-Za-z]", casing: "lower" },
'U': { validator: "[A-Za-z]", casing: "upper" },
'N': { validator: "[0-9]" }
});
Маска:
Inputmask("LLL-UUU-NNN").mask(element);
Подобная композиция позволяет формировать строго типизированные пользовательские форматы без внешней обработки.
Определения напрямую влияют на работу механизмов автозаполнения и
очистки ввода. При включенном режимe автоматической обработки символы
преобразуются в соответствии с правилами casing и
validator сразу после ввода.
В сценариях с динамическим обновлением маски определения продолжают действовать на изменяемую структуру, что обеспечивает согласованность поведения при редактировании.
При наличии нескольких условий валидации приоритет определяется следующим образом:
validator (если задана)Такой порядок позволяет переопределять поведение без нарушения базовой логики библиотеки.
При создании сложных определений учитывается несколько технических аспектов:
cardinality > 1 усложняет
синхронизацию курсора;Эти особенности определяют баланс между гибкостью и предсказуемостью поведения системы ввода.
Комбинирование нескольких пользовательских символов позволяет формировать доменные языки масок. Например, формат технических идентификаторов:
Inputmask.extendDefinitions({
'P': { validator: "[A-Z]" },
'Q': { validator: "[0-9]" },
'R': { validator: "[A-Z0-9]" }
});
Маска:
Inputmask("PPQQ-RRRR").mask(element);
Такой подход используется для описания серийных кодов, инвентарных номеров и структурированных идентификаторов.
При редактировании значения Inputmask повторно применяет определения к уже введенным символам. Это означает, что изменение rules в definitions может повлиять не только на новые данные, но и на существующее содержимое поля при следующей перерисовке маски.
Механизм definitions формирует основу декларативной системы описания форматов ввода. Вместо процедурной обработки данных на уровне приложения ввод описывается как набор символов с заданными свойствами, где каждое свойство определяет:
Такой подход позволяет строить масштабируемые схемы ввода без усложнения логики пользовательского интерфейса.