- PVSM.RU - https://www.pvsm.ru -

Нативная валидация как фреймворк. Лекция в Яндексе

Разработка форм — один из самых ответственных и сложных этапов создания веб-интерфейсов. Проект должен получить пользовательские данные, проверить их и дать пользователю обратную связь. Современные браузеры предоставляют разработчику встроенный API, позволяющий поэтапно реализовать валидацию данных методом progressive enhancement — от HTML/CSS к JS. Можно ли уже сегодня отказаться от тяжеловесных библиотек для валидации? Какие преимущества обеспечивает нативная валидация и насколько тернист путь её использования? В своём докладе на конференции FrontTalks [1] технический директор LOVATA Павел Ловцевич рассмотрел основные аспекты работы с HTML5 Constraint Validation API.

— Всем привет, меня зовут Павел, я приехал из Минска. Я расскажу про валидацию веб-форм на основе нативных, встроенных в браузер, технологий.

Я работаю техническим директором в компании LOVATA, а также работаю техническим директором в нашем продуктовом стартапе 2doc.by, это медицинский поиск с B2B-частью, которая заключается в автоматизации работы медицинских центров.

Я уже почти 10 лет провожу в Минске мероприятия. Долгое время это были только Web Standard Days, но за последний год Остапа понесло, и сразу плюс три мероприятия. Можно как Брежневу медали вешать. Приезжайте в Минск, у нас много классных мероприятий, будем дружить городами и сообществами.

Я уверен, в зале не найдется человека, который хоть раз бы не делал веб-форму в каком-то виде, хотя бы одно текстовое поле для приема данных. Это одна из самых важных штук в интерфейсе веб-сайтов и приложений, потому что она прямым образом влияет на конверсию, на успешность проекта.

Есть такой исследовательский институт Беймарда, который занимается исследованиями в области юзабилити. Они провели исследования по 37 открытым источникам, которые, в свою очередь, проводили независимые исследования с 2012 по 2017 годы в области использования веб-форм и пришли к следующим выводам: почти 70% пользователей бросают свои корзины. Из них 60% бросают их по той причине, что в какой-то момент они еще были не готовы начать оформление покупки, а просто знакомились с товаром. При этом 27% пользователей явно указали, что они бросили оформление заказа в силу того, что веб-форма была слишком сложной. Они столкнулись с теми или иными проблемами при работе с ней. Либо она была слишком длинной. Среднее количество полей в форме оформления заказа в этом исследовании составляло порядка 15. Либо были проблемы с валидацией. Так или иначе, веб-форма коренным образом повлияла на конверсию всех этих магазинов.

На основе этого исследования были сделаны выводы, что интерфейсные улучшения веб-форм могут привести к 35-процентному улучшению показателей конверсии. Принимая во внимание объем рынка, США в e-commerce, это 260 млрд долларов, мы всего лишь сделаем веб-форму лучше, сократим количество полей с 15 до 7–8, сделаем хорошую уместную валидацию. И индустрия выручит дополнительно 260 млрд в год.

Валидация — один из важнейших этапов работы с веб-формами пользователей. Раньше у нас были ненативные способы, их было много, каждый писал себе библиотеку. На текущий момент очень популярны npm-библиотеки для jQuery. Чтобы просто провалидировать поля формы, вы тащите за собой jQuery-бандл, который весит 80 КБ.

Все можно упростить, воспользовавшись встроенными в браузер инструментами.

Нативная валидация как фреймворк. Лекция в Яндексе - 1

Валидация – это настолько серьезная штука, что даже существует специальный стандарт ISO, который обозначает определение валидации.

Какие у цели преследует валидация? Во-первых, получение корректных данных в корректном формате для последующей их обработки. Во-вторых, защита пользователя от разного рода перехвата данных. И, наконец, защита приложения. Мы не хотим, чтобы через веб-форму нас взломали и получили доступ к данным пользователя, которые он ввел ранее.

Какое самое главное поле клиентской валидации, без которого никуда? Валидация на сервере! Это основной способ валидации, он отвечает за безопасность. Клиентская валидация – это в первую очередь то, что влияет на пользовательский опыт, тот самый UX. Хорошая валидация помогает в повышении конверсии.

