Полное руководство по HTML-формам и проверке ограничений

HTML Изучение

В этой статье мы рассмотрим поля HTML-формы и варианты проверки, предлагаемые HTML5. Мы также рассмотрим, как их можно улучшить с помощью CSS и JavaScript.

Что такое проверка ограничений?

У каждого поля формы есть цель. И эта цель часто регулируется контрсилами — или правила, регулирующие то, что следует и не следует вводить в каждое поле формы. Например, для emailполя потребуется действующий адрес электронной почты; passwordполе может потребовать определенных типов символов и иметь минимальное количество требуемых символов; а текстовое поле может иметь ограничение на количество вводимых символов.

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

Проверка на стороне клиента и на стороне сервера

Большая часть кода JavaScript, написанного в первые годы существования языка, обрабатывала проверку формы на стороне клиента. Даже сегодня разработчики тратят много времени на написание функций для проверки значений полей. Это все еще необходимо в современных браузерах? Наверное, нет. В большинстве случаев это действительно зависит от того, что вы пытаетесь сделать.

Но сначала вот большое предупреждающее сообщение:

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

Всегда дезинфицируйте данные на стороне сервера. Не каждый запрос будет поступать из браузера. Даже в этом случае нет гарантии, что браузер проверил данные. Любой, кто знает, как открыть инструменты разработчика браузера, также может обойти ваш с любовью созданный HTML и JavaScript.

Поля ввода HTML5

HTML предлагает:

  • <textarea> для многострочных текстовых полей
  • <select> для раскрывающегося списка опций
  • <button> для… кнопок

Но <input>чаще всего вы будете использовать :

<input type="text" name="username" />

typeАтрибут задает тип управления, и есть большой выбор вариантов:

type описание
button кнопка без поведения по умолчанию
checkbox флажок / галочка
color палитра цветов
date выбор даты для года, месяца и дня
datetime-local выбор даты и времени
email поле для ввода электронной почты
file сборщик файлов
hidden скрытое поле
image кнопка, которая отображает изображение, определяемое srcатрибутом
month сборщик месяца и года
number поле ввода номера
password поле ввода пароля с затемненным текстом
radio радио-кнопка
range ползунок
reset кнопка, которая сбрасывает все входные данные формы до значений по умолчанию (но не используйте ее, так как она редко бывает полезной)
search поле ввода поиска
submit кнопка отправки формы
tel поле для ввода номера телефона
text поле ввода текста
time выбор времени без часового пояса
url поле ввода URL
week номер недели и сборщик года

Браузер возвращается к работе, textесли вы опускаете typeатрибут или не поддерживает параметр. Современные браузеры хорошо поддерживают все типы, но старые браузеры по-прежнему отображают поле ввода текста.

Другие полезные <input>атрибуты включают:

атрибут описание
accept тип загрузки файла
alt альтернативный текст для типов изображений
autocomplete подсказка для автозаполнения полей
autofocus поле фокуса при загрузке страницы
capture метод ввода захвата мультимедиа
checked флажок / радио отмечен
disabled отключить элемент управления (он не будет проверен и его значение не будет отправлено)
form связать с формой, используя этот идентификатор
formaction URL для отправки на кнопки отправки и изображения
inputmode подсказка по типу данных
list ID <datalist>вариантов автозаполнения
max максимальное значение
maxlength максимальная длина строки
min минимальное значение
minlength минимальная длина строки
name имя элемента управления, отправленное на сервер
pattern шаблон регулярного выражения, например, [A-Z]+для одного или нескольких символов верхнего регистра
placeholder текст-заполнитель, когда значение поля пустое
readonly поле недоступно для редактирования, но оно все равно будет проверено и отправлено
required поле обязательно для заполнения
size размер элемента управления (часто переопределяется в CSS)
spellcheck набор trueили falseпроверка орфографии
src URL изображения
step инкрементные значения в числах и диапазонах
type тип поля (см. выше)
value начальное значение

Поля вывода HTML

Помимо типов ввода, HTML5 предоставляет выходные данные только для чтения:

  • output: текстовый результат вычисления или действия пользователя
  • progress: Прогресс бар с valueи maxатрибуты
  • meter: Шкала, которая может меняться между зеленым, желтым и красным цветом в зависимости от значений, установленных для value, min, max, low, high, и optimumатрибутов.

Метки входа

Поля должны иметь связанный <label>элемент, который можно обернуть вокруг элемента:

<label>your name <input type="text" name="name" /><label>

Или свяжите поле idс меткой с помощью forатрибута:

<label for="nameid">your name</label>
<input type="text" id="nameid" name="name" />

Ярлыки важны для доступности. Возможно, вы встречали формы, в которых используется placeholderдля экономии места на экране:

<input type="text" name="name" value="" placeholder="your name" />

Текст-заполнитель исчезает, когда пользователь что-то вводит — даже один пробел. Лучше показать метку, чем заставлять пользователя помнить, что это за поле!

