--- title: Валидация ограничений slug: Web/Guide/HTML/Constraint_validation tags: - CSS - Руководство - HTML5 - NeedsContent - Селекторы ---
Создание веб-форм всегда было сложной задачей. Хотя сверстать саму форму достаточно просто, проверить, имеет ли каждое поле валидное значение — сложнее, а информирование пользователя о проблеме может стать настоящей головной болью. HTML5 представил для форм новый механизм: он добавляет элементу {{ HTMLElement("input") }} новые семантические типы и constraint validation, чтобы облегчить проверку содержимого на стороне клиента. С помощью новых атрибутов основные ограничения могут быть проверены без использования JavaScript; более сложные ограничения могут быть проверены с помощью Constraint validation API.
Базовое введение в эти концепции с примерами можно найти в разделе Валидация форм на стороне клиента.
В HTML5 базовые ограничения объявляются двумя способами:
email
автоматически создаёт ограничение, которое проверяет, является ли значение валидным email-адресом.Внутренние ограничения атрибута {{ htmlattrxref("type", "input") }}:
Тип input | Описание ограничения | Связанное нарушение |
---|---|---|
<input type="URL"> |
Значение должно быть URL-адресом, как указано в URL Living Standard. | Нарушение ограничения TypeMismatch |
<input type="email"> |
Значение должно быть синтаксически правильным email-адресом, который обычно имеет формат username@hostname.tld . |
Нарушение ограничения TypeMismatch |
Для обоих этих типов input, если установлен атрибут {{ htmlattrxref("multiple", "input") }} допускается ввод нескольких разделённых запятыми значений. Если какое-то из значений не удовлетворяет условию, описанному выше, срабатывает нарушение ограничения Type mismatch.
Обратите внимание, что большинство типов input не имеют внутренних ограничений, так как некоторые из них недоступны для валидации ограничений или имеют алгоритм, по умолчанию преобразующий неправильные значения в правильные.
В дополнение к атрибуту type
, описанному выше, для описания основных ограничений используются следующие атрибуты:
Атрибут | Типы input, поддерживающие атрибут | Возможные значения | Описание ограничения | Связанное нарушение |
---|---|---|---|---|
pattern |
text , search , url , tel , email , password |
Регулярное выражение JavaScript (без ECMAScript 5 флагов global , ignoreCase , and multiline |
Значение должно соответствовать шаблону. | Нарушение ограничения patternMismatch |
min |
range , number |
Валидное число | Значение в поле должно быть больше или равно значению атрибута | Нарушение ограничения rangeUnderflow |
date , month , week |
Валидная дата | |||
datetime , datetime-local , time |
Валидная дата и время | |||
max |
range , number |
Валидное число | Значение в поле должно быть меньше или равно значению атрибута | Нарушение ограничения rangeOverflow |
date , month , week |
Валидная дата | |||
datetime , datetime-local , time |
Валидная дата и время | |||
required |
text , search , url , tel , email , password , date , datetime , datetime-local , month , week , time , number , checkbox , radio , file ; а также элементы {{ HTMLElement("select") }} и {{ HTMLElement("textarea") }} |
Нет, так как это булев атрибут: его наличие означает true, а отсутствие — false | В поле обязательно должно быть значение (если установлен атрибут) | valueMissing constraint violation |
step |
date |
Целое число дней | Если для шага не задан литерал any , значением должно быть min + целое число, кратное шагу |
Нарушение ограничения stepMismatch |
month |
Целое число месяцев | |||
week |
Целое число недель | |||
datetime , datetime-local , time |
Целое число секунд | |||
range , number |
Целое число | |||
minlength |
text , search , url , tel , email , password ; а также элемент {{ HTMLElement("textarea") }}/td>
| Целое число | Если атрибут не пустой, количество символов (точек кода) содержимого поля не должно быть меньше значения, указанного в атрибуте. Все символы новой строки нормализованы до одного символа (в отличие от CRLF-пар) для {{ HTMLElement("textarea") }}. | Нарушение ограничения tooShort |
maxlength |
text , search , url , tel , email , password ; а также элемент {{ HTMLElement("textarea") }} |
Целое число | Количество символов (точек кода) содержимого поля не должно превышать значение, указанное в атрибуте | Нарушение ограничения tooLong |
Валидация ограничений выполняется с помощью Constraint Validation API либо на отдельном элементе формы, либо на уровне формы, на самом элементе {{ HTMLElement("form") }}. Способы валидации:
checkValidity()
или reportValidity()
связанного с формой DOM-интерфейса, (HTMLInputElement
, HTMLSelectElement
, HTMLButtonElement
, HTMLOutputElement
или HTMLTextAreaElement
), который оценивает ограничения только на данном элементе, позволяя скрипту получить эту информацию. Метод checkValidity()
возвращает логическое значение, указывающее, соотвествует ли значение элемента его ограничениям. (Обычно это делает браузер при определении того, какой CSS-псевдоклассов применяется: {{ Cssxref(":valid") }} или {{ Cssxref(":invalid") }}.) Напротив, метод reportValidity()
сообщает пользователю о любых нарушениях ограничений.checkValidity()
или reportValidity()
интерфейса HTMLFormElement
.Вызов метода checkValidity()
называется статической валидацией ограничений, а вызов метода reportValidity()
или отправка формы называется интерактивной валидацией ограничений.
submit()
интерфейса HTMLFormElement
не запускает валидацию ограничений. Другими словами, этот метод отправляет данные формы на сервер, даже если ограничения нарушены. Вместо него вызовите метод click()
кнопки отправки формы.С помощью JavaScript и Constraint Validation API можно реализовать более сложные ограничения, например, ограничения, касающиеся сразу нескольких полей или ограничения, включающие сложные вычисления.
По сути, идея заключается в том, чтобы при наступлении определённого события поля формы (например, onchange) запускать JavaScript, чтобы определить, нарушено ограничение, и затем с помощью метода field.setCustomValidity()
, задать результат валидации: пустая строка означает, что ограничение соблюдается, а любая другая строка означает, что есть ошибка и эта строка является сообщением об ошибке, которое нужно показать пользователю.
Формат почтового индекса в разных странах отличается. Мало того, что в большинстве стран может быть дополнительный префикс с кодом страны (например, D —
в Германии, F —
во Франции или Швейцарии), в некоторых странах, почтовые индексы содержат фиксированное количеством цифр; другие, например, Великобритания, имеют ещё более сложную структуру, допускающую в определённых местах ещё и наличие букв.
Примечание: Далее представлена не полная библиотека валидации почтового индекса, а скорее демонстрация ключевых концепций.
В качестве примера мы добавим скрипт, выполняющий валидацию органичений простой формы:
<form> <label for="ZIP">ZIP : </label> <input type="text" id="ZIP"> <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>
Получим следующую форму:
{{EmbedLiveSample("Constraint_combining_several_fields_Postal_code_validation")}}
Сначала запишем функцию, проверяющую само ограничение:
function checkZIP() { // Для каждой страны определяем шаблон, которому должен следовать почтовый индекс var constraints = { ch : [ '^(CH-)?\\d{4}$', "Switzerland ZIPs must have exactly 4 digits: e.g. CH-1950 or 1950" ], fr : [ '^(F-)?\\d{5}$' , "France ZIPs must have exactly 5 digits: e.g. F-75012 or 75012" ], de : [ '^(D-)?\\d{5}$' , "Germany ZIPs 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])$', "Nederland ZIPs must have exactly 4 digits, followed by 2 letters except SA, SD and SS" ] }; // Прочитать id страны var country = document.getElementById("Country").value; // Получить поле NPA var ZIPField = document.getElementById("ZIP"); // Создать валидатор ограничения var constraint = new RegExp(constraints[country][0], ""); console.log(constraint); // Валидировать индекс if (constraint.test(ZIPField.value)) { // Индекс соответствует ограничению, мы используем ConstraintAPI, чтобы сообщить об этом ZIPField.setCustomValidity(""); } else { // Индекс не соответствует ограничению , мы используем ConstraintAPI, чтобы // показать сообщение, описывающее формат, требуемый для данной страны ZIPField.setCustomValidity(constraints[country][1]); } }
Затем мы связываем его с событием onchange для {{ HTMLElement("select") }} и с событием oninput для {{ HTMLElement("input") }}:
window.onload = function () { document.getElementById("Country").onchange = checkZIP; document.getElementById("ZIP").oninput = checkZIP; }
Вы можете посмотреть живой пример валидации индекса.
Ещё одним распространённым ограничением является лимит размера загружаемых файлов. Данная проверка на стороне клиента перед отправкой на сервер требует сочетания Constraint Validation API и особенно метода field.setCustomValidity()
с другим JavaScript API, в данном случае — File API.
Вот часть HTML:
<label for="FS">Select a file smaller than 75 kB : </label> <input type="file" id="FS">
Она отображает:
{{EmbedLiveSample("Limiting_the_size_of_a_file_before_its_upload")}}
JavaScript считывает выбранный файл, с помощью метода File.size()
получает его размер, сравнивает его с лимитом и вызывает Constraint Validation API, чтобы сообщить браузеру о нарушении:
function checkFileSize() { var FS = document.getElementById("FS"); var files = FS.files; // Если выбран хотя бы один файл if (files.length > 0) { if (files[0].size > 75 * 1024) { // Проверить ограничение FS.setCustomValidity("Размер файла не должен превышать 75 kB"); return; } } // Если нарушения ограничений нет FS.setCustomValidity(""); }
Наконец мы связываем метод с нужным событием:
window.onload = function () { document.getElementById("FS").onchange = checkFileSize; }
Живой пример валидации ограничения размера файла.
Помимо установки ограничений, веб-разработчики хотят управлять тем, какие сообщения показываются пользователям и как они оформлены.
Изменять внешний вид элементов можно с помощью CSS-псевдоклассов.
Псевдоклассы {{cssxref(':required')}} и {{cssxref(':optional')}} позволяют писать селекторы, соответствующие элементам формы, которые имеют или не имеют атрибут {{ htmlattrxref("required") }}
Смотрите {{cssxref(':placeholder-shown')}}
Псевдоклассы {{cssxref(':valid')}} и {{cssxref(':invalid')}} используются для представления элементов <input>, содержимое которых является валидным или не валидным соответственно. Эти классы позволяют пользователю оформлять валидные или не валидные элементы формы, чтобы облегчить определение элементов, которые имеют корректный или некорректный формат.
Следующее может помочь с управлением текстом нарушения ограничений:
input
submit
с указанным типом {{HTMLElement("input/submit", "submit")}}. Другие типы кнопок не участвуют в валидации ограничений.ValidityState
описывает объект, возвращаемый свойством validity перечисленных выше типов элементов. Он представляет разные способы определения не валидности значения. Вместе они помогают объяснить, почему значение элемента не проходит валидацию, если оно не валидно.