Из чего состоит хорошая валидация? Было проведено исследование, Мартин Тредер основывался на нескольких источниках, в том числе большом исследовании Люка Врублевски, известного специалиста в области юзабилити. Он пришел к следующим выводам, что, во-первых, валидация должна быть в правильном месте. Имеется в виду форма сообщения о некой ошибке, где мы выводим сообщение об ошибке пользователя, чтобы ему удобно было с ней работать.

Во-вторых, в правильное время – инлайн-валидация, никто не хочет заполнять всю форму, и в конце при сабмите увидеть, что у нас какие-то ошибки, возвращаться и начинать сначала. Еще хуже, если мы потеряем какие-то данные.

В третьих, подходящий цвет. Мы привыкли видеть, что в формах поля с ошибками так или иначе подсвечиваются красным цветом, однако исследования показывают, что один из лучших вариантов все же оранжевый цвет. Он не настолько давит на пользователя, плюс это цвет, которые могут видеть дальтоники.

В, в четвертых, понятный язык. Это широкое понятие. Мы должны явно сообщить пользователю о том, что он не так сделал и как это исправить, а не просто подсветить ошибочно заполненное поле, и оставить пользователя разбираться с ним один на один.

Нативная валидация как фреймворк. Лекция в Яндексе - 2

Исследование Люка Врублевски говорит о том, что инлайн-валидация ведет к повышению следующих показателей. На 22% увеличивается успешность завершения заполнения формы; на 22% уменьшается количество ошибок при ее заполнении; удовлетворенность пользователей растет на 31%; время на заполнение веб-формы при прочих равных сокращается на 42%; а глаза пользователей меньше напрягаются при инлайн-валидации, так как им не приходится постоянно бегать по разным полям, таким образом, количество фиксаций глаз на веб-форме уменьшается на 47%.

Главная тема моего доклада – специальное API, встроенное в браузер уже достаточно давно, но до сих пор эта тема не была активно продвигаема.

Я в этом году занялся этой темой, также было несколько исследований, например, Питер Поль Кох из Голландии провел большое исследование использования нативной валидации в браузере, а также Крис Фердинанди также написал большую серию статей.

Что мы можем делать с нативной валидацией?

Нативная валидация как фреймворк. Лекция в Яндексе - 3

С точки зрения поддержки все достаточно неплохо. В данном случае имеется в виду базовая поддержка, которая говорит о том, что мы можем указывать поля как обязательные и отлавливать их состояние валидность или невалидности, заполнено поле или нет.

В данной ситуации, если браузер поддерживает Form validation, мы говорим о том, что он поддерживает некие нативные методы JS API.

Первый способ включения валидации – просто пометка поля с помощью атрибута Required как обязательного.

Нативная валидация как фреймворк. Лекция в Яндексе - 4

Слева поле помечено атрибутом required, справа не помечено. Сразу на форму и на элементы этой формы навешаны псевдоклассы valid и invalid, которые подсвечивают нам состояние их состояние. Как видите, сама форма может также отлавливать состояние валидности или невалидности, «слушая» состояние полей внутри. Внутренняя рамка также может отлавливать эти состояния.

Если мы попробуем сюда что-то ввести, то увидим, что форма и fieldset получили проброшенное состояние валидности, и форму можно отправить.

Нативная валидация как фреймворк. Лекция в Яндексе - 5

С точки зрения поддержки у нас есть проблемы только у Edge и IE. Они заключаются в том, что в данных браузерах fieldset и form не поддерживают состояние валидности/невалидности. Но я не вижу в этом большой проблемы, т.к. не встречал в своей практике кейсов, когда нам было бы очень важно отлавливать это состояние именно на этих элементах.

В приведенной форме, кнопка изначально была подсвечена зеленым, т.к. браузерах этот элемент формы всегда находится в состоянии валидности, и только в Firefox, есть специальный вендорный псевдокласс и только для кнопки, когда это input в type submit. Отдельная узкая история, сомневаюсь, что вам это может понадобиться.

Нативная валидация как фреймворк. Лекция в Яндексе - 6

Нативная валидация как фреймворк. Лекция в Яндексе - 7

Второй способ включения валидации с помощью атрибута. Мы можем задать длину строки в поле, ограничить ее максимальным и минимальным значением, указать паттерн и т.д.

Required поддерживают все виды полей форм.

С длиной строки (minlength/maxlength) важно понимать, что помимо таких типов полей, как file, checkbox, radio, булевы типы, существуют типы полей, которые не поддерживают данный вид ограничения. Это числовые поля, например, либо type number либо type data и все его вариации, потому как у них есть свои специальные ограничители, которые оценивают не длину строки, а величину значения, введенного в поле.