Читайте также:  Как использовать Bootstrap с React?

Входное поведение

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

Большинство типов полей очевидны, но есть исключения. Например, кредитные карты являются числовыми, но счетчик увеличения / уменьшения бесполезен, и при вводе 16-значного числа слишком легко нажимать вверх или вниз. Лучше использовать стандартный textтип, но установить для inputmodeатрибута значение numeric, которое показывает соответствующую клавиатуру. Настройка autocomplete=»cc-number»также предлагает любые предварительно настроенные или ранее введенные номера карт.

Использование правильных местах typeи autocorrectпредлагает преимущества, которые было бы трудно добиться в JavaScript. Например, некоторые мобильные браузеры могут:

  • импортировать данные кредитной карты путем сканирования карты с помощью камеры
  • импортировать одноразовые коды, отправленные по SMS

Автоматическая проверка

Браузер обеспечивает входное значение прилипает с ограничениями, определяемыми type, min, max, step, minlength, maxlength, pattern, и requiredатрибуты. Например:

<input type="number" min="1" max="100" required />

Попытка отправить пустое значение предотвращает отправку формы и показывает следующее сообщение в Chrome:

Попытка отправить пустое значение предотвращает отправку

Спиннеры не допускают значений за пределами диапазона от 1 до 100. Подобные сообщения проверки появляются, если вы вводите строку, которая не является числом. И все это без единой строчки JavaScript.

Вы можете остановить проверку браузера следующим образом:

  • добавление novalidateатрибута к <form>элементу
  • добавление formnovalidateатрибута к кнопке отправки или изображению

Создание пользовательских входных данных JavaScript

Если вы пишете новый компонент ввода даты на основе JavaScript, остановитесь и отойдите от клавиатуры!

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

Есть три основные причины, по которым разработчики предпочитают создавать входные данные на основе JavaScript.

  1. Стандартные элементы управления сложно стилизовать

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

  1. Современные <input>типы не поддерживаются в старых браузерах.

По сути, вы пишете код для Internet Explorer. Пользователи IE не получат средства выбора даты, но все равно смогут вводить даты в YYYY-MM-DDформате. Если ваш клиент настаивает, загрузите полифилл только в IE. Нет необходимости перегружать современные браузеры.

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

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

Подводя итог: избегайте повторного изобретения элементов управления HTML!

Стиль проверки CSS

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

селектор описание
:focus поле с фокусом
:focus-within элемент содержит поле с фокусом (да, это родительский селектор!)
:focus-visible элемент имеет фокус из-за навигации с клавиатуры, поэтому необходимо кольцо фокусировки или более очевидный стиль
:required поле с requiredатрибутом
:optional поле без requiredатрибута
:valid поле, прошедшее проверку
:invalid поле, которое не прошло проверку
:user-valid поле, прошедшее проверку после взаимодействия с ним пользователя (только Firefox)
:user-invalid поле, которое не прошло проверку после того, как пользователь взаимодействовал с ним (только Firefox)
:in-range значение находится в пределах диапазона на входе numberилиrange
:out-of-range значение вне допустимого диапазона на входе numberилиrange
:disabled поле с disabledатрибутом
:enabled поле без disabledатрибута
:read-only поле с read-onlyатрибутом
:read-write: поле без read-onlyатрибута
:checked установленный флажок или переключатель
:indeterminate неопределенный флажок или радио-состояние, например, когда все переключатели не отмечены
:default кнопка отправки по умолчанию или изображение

Вы можете стилизовать placeholderтекст ввода с помощью ::placeholderпсевдоэлемента:

/* blue placeholder on email fields */
input[type="email"]::placeholder {
  color: blue;
}

Указанные выше селекторы имеют одинаковую специфику, поэтому порядок может иметь значение. Рассмотрим этот пример:

input:invalid { color: red; }
input:enabled { color: black; }

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

Браузер применяет стили проверки при загрузке страницы. Например, в следующем коде каждое недопустимое поле выделено красной рамкой:

:invalid {
  border-color: #900;
}

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

JavaScript и API проверки ограничений

Constraint Validation API предоставляет возможности настройки формы, которые могут расширить стандартную проверку HTML поля. Ты мог:

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

Проверка формы

Перед использованием API ваш код должен отключить проверку по умолчанию и сообщения об ошибках, установив для noValidateсвойства формы значение true(так же, как добавление novalidateатрибута):

const myform = document.getElementById('myform');
myform.noValidate = true;

Затем вы можете добавить обработчики событий, например, при отправке формы:

myform.addEventListener('submit', validateForm);

Обработчик может проверить действительность всей формы с помощью методов checkValidity()или reportValidity(), которые возвращаются, trueкогда все входные данные формы действительны. (Разница в том, что checkValidity()проверяет, подлежат ли какие-либо входные данные проверке ограничений.)

Читайте также:  Laravel и Yii: какой вариант выбрать?

Документы Mozilla объясняют:

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

