Kodokon kodokon.com

Продвинутые формы и нативная валидация

Используй required, pattern, inputmode и Constraint Validation API, чтобы получить надёжные формы без единой внешней библиотеки.

10 мин · 3 вопросов

Открыть этот урок в Kodokon

В браузере встроен полноценный движок валидации, который многие команды по привычке заново пишут на JavaScript. Из чего он состоит: required (обязательное поле), типы (email, url, date), проверяющие формат, minlength/maxlength, min/max/step для числовых значений и pattern, принимающий регулярное выражение. Важнейшая деталь: pattern неявно привязан к границам - совпасть должно всё значение целиком, как если бы регулярное выражение было обёрнуто в ^ и $. Добавляй autocomplete со стандартизированными значениями (postal-code, email, tel): это одновременно UX и доступность.

HTML
<label for="zip">Postal code</label>
<input id="zip" name="zip" type="text"
       required pattern="[0-9]{5}"
       inputmode="numeric"
       autocomplete="postal-code">
Нативная валидация: формат, обязательность, подходящая клавиатура

Атрибут inputmode часто понимают неправильно: он не проверяет ничего. Он лишь сообщает мобильной системе, какую виртуальную клавиатуру показать (numeric, tel, email, decimal, search). Именно поэтому связка type="text" + inputmode="numeric" + pattern - рекомендуемый приём для числовых кодов: ты получаешь нужную клавиатуру, не наследуя поведение type="number".

CSS
input:user-invalid {
  border: 2px solid #b3261e;
}
input:user-valid {
  border: 2px solid #1b5e20;
}
:user-invalid срабатывает только после взаимодействия пользователя

Со стороны CSS предпочитай :user-invalid, а не :invalid: последний применяется сразу при загрузке страницы и красит красным поля, которых пользователь ещё даже не касался. Со стороны JavaScript инструментарий дополняет Constraint Validation API: checkValidity() запускает проверку, объект validity показывает точную причину (patternMismatch, valueMissing, tooShort), а setCustomValidity() позволяет заменить типовые сообщения браузера своими.

JAVASCRIPT
const zip = document.querySelector("#zip");
zip.addEventListener("input", () => {
  if (zip.validity.patternMismatch) {
    zip.setCustomValidity("Enter 5 digits.");
  } else {
    zip.setCustomValidity("");
  }
});
Своё сообщение через API валидации

Проверка знаний

Убедись, что запомнил ключевые моменты этого урока.

  1. Что именно делает inputmode="numeric"?
    • Отклоняет любой нечисловой ввод
    • Преобразует значение поля в число
    • Предлагает числовую клавиатуру на мобильных, ничего не проверяя
  2. Принимается ли значение "abc12345" при pattern="[0-9]{5}"?
    • Да, ведь в нём действительно есть 5 цифр подряд
    • Нет, потому что pattern требует совпадения всего значения целиком
    • Да, если поле не обязательное
  3. Почему для оформления ошибок лучше :user-invalid, а не :invalid?
    • :user-invalid применяется только после взаимодействия пользователя
    • :invalid не поддерживается современными браузерами
    • :user-invalid также проверяет отключённые поля