Для полей, значения которых могут быть оценены в величине, в качестве ограничения применяются атрибуты min и max.

Step так же используется с подобного рода полями. Его основная задача в том, чтобы задать шаг значения, которое мы можем вводить в поле. Это может быть кратность некоему числу, временному отрезку и т.д.

Pattern применяется для всех текстовых полей, кроме числовых полей и полей даты. Это самый хорошо поддерживаемый элемент атрибут в формах, с помощью которого в т.ч. мы можем писать фолбэки для браузеров, которые по тем или иным причинам не понимают назначение определенного типа поля, которое мы рассмотрим далее.

Нативная валидация как фреймворк. Лекция в Яндексе - 8

Третий тип включения валидации – указание конкретного типа поля, его семантика. Кроме стандартных — text, password, file, text area — можно сюда докинуть select, существуют еще number, range, email, tel, url и date. C date пока все не очень хорошо в плане поддержки, но через две версии Firefox у нас появится чуть ли не лучший date picker, останется только Safari подтянуться.

Давайте попробуем создать форму по методу прогрессивного улучшения. Мы все идем к ситуации, когда последние 10 лет мы собирали все в бандлы, все наши скрипты, стили, и по мере распространения HTTP 2, заточенного на многопоточную загрузку наших ассетов к страницам, мы будем постепенно отказываться от склеивания файлов. У нас возможно чаще будут возникать ситуации, когда часть ресурсов может недогрузиться. Да, мы можем отлавливать с помощью различных JS API подобные состояния, так или иначе реагировать на них, но при этом, если мы будем делать валидацию формы с помощью CSS, мы сможем до момента, когда JS отработает, уже неким образом улучшить пользовательский опыт.

Нативная валидация как фреймворк. Лекция в Яндексе - 9

Представим, что это некая абстрактная форма заказа. Все подсвечено зеленым, не задано никаких ограничений. Если зададим ограничение обязательности полей, мы сразу увидим, какие поля станут подсвечены красным. Что-то введем в обязательное поле, поле заполнено, все стало окей.

Нативная валидация как фреймворк. Лекция в Яндексе - 10

(Работа с формой в видео начиная с 13:30 [2] — прим. ред.) Поддержка type number достаточно хорошая, только в Edge есть проблема в том, что он не отображает в поле специальные управляющие элементы стрелочки, которые позволяют пользователю не вводить данные, а переключать их с помощью этих стрелочек. Есть особенность в Firefox в том, что он позволяет внести нечисловое значение в это тип поля, а Chromium-браузеры и Edge в принципе не позволят этого сделать. Это более правильное поведение, т. к. позволяет предотвратить создание ситуации, когда возникает ошибка. С помощью этого поля мы ограничим соответствующее поле заказа в нашей форме.

Нативная валидация как фреймворк. Лекция в Яндексе - 11

Что не так в форме, которую я обнаружил в аэропорту Шереметьево? Здесь использован неправильный тип поля, но почему? Использован type number, предназначенный для полей, принимающих значения вида число с плавающей запятой. Если это просто набор цифр, как в данном случае, это просто код в SMS, то это не та ситуация, когда нужен type number. В этой ситуации вы должны использовать обычный type text с паттерном, ограничивающим диапазон символов, которые можно сюда вбивать.

Точно такая же ситуация в форме восстановления пароля в Instagram. Это типичный неправильный кейс использования типа number для полей. Не делайте так, это неправильно.

Нативная валидация как фреймворк. Лекция в Яндексе - 12

Есть еще три специальных семантических типа поля. Первый – e-mail. Его основное значение провалидировать e-mail. Он имеет достаточно мягкую валидацию по RFC 822, которая допускает наличие e-mail на localhost, поэтому у вас по дефолту подобное поле провалидируется, если вы просто введете некое значение до символа собаки и после без указания домена верхнего уровня.

Также назначение этого поля – включение специальных клавиш на виртуальной клавиатуре ваших устройств, когда кликнув в поле e-mail у вас на клавиатуре появится символ собачки.

Тип tel не имеет никаких специальных ограничений по паттерну, слишком разные во всем мире форматы номеров телефонов. Его основная задача включить на устройстве цифровую клавиатуру, потому что при наборе телефонов в большинстве случаев вам не нужны буквы.

