Приемы Angular: улучшите UX кнопки отправки, НЕ отключая ее.

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

1. Проблема:

При создании угловых форм я усвоил то, что я могу очень легко отслеживать их состояния валидации:

Итак, я быстро реализовал свою первую форму и в итоге получил что-то вроде той, которую вы видите на скриншоте ниже:

Что не так с этой картинкой?

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

2. Типичное (несовершенное) решение:

Поэтому я подумал: О, теперь я знаю, для чего нужны эти другие свойства элементов управления формой, которые дает нам Angular! Давайте использовать состояние .dirty или .touched, чтобы отображать только проверки полей, когда пользователь взаимодействует с ними:

Давайте попробуем это:

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

Тем не менее, есть еще одна проблема, которую многие разработчики упускают:

⬅️ кнопка отправки.

Очень простое и распространенное решение в формах Angular - отключить кнопку в зависимости от срока действия формы:

<button [disabled]="formRef.invalid"></button>

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

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

3. Окончательное решение:

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

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

  • Изначально мы не показываем пользователю никаких ошибок (он же «невиновен, пока виновность не будет доказана»).
  • Мы разрешаем пользователю нажимать кнопку отправки, и когда он это делает, когда не все правила проверки соблюдены, только тогда мы покажем ошибки.

Реализация:

Это поведение, которое мы, вероятно, захотим использовать во всем нашем приложении, поэтому мы реализуем его как директиву. :

  1. мы захотим добавить его на кнопки отправки и использовать вместо событий (click) для сохранения форм
  2. директива должна знать о форме, с которой мы работаем - очевидный способ (но не единственный, читайте дальше) - передать его как @Input()
  3. директива будет прослушивать нажатие на элемент кнопки через @HostListener('click')
  4. когда происходит щелчок, директива будет проходить через все элементы управления формы и запускать markAsDirty() или markAsTouched(), чтобы сработала логика отображения сообщений проверки
  5. если форма действительна, щелчок также заставит директиву генерировать событие, чтобы мы знали, что можем отправить форму

Код:

Использование:

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

Улучшенное решение:

На самом деле мы можем заставить директиву определять форму, в которой она находится, с помощью механизма внедрения зависимостей Angular и вообще пропустить необходимость определения ввода! Посмотрите, что происходит в конструкторе:

Теперь наш html-код сводится к следующему:

Это буквально настолько просто, насколько это возможно. А вот форма в действии:

Вы можете увидеть рабочий пример с кодом
в песочнице StackBlitz.

Вы узнали что-то новое? В таком случае вы можете:

→ похлопайте кнопку 👏 внизу️, чтобы это увидело больше людей
подписывайтесь на меня в Твиттере (@sulco), чтобы вы не пропустили следующие публикации!

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

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