// validate form on submission
function validateForm(e) {

  const form = e.target;

  if (form.checkValidity()) {

    // form is valid - make further checks

  }
  else {

    // form is invalid - cancel submit
    e.preventDefault();

  }

};

Действительная форма теперь может подвергаться дальнейшим проверкам. Точно так же недопустимая форма может иметь выделенные недопустимые поля.

Проверка поля

Отдельные поля имеют следующие свойства проверки ограничений:

  • willValidate: возвращает, trueесли элемент является кандидатом на проверку ограничения.
  • validationMessage: сообщение проверки. Это будет пустая строка, если поле действительное.
  • valitity: объект ValidityState. У этого есть validсвойство, установленное, trueкогда поле допустимо. Если это так false, одно или несколько из следующих свойств будут true:
ValidityState описание
.badInput браузер не может понять ввод
.customError настроено настраиваемое сообщение о достоверности
.patternMismatch значение не соответствует указанному patternатрибуту
.rangeOverflow значение больше maxатрибута
.rangeUnderflow значение меньше minатрибута
.stepMismatch значение не соответствует stepправилам атрибута
.tooLong длина строки больше maxlengthатрибута
.tooShort длина строки меньше minlengthатрибута
.typeMismatch значение не является действительным адресом электронной почты или URL
.valueMissing requiredзначение пусто

Для отдельных полей используются следующие методы проверки ограничений:

  • setCustomValidity(message): устанавливает сообщение об ошибке для недопустимого поля. Если поле действительно, необходимо передать пустую строку, иначе поле останется недействительным навсегда.
  • checkValidity(): возвращается, trueкогда ввод действителен. valitity.validСвойство делает то же самое, но checkValidity()также вызывает invalidсобытие на поле, которое может быть полезным.

Функция- validateForm()обработчик может перебирать каждое поле и при необходимости применять invalidкласс к его родительскому элементу:

function validateForm(e) {
  const form = e.target;
  if (form.checkValidity()) {
    // form is valid - make further checks
  }
  else {
    // form is invalid - cancel submit
    e.preventDefault();
    // apply invalid class
    Array.from(form.elements).forEach(i => {
      if (i.checkValidity()) {
        // field is valid - remove class
        i.parentElement.classList.remove('invalid');
      }
      else {
        // field is invalid - add class
        i.parentElement.classList.add('invalid');
      }
    });
  }
};

Предположим, ваш HTML определил поле электронной почты:

<div>
  <label for="email">email</label>
  <input type="email" id="email" name="email" required />
  <p class="help">Please enter a valid email address</p>
</div>

Сценарий применяет invalidкласс к, <div>когда электронная почта не указана или недействительна. CSS может отображать или скрывать сообщение проверки при отправке формы:

.help { display: none; }
.invalid .help { display: block; }
.invalid label, .invalid input, .invalid .help {
  color: red;
  border-color: red;
}

Создание настраиваемого валидатора форм

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

Он реализован с использованием универсального класса проверки формы с именем FormValidate. При создании экземпляра объекта передается элемент формы. Может быть установлен необязательный второй параметр:

  • true для проверки каждого поля при взаимодействии с ним пользователя
  • false (по умолчанию) для проверки всех полей после первой отправки (после этого выполняется проверка на уровне поля)
// validate contact form
const contactForm = new FormValidate(document.getElementById('contact'), false);

.addCustom(field, func)Метод определяет пользовательские функции проверки. Следующий код гарантирует, что поля emailили telдопустимы (ни у одного из них нет requiredатрибутов):

// custom validation - email and/or telephone
const
  email = document.getElementById('email'),
  tel = document.getElementById('tel');

contactForm.addCustom(email, f => f.value || tel.value);
contactForm.addCustom(tel, f => f.value || email.value);

А FormValidateобъект отслеживает оба из следующих действий :

  • focusout события, которые затем проверяют отдельное поле
  • submitсобытия формы, которые затем проверяют каждое поле

Оба вызывают.validateField(field)метод, который проверяет, проходит ли поле стандартную проверку ограничений. Когда это происходит, все пользовательские функции проверки, назначенные этому полю, выполняются по очереди. Все должны вернуться, trueчтобы поле было действительным.

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

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

// custom submit
contactForm.submit = e => {
  e.preventDefault();
  alert('Form is valid!\n(open the console)');
  const fd = new FormData(e.target);
  for (const [name, value] of fd.entries()) {
    console.log(name + ': ' + value);
  }
}

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

Form Finesse

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

Рекомендации:

  • По возможности используйте стандартные типы ввода HTML. Набор min, max, step, minlength, maxlength, pattern, required, inputmode, и autocompleteатрибуты по мере необходимости.
  • При необходимости используйте немного JavaScript, чтобы включить настраиваемую проверку и сообщения.
  • Для более сложных полей постепенно улучшайте стандартные входные данные.

Наконец: забудьте про Internet Explorer!

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

 

Оцените статью
bestprogrammer.ru
Добавить комментарий