Тип URL работает похожим образом, как email, там достаточно лайтовая валидация, которая позволяет фактически указывать localhost без указания домена. Эти требования можно ужесточить с помощью атрибута pattern.

Нативная валидация как фреймворк. Лекция в Яндексе - 13

Давайте попробуем ужесточить в нашей форме ограничения. Помимо того, что мы задали type number, представим гипотетически, что пользователь может сделать заказ не менее чем двух единицы товара и не более чем 20.

Нативная валидация как фреймворк. Лекция в Яндексе - 14

У нас есть поля адреса и города. Мы считаем, что город менее чем из двух букв существовать в принципе не может, а нам необходимо осуществить доставку. Мы ограничиваем это поле двумя символами, и предположим, что вряд ли существует город с названием больше, чем 100 символов. Но с ограничениями максимальной длины строки всегда будьте осторожны. Когда валидируете тот же e-mail и так далее, вы никогда не можете быть уверенными до конца, какое реальное значение может быть максимальным. В любом случае, в полях даже с точки зрения безопасности стоит ограничивать длину поля, но делать ее достаточно комфортной, чтобы избежать ситуации, когда вы не попали в реальные данные, которые могут быть туда введены.

Нативная валидация как фреймворк. Лекция в Яндексе - 15

Поддержка атрибута pattern достаточно хорошая, никаких проблем нигде нет. У Safari на iOS версии 10.2 была проблема с тем, что при установленном для поля паттерне форма сабмитилась, несмотря на то, что зажигалось событие невалидности данных.

Нативная валидация как фреймворк. Лекция в Яндексе - 16

Основные возможности применения pattern – возможность задания диапазонов значений, указание только символов цифр или букв, вариативных значений и задание диапазона минимальной и максимальной длины строки.

Нативная валидация как фреймворк. Лекция в Яндексе - 17

Попробуем провалидировать паттерн. Я из Минска, у нас все почтовые индексы начинаются на 220, меняются только три последних числа.

Нативная валидация как фреймворк. Лекция в Яндексе - 18

Вы видите обычную Perl подобную регулярку, к которой мы привыкли в JS. Стоит обратить внимание, что привычные символы начала и окончания строки, в случае использования с Constraint Validation API можно опускать. Более краткая запись без них будет работать так же.

Нативная валидация как фреймворк. Лекция в Яндексе - 19

Я указал атрибут title, стандартный атрибут подсказки, всплывающей при наведении на элемент. В комбинации с текстовым полем, у которого задан pattern, этот атрибут title будет всплывать в нативной подсказке, сообщающей пользователю, что он ввел некорректные данные. Это единственный способ для единственного типа поля задать без помощи JS содержимое этого сообщения.

Какие очевидные баги на данном этапе и как мы можем их решать?

Нативная валидация как фреймворк. Лекция в Яндексе - 20

(Работа с формой в видео начиная с 19:40 [3] — прим. ред.) Левое поле является обязательным, у него задано ограничение максимальной строки в четыре символа. Вы видите шесть символов. Это достаточно неприятный момент, реализованный во всех браузерах одинаково, который заключается в том, что если у нас дефолтное value нашего поля превышает наше ограничение, то у нас не зажигается флаг невалидности.

Если мы попробуем его менять, курсор не пускает, потому что атрибут maxlength не позволяет ввести больше допустимого количества символов, это работает одинаково во всех браузерах.

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

Для минимального значений то же самое. Здесь задано минимум 4, введено 2 – валидно. Начинаем вводить – невалидно. Достигли 4 – валидно.

Нативная валидация как фреймворк. Лекция в Яндексе - 21

В Edge есть проблема с тем, что minlength не поддерживается как атрибут. Но вы можете это обойти, просто использовав паттерн, который будет работать совместно с вашими атрибутами minlength и maxlength, и он будет иметь приоритет.

Нативная валидация как фреймворк. Лекция в Яндексе - 22

Type number. Если браузер не понимает какой-то особый тип поля, то дефолтное поведение – он фолбэчится на обычный type text. Если у вас возникнет кейс, когда какой-то очень старый браузер не поддерживает type number, но это сделать необходимо, вы можете задать регулярку, которая позволит валидировать только числа, допустимые в данном типе поля.

Нативная валидация как фреймворк. Лекция в Яндексе - 23

