Spec-Zone.ru › HTML

Использование проверки HTML-форм и Constraint Validation API

Создание веб-форм всегда было сложной задачей. Хотя разметить саму форму легко, проверить, имеет ли каждое поле допустимое и согласованное значение, гораздо сложнее, а информирование пользователя о проблеме может стать настоящей головной болью. В HTML5 появились новые механизмы для форм: новые семантические типы элемента <input> и проверка ограничений, упрощающая проверку содержимого формы на стороне клиента. Простые стандартные ограничения можно проверять без JavaScript, задав новые атрибуты; более сложные ограничения можно проверять с помощью Constraint Validation API.

Основные сведения об этих понятиях с примерами см. в руководстве по проверке форм.

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

  • Изменив HTML с помощью инструментов разработчика браузера.
  • Составив HTTP-запрос вручную, не используя форму.
  • Программно записав содержимое в форму (некоторые проверки ограничений выполняются только для пользовательского ввода, но не в случае, если задать значение поля формы с помощью JavaScript).

Поэтому всегда следует проверять данные формы на серверной стороне так же, как и на клиентской.

Встроенные и базовые ограничения

В HTML базовые ограничения задаются двумя способами:

  • Выбором наиболее подходящего с семантической точки зрения значения для атрибута type элемента <input>. Например, выбор типа email автоматически создаёт ограничение, проверяющее, является ли значение допустимым адресом электронной почты.
  • Заданием значений атрибутов, связанных с проверкой, что позволяет описывать базовые ограничения без использования JavaScript.

Семантические типы полей ввода

Встроенные ограничения для атрибута type таковы:

Тип поля ввода Описание ограничения Соответствующее нарушение
<input type="URL"> Значение должно быть абсолютным URL-адресом, как определено в живом стандарте URL. Нарушение ограничения TypeMismatch
<input type="email"> Значение должно быть синтаксически допустимым адресом электронной почты, обычно имеющим формат username@hostname.tld, но оно также может быть локальным, например username@hostname. Нарушение ограничения TypeMismatch

Для типа поля ввода email, если задан атрибут multiple, можно указать несколько значений в виде списка, разделённого запятыми. Если какое-либо значение в списке не удовлетворяет описанному здесь условию, возникает нарушение ограничения несоответствия типа.

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

Атрибуты, связанные с проверкой

Помимо описанного выше атрибута type, для описания базовых ограничений используются следующие атрибуты:

Атрибут Типы полей ввода, поддерживающие атрибут Допустимые значения Описание ограничения Соответствующее нарушение
pattern text, search, url, tel, email, password Регулярное выражение JavaScript (скомпилированное с отключёнными флагами global, ignoreCase и multiline) Значение должно соответствовать шаблону. Нарушение ограничения patternMismatch
min range, number Допустимое число Значение должно быть больше или равно этому значению. Нарушение ограничения rangeUnderflow
date, month, week Допустимая дата
datetime-local, time Допустимые дата и время
max range, number Допустимое число Значение должно быть меньше или равно этому значению. Нарушение ограничения rangeOverflow
date, month, week Допустимая дата
datetime-local, time Допустимые дата и время
required text, search, url, tel, email, password, date, datetime-local, month, week, time, number, checkbox, radio, file; также для элементов <select> и <textarea> отсутствует, поскольку это логический атрибут: его наличие означает true, отсутствие — false Значение должно быть задано (если атрибут установлен). Нарушение ограничения valueMissing
step date Целое число дней Если для шага не задано буквальное значение any, значение должно быть равно min + целому кратному шага. Нарушение ограничения stepMismatch
month Целое число месяцев
week Целое число недель
datetime-local, time Целое число секунд
range, number Целое число
minlength text, search, url, tel, email, password; также для элемента <textarea> Целочисленная длина Число символов (кодовых точек) должно быть не меньше значения атрибута, если оно не пустое. Все символы новой строки для <textarea> нормализуются до одного символа (в отличие от пар CRLF). Нарушение ограничения tooShort
maxlength text, search, url, tel, email, password; также для элемента <textarea> Целочисленная длина Число символов (кодовых точек) не должно превышать значение атрибута. Нарушение ограничения tooLong

