От автора: в этой статье мы рассмотрим атрибут pattern и как с его помощью проводить валидацию форм, а именно html 5 проверка формы.
Валидация
Валидация форм, как и юзабилити, имеет жизненно важное значение для безопасности сайта. В процессе проверки перед отправкой формы оцениваются значения полей input на корректный формат ввода. К примеру, у нас есть поле input для ввода email’а, в таком случае значением должен выступать правильный адрес почты; адрес должен начинаться с цифры или буквы, затем знак @ и в конце доменное имя.
Спецификация HTML5 упростила процесс проверки формы, представив новые типы поля input: email, url и tel. Данные значения обеспечивают автоматическую валидацию. При любом несовпадении формата ввода данные input’ы будут выдавать ошибку, предотвращая отправку формы.
Однако ожидать полной обработки всех возможных сценариев с полем input непрактично. Скажем, у вас есть поля для имени пользователя, почтового индекса или другие специализированные типы данных, не входящих в спецификацию? Как проводить проверку этих полей? Вот тут нам и поможет атрибут pattern.
Применение атрибута pattern
Атрибут pattern применим только к полям input. С его помощью можно задавать наши собственные правила валидации значения поля input при помощи Регулярных Выражений (RegEx). И еще раз – если значение не совпадает с заданным шаблоном, то выскачет ошибка.
К примеру, у нас есть поле имени пользователя в форме. Стандартизированного типа для поля имени пользователя не существует, значит, мы воспользуемся обычным типом text:
1 2 3 |
<form action="somefile.php"> <input type="text" name="username" placeholder="Username"> </form> |
Зададим правило проверки при помощи атрибута pattern. В нашем примере значение поля должно состоять из букв нижнего регистра; никаких заглавных букв, цифр или других специальных символов. Кроме того, длина поля не должна превышать 15 символом. В форме RegEx данные правила можно записать в виде [a-z]{1,15}. Пропишите [a-z]{1,15} в качестве значения атрибута pattern для поля username.
1 2 3 |
<form action="somefile.php"> <input type="text" name="username" placeholder="Username" pattern="[a-z]{1,15}"> </form> |
Теперь данное поле принимает только буквы нижнего регистра. Любое другое значение вызовет ошибку:
Как видно на скриншоте выше, в сообщении об ошибке сказано «Please match the requested format». Т.е. наша проверка формы работает, но это сообщение не дает представление пользователю о том, какой формат ввода от него требуется, а значит плохой UX.
Настройка сообщения о проверке
К нашему счастью мы можем настраивать текст сообщения, чтобы сделать его более информативным. В нашем распоряжении несколько способов. Самый простой это задать атрибут title для input’а:
1 2 3 4 5 6 7 8 |
<form action="somefile.php"> <input type="text" name="username" placeholder="Username" pattern="[a-z]{1,15}" title="Username should only contain lowercase letters. e.g. john"> </form> |
Теперь заголовок появляется с текстом сообщения по умолчанию:
И все же всплывающее сообщение неустойчиво. Если сравнить это сообщение с сообщением для поля email выше, то инструкция будет куда длиннее. Второй способ решает данную задачу.
Замена стандартного текста сообщения
Теперь давайте заменим стандартный текст «Please match the requested format» на наш. Нам понадобится немного JavaScript. Начнем с добавления id полю input для удобства выбора данного поля в JS.
1 2 3 4 5 6 7 8 |
<form action="somefile.php"> <input type="text" name="username" placeholder="Username" pattern="[a-z]{1,15}" id="username"> </form> |
Теперь мы можем выбрать наше поле через JS и присвоить ему переменную (код ниже или между тегов script, или в отдельном JS файле, или в панели JS на CodePen):
И в конце мы задаем текст сообщения, всплывающего при неправильном вводе.
1 2 3 |
input.oninvalid = function(event) { event.target.setCustomValidity('Username should only contain lowercase letters. e.g. john'); } |
Событие oninvalid наследуется от объекта event, в котором есть несколько свойств, среди которых target (элемент с неправильно введенным текстом) и validationMessage – содержит текст сообщения об ошибке. В примере выше мы переписали текст сообщения при помощи метода setCustomValidity(). Наше сообщение заменило стандартное.
Стили
Спецификация CSS3 добавила несколько удобных псевдоклассов в дополнение к новым типам поля input и методам, описанным выше, используемых для изменения стандартного сообщения об ошибке. И это псевдоклассы :valid and :invalid. С их помощью можно применять стили к элементам в зависимости от их состояния, к примеру:
1 2 3 4 5 6 7 |
input:invalid { border-color: red; } input, input:valid { border-color: #ccc; } |
Необходимо помнить несколько вещей при использовании псевдоклассов:
Первое, :valid применяется по умолчанию, даже если поле пустое. Т.е. в коде выше мы установили цвет по умолчанию border-color: #ccc;. Пустое значение всегда проходит проверку, если не добавить атрибут required. В таком случае значение поля становится неверным, и его рамка становится красной.
Стили для состояний valid и invalid применяются мгновенно с вводом пользователем текста, даже если значение пустое. Такое мгновенное изменение стилей может напугать пользователей.
Пару слов и стилизации всплывающих сообщений
Валидация форм стала новым стандартом спецификации HTML5, однако внешний вид всплывающих сообщений полностью лежит на разработчиках браузеров. В разных браузерах данные поля выглядят по-разному, и они могут не сочетаться с вашим UI.
Google Chrome убрал возможность настройки стилей всплывающего поля пару лет назад. Если же вам необходимо стилизовать поле под себя, то остается только полностью переписать данное поле с помощью JavaScript. Рассмотрим, как это сделать!
Расширяем функционал
Сейчас мы создадим полностью кастомное всплывающее поле, которое будет появляться, когда пользователь вводит неправильное значение. Для начала необходимо выбрать требуемые элементы с идентификаторами input и form:
1 2 |
var input = document.getElementById('username'); var form = document.getElementById('form'); |
Затем мы создаем новые элементы, которые будут хранить наше сообщение:
1 2 3 4 |
var elem = document.createElement('div'); elem.id = 'notify'; elem.style.display = 'none'; form.appendChild(elem); |
Мы создали новый DIV, присвоили ему id со значением notify и спрятали его при помощи display: none. В конце мы вставляем новый DIV в нашу форму.
Работаем с событиями
Нам необходимо обработать два события. Первое это invalid, которое вызывается при несовпадении значения с шаблоном. Код ниже для события invalid:
1 2 3 4 5 6 7 8 9 10 |
input.addEventListener('invalid', function(event){ event.preventDefault(); if ( ! event.target.validity.valid ) { elem.textContent = 'Username should only contain lowercase letters e.g. john'; elem.className = 'error'; elem.style.display = 'block'; input.className = 'invalid animated shake'; } }); |
С помощью event.preventDefault(); мы блокируем всплывающее поле браузера. Взамен мы будем показывать наше поле DIV, внутрь которого мы добавили текст с классом error. Поле показывается при помощи изменения значения display: block;
Также input’у мы добавили класс invalid, в котором прописали красную рамку.
1 2 3 |
input.invalid { border-color: #DD2C00; } |
В дополнение можно добавить классы animated и shake из фреймворка Animate.css. Данные классы придадут аутентичности. Второе событие – input. Событие вызывается при изменении значения поля. Данное событие мы будем использовать для возврата поля в нормальное состояние, а также чтобы прятать всплывающее сообщение.
1 2 3 4 5 6 |
input.addEventListener('input', function(event){ if ( 'block' === elem.style.display ) { input.className = ''; elem.style.display = 'none'; } }); |
В коде выше мы удаляем классы для поля input и прячем сообщение.
Теперь у нас полностью настроенное всплывающее сообщение. Попробуйте – введите любое значение:
Заключительные мысли
Стандартные типы поля input и атрибут pattern придадут вашей форме дополнительный уровень защиты, но не забывайте и про валидацию формы на стороне сервера. Как ни странно даже при отключенном JS последние версии браузеров показывают всплывающее сообщение и не отправляют форму. Safari не поддерживает атрибут pattern на момент написания статьи. Однако похожий функционал можно реализовать с помощью полифилла Webshim Lib. Надеюсь, вам понравился сегодняшний урок, и вы будете держать данную статью под рукой, когда вам понадобится воспользоваться HTML5 валидацией формы.
Комментарии (6)