Если мы захотим задать ограничение значения, регулярка не может вычислить величину значения, но мы можем подобными приемами задавать диапазоны допустимых значений. Естественно, это не очень удобно, и чем больше будет допустимое значение, тем больше будет регулярка. Поэтому это работающий случай, но очень частный, потому что может быть сложно и неудобно с ним работать. Но он работает.

Нативная валидация как фреймворк. Лекция в Яндексе - 24

Тип e-mail. Дефолтный RFC 822, который допускает наличие e-mail на localhost. Естественно, нас это не устраивает, мы хотим получить реальный e-mail пользователя, поэтому мы можем улучшить валидацию уже существующего семантического поля, добавив правильный паттерн.

Нативная валидация как фреймворк. Лекция в Яндексе - 25

Я не стал вбивать реальный паттерн, он был бы слишком большой, можете нагуглить реальный паттерн для RFC 822. Паттерн для привычного вида e-mail тоже легко гуглится.

Нативная валидация как фреймворк. Лекция в Яндексе - 26

Еще достаточно важный тип поля – date. В Firefox тоже скоро приедет поддержка этого типа. В нашей форме этого нет, но я покажу способ, при котором также можно сделать валидацию без JS данного типа поля.

Нативная валидация как фреймворк. Лекция в Яндексе - 27

Например, если мы хотим принимать данные от пользователя о дате в формате YYYY-MM-DD, то регулярка в атрибуте pattern поможет в этом деле.

Нативная валидация как фреймворк. Лекция в Яндексе - 28

(Работа с формой в видео начиная с 23:25 [4] — прим. ред.) Попробуем заполнить нашу форму. Язык, на котором отображаются стандартные сообщение о заполнении, это не дефолтная локаль ОС, это локаль браузера. Если вам необходимо управлять языком, числовыми форматами, денежными, дат и т.д., вы для этого можете использовать специально JS API – Internationalization, чтобы настраивать эти вещи. На данном этапе мы работаем только с CSS-частью валидации.

Для поля задано минимальное числовое значение 2. Вводим 1 – не подходит. Смотрим, что сообщает браузер – указывает «минимум 2», 12 попадает в диапазон, поэтому все ОК.

Я сделал одно поле необязательным, чтобы видеть, как поле может выглядеть на фоне остальных полей. Мы считаем, что для нас имя пользователя неважно в данной ситуации.

Пробуем вбить e-mail. Всплыл тот самый title, который я вписал в соответствующий атрибут данного поля, который говорит о том, что мы хотим валидировать полный e-mail, а не по RFC 822.

Индекс. Паттерн так же установлен, всплывает title.

Город и адрес – минимум два символа, окей.

Что вас должно смущать в такой форме? Поля красные. Форма изначально бьет в глаза пользователям, что данные невалидны. Исследование, на которое я ссылался, говорит о том, что инлайновая валидация должна происходить только тогда, когда пользователь явно ввел данные, и когда он покинул это поле, только тогда мы можем предлагать валидацию данных.

Существует специальный псевдокласс :user-error в живом стандарте от WHATWG, он не поддерживается в браузерах, к сожалению. Это специальный псевдокласс, призванный валидировать поля, в которые пользователь явно ввел данные.

Существует другой псевдокласс :user-invalid от разработчиков спецификации W3C, он тоже не поддерживается в браузерах.

Не отчаивайтесь, есть другой псевдокласс :placeholder-shown. Это специальный псевдокласс, который отлавливает состояние отображения плейсхолдера в поле формы. Как мы можем его использовать, чтобы решить проблему, о которой я сказал ранее?

Нативная валидация как фреймворк. Лекция в Яндексе - 29

Во-первых, в полях форм уже могут быть некие плейсхолдеры, которые бы помогали пользователю понимать, в каком формате вводить эти данные. Если пользователь ввел в поле некие данные, плейсхолдер пропал, и мы можем отловить это состояние, и опираясь на него, валидировать форму.

Если же у вас нет явного плейсхолдера, то вы можете создать пустой плейсхолдер просто с пробелом, и это будет работать точно так же.

Нативная валидация как фреймворк. Лекция в Яндексе - 30

Мы отлавливаем состояние того, что плейсхолдер не отображается, что поле не в фокусе, то есть пользователь закончил вводить данные.

Нативная валидация как фреймворк. Лекция в Яндексе - 31