Процесс проверки ограничений

Проверка ограничений выполняется с помощью Constraint Validation API для отдельного элемента формы или на уровне формы, непосредственно для элемента <form>. Проверка ограничений выполняется следующими способами:

  • Вызовом метода checkValidity() или reportValidity() интерфейса DOM, связанного с формой (HTMLInputElement, HTMLSelectElement, HTMLButtonElement, HTMLOutputElement или HTMLTextAreaElement), который проверяет ограничения только для этого элемента и позволяет скрипту получить эту информацию. Метод checkValidity() возвращает логическое значение, указывающее, соответствует ли значение элемента его ограничениям. (Обычно пользовательский агент делает это, определяя, какой из псевдоклассов CSS — :valid или :invalid — применим.) В отличие от него, метод reportValidity() сообщает пользователю о нарушениях ограничений.
  • Вызовом метода checkValidity() или reportValidity() интерфейса HTMLFormElement.
  • Отправкой самой формы.

Вызов checkValidity() называется статической проверкой ограничений, а вызов reportValidity() или отправка формы — интерактивной проверкой ограничений.

Примечание:

  • Если для элемента <form> задан атрибут novalidate, интерактивная проверка ограничений не выполняется.
  • Вызов метода submit() интерфейса HTMLFormElement не запускает проверку ограничений. Иными словами, этот метод отправляет данные формы на сервер, даже если они не соответствуют ограничениям. Вместо этого вызовите метод click() у кнопки отправки.
  • Ограничения minlength и maxlength проверяются только для данных, введённых пользователем. Они не проверяются, если значение задано программно, даже при явном вызове checkValidity() или reportValidity().

Сложные ограничения с помощью Constraint Validation API

С помощью JavaScript и Constraint API можно реализовать более сложные ограничения, например ограничения, объединяющие несколько полей или требующие сложных вычислений.

Основная идея заключается в том, чтобы запускать JavaScript при возникновении события в поле формы (например, onchange), вычислять, нарушено ли ограничение, а затем использовать метод field.setCustomValidity() для установки результата проверки: пустая строка означает, что ограничение выполнено, а любая другая строка указывает на ошибку и служит сообщением об ошибке, которое нужно показать пользователю.

Ограничение, объединяющее несколько полей: проверка почтового индекса

Формат почтового индекса различается в разных странах. Во многих странах допускается необязательный префикс с кодом страны (например, D- в Германии, F- во Франции и CH- в Швейцарии). В некоторых странах почтовые индексы состоят только из фиксированного числа цифр, а в других, например в Великобритании, используется более сложный формат, в котором в определённых позициях могут стоять буквы.

Примечание: Это не полноценная библиотека для проверки почтовых индексов, а лишь демонстрация основных понятий.

В качестве примера добавим скрипт, который проверяет ограничения формы:

<form>
  <label for="postal-code">Postal Code: </label>
  <input type="text" id="postal-code" />
  <label for="country">Country: </label>
  <select id="country">
    <option value="ch">Switzerland</option>
    <option value="fr">France</option>
    <option value="de">Germany</option>
    <option value="nl">The Netherlands</option>
  </select>
  <input type="submit" value="Validate" />
</form>

Он отображает следующую форму:

Сначала напишем функцию, проверяющую само ограничение:

const countrySelect = document.getElementById("country");
const postalCodeField = document.getElementById("postal-code");

