В интерфейсах ввода данных визуальная обратная связь играет критическую роль, особенно в формах, где пользователь вводит структурированные значения: телефоны, даты, банковские реквизиты, коды идентификации. Библиотека Inputmask предоставляет инструменты не только для ограничения формата ввода, но и для интеграции с механизмами валидации, которые позволяют отображать состояние поля в реальном времени.
Inputmask изначально решает задачу маскирования ввода, но не ограничивается этим. Поверх маски можно строить слой логической проверки, который определяет текущее состояние значения:
На основе этих состояний формируется визуальная индикация, которая обычно выражается через CSS-классы, атрибуты или внешние обработчики событий.
Ключевая идея заключается в разделении двух уровней:
Inputmask работает на уровне структуры, а визуальная индикация строится вокруг событий библиотеки.
Для реализации индикации валидности используются события, которые Inputmask генерирует в процессе работы с полем ввода.
oncompleteСрабатывает, когда пользователь полностью заполнил маску. Это состояние часто интерпретируется как «валидное значение введено».
Типичный сценарий:
Логика обработки:
Inputmask({
mask: "+7 (999) 999-99-99",
oncomplete: function () {
this.classList.add("is-valid");
this.classList.remove("is-invalid");
}
}).mask("#phone");
onincompleteСрабатывает, когда поле покидает состояние заполненной маски, но значение остаётся незавершённым.
Используется для отображения состояния ошибки или предупреждения.
Inputmask({
mask: "99/99/9999",
onincomplete: function () {
this.classList.add("is-invalid");
this.classList.remove("is-valid");
}
}).mask("#date");
onclearedВызывается при полном очищении поля. В визуальной логике часто используется для сброса всех состояний.
Inputmask({
mask: "9999-9999-9999-9999",
oncleared: function () {
this.classList.remove("is-valid", "is-invalid");
}
}).mask("#card");
Наиболее распространённый способ визуальной индикации — управление классами элемента. Обычно применяются три состояния:
Пример базовой схемы:
.input {
border: 1px solid #ccc;
transition: border-color 0.2s ease;
}
.input.is-valid {
border-color: #2ecc71;
background-color: #f0fff4;
}
.input.is-invalid {
border-color: #e74c3c;
background-color: #fff5f5;
}
С точки зрения UX важно, что изменение состояния должно происходить
не мгновенно при каждом символе, а после перехода Inputmask в устойчивое
состояние (oncomplete или onincomplete).
Inputmask поддерживает сценарий, в котором значение ещё не завершено, но уже соответствует допустимой структуре на текущем этапе ввода.
Например, при маске:
99-9999
ввод 12- уже частично соответствует структуре, но не
является завершённым значением.
Для визуализации такого состояния часто используется третья категория:
is-dirty или is-partialПример расширенной логики:
Inputmask({
mask: "99-9999",
onincomplete: function () {
this.classList.add("is-partial");
this.classList.remove("is-valid");
},
oncomplete: function () {
this.classList.add("is-valid");
this.classList.remove("is-partial", "is-invalid");
}
}).mask("#code");
Inputmask не заменяет встроенную HTML5-валидацию, а дополняет её. Это позволяет использовать стандартные механизмы браузера:
:valid:invalidrequiredpatternОднако важно учитывать, что Inputmask может временно приводить поле в состояние, которое не проходит нативную проверку до завершения ввода.
Пример комбинированного подхода:
<input
id="email"
type="text"
required
/>
Inputmask({
mask: "*{1,20}@*{1,10}.aa",
oncomplete: function () {
this.setCustomValidity("");
this.classList.add("is-valid");
},
onincomplete: function () {
this.setCustomValidity("Поле заполнено не полностью");
this.classList.add("is-invalid");
}
}).mask("#email");
Здесь используется:
setCustomValidity для участия в HTML-валидации;inputХотя Inputmask предоставляет собственные события, часто используется
синхронизация с нативным событием input для обновления UI в
реальном времени.
const el = document.querySelector("#phone");
Inputmask({
mask: "+7 (999) 999-99-99"
}).mask(el);
el.addEventListener("input", function () {
if (el.inputmask && el.inputmask.isComplete()) {
el.classList.add("is-valid");
} else {
el.classList.remove("is-valid");
}
});
Метод isComplete() позволяет определить, заполнена ли
маска полностью.
Inputmask предоставляет API для проверки состояния значения без необходимости отслеживания событий.
isComplete()Возвращает логическое значение, отражающее завершённость ввода.
const im = Inputmask("9999 9999 9999 9999").mask("#card");
const el = document.querySelector("#card");
el.addEventListener("blur", function () {
if (el.inputmask.isComplete()) {
el.classList.add("is-valid");
} else {
el.classList.add("is-invalid");
}
});
getmetadata() и
контекст состоянияХотя этот метод не относится напрямую к визуальной валидации, он может использоваться для уточнения логики отображения состояния. Например, разные маски могут иметь разные правила завершённости.
При использовании динамических масок визуальная индикация становится сложнее, поскольку формат ввода может меняться в процессе набора.
Пример:
Inputmask({
mask: ["999-999", "9999-9999"],
keepStatic: true,
oncomplete: function () {
this.classList.add("is-valid");
},
onincomplete: function () {
this.classList.remove("is-valid");
this.classList.add("is-invalid");
}
}).mask("#dynamic");
Особенность таких сценариев:
При интенсивном вводе мгновенное обновление классов может приводить к визуальному «дребезгу». Для стабилизации состояния используется отложенная проверка.
let timer;
const el = document.querySelector("#input");
Inputmask("99999").mask(el);
el.addEventListener("input", function () {
clearTimeout(timer);
timer = setTimeout(() => {
if (el.inputmask.isComplete()) {
el.classList.add("is-valid");
el.classList.remove("is-invalid");
} else {
el.classList.add("is-invalid");
el.classList.remove("is-valid");
}
}, 200);
});
Такой подход позволяет:
Помимо CSS-классов, состояние может отражаться через атрибуты, что удобно для интеграции с UI-фреймворками.
Inputmask("99/99/9999").mask("#date");
document.querySelector("#date").addEventListener("blur", function () {
this.setAttribute(
"data-valid",
this.inputmask.isComplete()
);
});
CSS:
input[data-valid="true"] {
border-color: #2ecc71;
}
input[data-valid="false"] {
border-color: #e74c3c;
}
В сложных формах визуальная индикация должна быть синхронизирована с бизнес-валидацией. Inputmask обеспечивает только синтаксическую корректность, тогда как дополнительные проверки (например, проверка существования номера телефона или карты) выполняются отдельно.
Типичная архитектура:
Такое разделение предотвращает ложное ощущение валидности при корректном, но несуществующем значении.
В реальных приложениях визуальная индикация часто зависит от нескольких факторов:
Пример комбинированной логики:
function updateState(el, isServerValid) {
const isMaskValid = el.inputmask.isComplete();
if (isMaskValid && isServerValid) {
el.classList.add("is-valid");
el.classList.remove("is-invalid");
} else {
el.classList.add("is-invalid");
el.classList.remove("is-valid");
}
}
Такая схема позволяет отделить ответственность и избежать противоречий между слоями проверки.