Ну и что присутствует состояние невалидности. Мы можем зажечь флаг, явным образом выделить поле как невалидное.

Нативная валидация как фреймворк. Лекция в Яндексе - 32

С поддержкой все был бы неплохо, если бы не Edge, но у него настолько низкая доля даже в мировом разрезе, что опираясь на тот факт, что данный тип валидации – это лишь начальный этап, пока не приехал JS, думаю, это не настолько страшно и критично.

(Работа с формой в видео начиная с 27:25 [5] — прим. ред.) Вот та же форма, но с этим длинным селектором. Что-то вводим – не подходит. Вбиваем корректные данные, уходим с поля – подходит. И так же далее, до тех пор, пока не введем что-то корректное, поле никак не будет нас раздражать и как-то некорректно отображаться.

Проблемы нативных сообщений достаточно серьезные.

Первая проблема – невозможность стилизации. Вы в принципе никаким образом не можете подстроить под ваш дизайн нативное сообщение браузера.

Разные принципы работы в разных браузерах. Они относятся к таким областям как время появления, длительность появления нативного сообщения, условия появления и так далее.

Самое печальное, что в Chromium-браузерах текст, который появляется в сообщениях об ошибке, в принципе не читается скринридером.

Попробуем улучшить наши формы с помощью JS.

Нативная валидация как фреймворк. Лекция в Яндексе - 33

Constraint Validation API содержит сразу несколько способов для работы с вашими формами. Во-первых, это метод checkValidity, возвращающий вам true/false, зажигающий событие невалидности или валидности поля.

Второй метод reportValidity делает то же самое, плюс выводит нативное сообщение. setCustomValidity возвращает значение поля и позволяет нам задать кастомное сообщение в этом поле.

Свойство willValidate, по сути, срабатывает на submit и говорит о том, какое поле подвержено валидации или не подвержено, потому что мы можем отдельные поля исключать из валидации, указав атрибут novalidate для конкретного поля.

Свойство Valiidity позволяет вернуть объект с различными ограничениями, которые мы можем отловить, чтобы явно указать пользователю, в чем он ошибся.

Необходимо сразу сказать, что reportValidity() – опасное свойство, никогда его не используйте.

Нативная валидация как фреймворк. Лекция в Яндексе - 34

(Работа с формой в видео начиная с 29:30 [6] — прим. ред.) Проверим в браузере Chrome невалидное поле. Я перевожу в него фокус ввода и не могу выйти отсюда. Что бы вы не пытались сделать, если вы попали в Chrome в невалидное поле, которое валидируется этим методом, пока вы не сделаете данные в этом поле валидными, вы не сможете выйти из этого поле. Просто не используйте этот метод.

Второй метод, немного кривой, но его можно использовать.

Нативная валидация как фреймворк. Лекция в Яндексе - 35

Мы можем проверять конкретное свойство, что конкретно пошло не так с пользовательскими данными, и выводить необходимое сообщение.

Нативная валидация как фреймворк. Лекция в Яндексе - 36

Когда мы задаем setCustomValidity и передаем строку, у нас срабатывает событие невалидности и поле зажигается как невалидное.

Нативная валидация как фреймворк. Лекция в Яндексе - 37

Если мы передадим пустую строку, такая особенность реализации этого API, то в поле не выведется сообщение, но при этом поле станет валидным.

Нативная валидация как фреймворк. Лекция в Яндексе - 38

Объект Validity содержит целую гроздь способов проверки всего, что мы можем проверять, длину строки, все те возможности на основе типа поля, атрибутов поля, все проверяется с помощью этих свойств.

Нативная валидация как фреймворк. Лекция в Яндексе - 39

Вы можете строить совершенно разные собственные проверки, не опираясь только на то, что предлагают вам авторы спецификации.

Нативная валидация как фреймворк. Лекция в Яндексе - 40

Способ, как сделать поле невалидным, просто проверяя на соответствие два поля пароля. Таких кейсов можно придумать много, это будет расширение нативного API.

Нативная валидация как фреймворк. Лекция в Яндексе - 41

Мы идем по принципу прогрессивного улучшения. Что мы хотим получить? Состояние полей, выключить нативную валидацию, проверить валидности при снятии фокуса, идентифицировать ошибку, показать сообщение об ошибке, стилизовать это сообщение, сделать сообщение дружественным для скринридеров и проверить поля по сабмиту формы.