function checkPostalCode() {
  // For each country, defines the pattern that the postal code has to follow
  const constraints = {
    ch: [
      "^(CH-)?\\d{4}$",
      "Swiss postal codes must have exactly 4 digits: e.g. CH-1950 or 1950",
    ],
    fr: [
      "^(F-)?\\d{5}$",
      "French postal codes must have exactly 5 digits: e.g. F-75012 or 75012",
    ],
    de: [
      "^(D-)?\\d{5}$",
      "German postal codes must have exactly 5 digits: e.g. D-12345 or 12345",
    ],
    nl: [
      "^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$",
      "Dutch postal codes must have exactly 4 digits, followed by 2 letters except SA, SD and SS",
    ],
  };

  // Read the country id
  const country = countrySelect.value;

  // Build the constraint checker
  const constraint = new RegExp(constraints[country][0], "");
  console.log(constraint);

  // Check it!
  if (constraint.test(postalCodeField.value)) {
    // The postal code follows the constraint, we use the ConstraintAPI to tell it
    postalCodeField.setCustomValidity("");
  } else {
    // The postal code doesn't follow the constraint, we use the ConstraintAPI to
    // give a message about the format required for this country
    postalCodeField.setCustomValidity(constraints[country][1]);
  }
}

Затем свяжем её с событием change элемента <select> и событием input элемента <input>:

countrySelect.addEventListener("change", checkPostalCode);
postalCodeField.addEventListener("input", checkPostalCode);

Ограничение размера файла перед загрузкой

Ещё одно распространённое ограничение — ограничение размера загружаемого файла. Для проверки на стороне клиента до передачи файла на сервер необходимо объединить Constraint Validation API, в частности метод field.setCustomValidity(), с другим API JavaScript — в данном случае File API.

Вот HTML-часть:

<label for="fs">Select a file smaller than 75 kB: </label>
<input type="file" id="fs" />

Она отображает:

JavaScript считывает выбранный файл, использует метод File.size() для получения его размера, сравнивает размер с (заданным в коде) пределом и вызывает Constraint API, чтобы сообщить браузеру о нарушении:

const fs = document.getElementById("fs");

function checkFileSize() {
  const files = fs.files;

  // If there is (at least) one file selected
  if (files.length > 0) {
    if (files[0].size > 75 * 1000) {
      // Check the constraint
      fs.setCustomValidity("The selected file must not be larger than 75 kB");
      fs.reportValidity();
      return;
    }
  }
  // No custom constraint violation
  fs.setCustomValidity("");
}

Наконец, свяжем метод с соответствующим событием:

fs.addEventListener("change", checkFileSize);

Визуальное оформление проверки ограничений

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

Управление внешним видом элементов

Внешним видом элементов можно управлять с помощью псевдоклассов CSS.

Псевдоклассы CSS :required и :optional

Псевдоклассы :required и :optional позволяют писать селекторы, соответствующие элементам формы, у которых есть атрибут required, или элементам, у которых его нет.

Псевдокласс CSS :placeholder-shown

См. :placeholder-shown.

Псевдоклассы CSS :valid и :invalid

Псевдоклассы :valid и :invalid используются для обозначения элементов <input>, содержимое которых проходит или не проходит проверку в соответствии с типом поля ввода. С помощью этих классов можно оформлять допустимые и недопустимые элементы формы, чтобы было легче определить, какие из них заполнены правильно, а какие — нет.

Управление текстом сообщения о нарушении ограничения

Управлять текстом сообщения о нарушении ограничения можно с помощью следующих средств:

  • Метод setCustomValidity(message) для следующих элементов:

    • <fieldset>. Примечание: установка пользовательского сообщения о допустимости для элементов fieldset в большинстве браузеров не предотвращает отправку формы.
    • <input>
    • <output>
    • <select>
    • Кнопки отправки (созданные с помощью элемента <button> с типом submit или элемента input с типом submit). Кнопки других типов не участвуют в проверке ограничений.
    • <textarea>
  • Интерфейс ValidityState описывает объект, возвращаемый свойством validity перечисленных выше типов элементов. Он представляет различные причины, по которым введённое значение может быть недопустимым. Вместе они помогают объяснить, почему значение элемента не проходит проверку.

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API