Нативная валидация как фреймворк. Лекция в Яндексе - 42

Получаем состояние полей, чекая свойство Validity.

Нативная валидация как фреймворк. Лекция в Яндексе - 43

Мы хотим, допустим, явно указывать формы, управление валидацией которых мы хотим перехватывать, чтобы лучше их валидировать. Мы просто отлавливаем все формы с явно указанным классом Validate и устанавливаем в них управляющий атрибут novalidate, который отключает невозможность сабмита формы, при этом вся остальная валидация работает, все события валидности и невалидности сохраняются.

Нативная валидация как фреймворк. Лекция в Яндексе - 44

Дальше мы вешаем обработчик событий и слушаем все события blur на снятие фокуса, это лучший способ проверять данные при снятии фокуса.

Нативная валидация как фреймворк. Лекция в Яндексе - 45

Мы создадим специальную функцию hasError, которая будет пробегаться по всем этим свойствам, чтобы определить, валидно поле или нет, по всем свойствам Validity.

Нативная валидация как фреймворк. Лекция в Яндексе - 46

Нативная валидация как фреймворк. Лекция в Яндексе - 47

Мы смотрим, если у нас некое поле невалидно, а от формы возвращается невалидность, тогда мы дальше бежим по всем остальным свойствам, чтобы проверить каждое из них на соответствие ограничению.

Нативная валидация как фреймворк. Лекция в Яндексе - 48

Мы можем расширить проверку несоответствия типа. Несоответствие типа соответствует как e-mail, так и URL, но чтобы выделить конкретный e-mail, мы можем указать, что проблема с ним.

Нативная валидация как фреймворк. Лекция в Яндексе - 49

Мы также можем помочь пользователю, читая атрибуты minLength, maxLength, с минимальной и максимальной величиной значения, чтобы в подсказке явно указывать, что не так и чего мы ожидаем от пользователя. То же самое для числового поля.

Нативная валидация как фреймворк. Лекция в Яндексе - 50

При наличии паттерна мы будем забирать из паттерна значение title, чтобы выводить его в нашем кастомном сообщении.

Нативная валидация как фреймворк. Лекция в Яндексе - 51

Забираем и выводим.

Нативная валидация как фреймворк. Лекция в Яндексе - 52

Нативная валидация как фреймворк. Лекция в Яндексе - 53

Далее мы хотим отобразить ошибку.

Нативная валидация как фреймворк. Лекция в Яндексе - 54

Также заведем отдельную функцию для этого, повесим в наш обработчик отображение сообщения об ошибке.

Нативная валидация как фреймворк. Лекция в Яндексе - 55

Будем добавлять класс error для наших полей.

Нативная валидация как фреймворк. Лекция в Яндексе - 56

Также будем забирать id этого поля, чтобы потом взаимодействовать с ним и с блоком сообщения об ошибке.

Нативная валидация как фреймворк. Лекция в Яндексе - 57

Как мы будем отображать сообщение об ошибке? Просто будем создавать элемент div с нужным классом, привязывать его к нужному полю. И в дальнейшем отображать.

Нативная валидация как фреймворк. Лекция в Яндексе - 58

Нативная валидация как фреймворк. Лекция в Яндексе - 59

Нативная валидация как фреймворк. Лекция в Яндексе - 60

Далее мы будем связывать наше поле с этим div с помощью специального aria-атрибута, чтобы скрин ридеры понимали, что эта ошибка относится к этому полю, и в этом нам помогает id.

Нативная валидация как фреймворк. Лекция в Яндексе - 61

Скрыть сообщение об ошибке тоже достаточно просто будет.

Нативная валидация как фреймворк. Лекция в Яндексе - 62

Создаем специальную функцию, вешаем ее в обработчик.

Нативная валидация как фреймворк. Лекция в Яндексе - 63

Наша задача будет убрать класс error с поля, убрать aria-атрибут.

Нативная валидация как фреймворк. Лекция в Яндексе - 64

Еще раз посмотреть id и потом произвести скрытие этой ошибки.

Нативная валидация как фреймворк. Лекция в Яндексе - 65

Нативная валидация как фреймворк. Лекция в Яндексе - 66

Нам нельзя забывать, что помимо того, что валидация может происходить инлайново, необходимо еще обрабатывать ситуацию, когда мы валидируем submit формы.

Нативная валидация как фреймворк. Лекция в Яндексе - 67

Создаем соответствующий event listener, точно так же проверяем, бегаем по всем полям.

Нативная валидация как фреймворк. Лекция в Яндексе - 68

Нативная валидация как фреймворк. Лекция в Яндексе - 69

В случае наличия ошибок мы перехватываем с помощью preventDefault дефолтное поведение кнопки, выводим сообщение об ошибке.

Нативная валидация как фреймворк. Лекция в Яндексе - 70

Нативная валидация как фреймворк. Лекция в Яндексе - 71

Что важно, получив ранее id всех полей, мы переводим фокус ввода в первое из полей, которое невалидно. При этом у нас не будет возникать ситуации, которая была в Chrome, когда поле невалидно, но из него нельзя выйти.

Нативная валидация как фреймворк. Лекция в Яндексе - 72

Мы получили форму. (Работа с формой в видео начиная с 35:40 [7] — прим. ред.) Выскочили поля, заполняем их, все окей, форма отправилась.

Есть отличная серия статей от Криса Фердинанди [8], я упоминал ее ранее. Крис написал скрипт Validate JS, части этого скрипта я сегодня продемонстрировал. Скрипт работает поверх нативного API и позволяет вам создавать форму, которая, в свою очередь, работает по методу прогрессивного улучшения. Скрипт очень простой, все что нужно — подключить его к странице, добавить для нужных форм класс Validate и наслаждаться. Этот скрипт — во второй части статей.

В третьей части статей он рассказывает про Polyfill, который Крис написал и который расширяет поддержку даже до браузера IE9 для использования нативной валидации.

Отличная серия статей от Питера-Поля Коха [9] в мае 2017 года вышла в блоге разработчиков Samsung Internet. Это титаническое исследование, в котором вы можете узнать обо всех особенностях реализации этого API в браузерах, обо всех косяках. Зная о них, вы сможете принять решение, использовать ли данное API в своем проекте.

Использование нативного API однозначно позволяет нам прогрессивно улучшать нашу форму. До того, как к нам приезжает JS, мы уже можем обрабатывать данные пользователя.

Тот скрипт, что я использовал в презентации, весит всего 6 КБ, в минифицированном виде 2,7 КБ. Сравните: самая популярная валидация на jQuery тащит только jQuery за собой на 80 КБ.

Использование этого API позволяет вам понимать их особенности, давать обратную связь авторам спецификации о том, что удобно, а что нет. В свое время jQuery тоже появился как API поверх API, и самые лучшие вещи из jQuery перешли в спецификацию ECMAScript. Я убежден: чем больше разработчиков будут обращаться к данному API и использовать его в работе, тем больше будет обратной связи и тем скорее API будет доведено до нормального состояния.

Нативная валидация как фреймворк. Лекция в Яндексе - 73

Когда API будет доведено до такого состояния, что не понадобятся какие-то прослойки, нативная валидация станет работать гораздо быстрее, чем любой сценарий в скрипте, который вы подключаете в сценарий извне. Андрей Ситник тоже говорит, что поверх любого API можно написать более удобный API и использовать его безопасно. На этом все, спасибо.

Автор: Леонид Клюев

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/276665

Ссылки в тексте:

[1] FrontTalks: https://events.yandex.ru/events/fronttalks/2017/

[2] Работа с формой в видео начиная с 13:30: https://youtu.be/9G8CSNgCxE8?t=13m30s

[3] Работа с формой в видео начиная с 19:40: https://youtu.be/9G8CSNgCxE8?t=19m40s

[4] Работа с формой в видео начиная с 23:25: https://youtu.be/9G8CSNgCxE8?t=23m25s

[5] Работа с формой в видео начиная с 27:25: https://youtu.be/9G8CSNgCxE8?t=27m25s

[6] Работа с формой в видео начиная с 29:30: https://youtu.be/9G8CSNgCxE8?t=29m30s

[7] Работа с формой в видео начиная с 35:40: https://youtu.be/9G8CSNgCxE8?t=35m40s

[8] серия статей от Криса Фердинанди: https://css-tricks.com/form-validation-part-1-constraint-validation-html/

[9] Отличная серия статей от Питера-Поля Коха: https://medium.com/@pp.koch

[10] Источник: https://habrahabr.ru/post/348240/?utm_source=habrahabr&utm_medium=rss&utm_campaign=348240