Проверка данных веб-форм

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

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

Цель этой статьи, узнать о новых интерфейсах API, чтобы помочь себе и веб-разработчикам делать веб-формы лучше.

Что будет в этой статье:

  • Обзор того, что ограничивает проверка.
  • Узнать спецификацию и реализацию в браузерах.
  • Примеры использования проверки заполнения полей веб-форм.

Проверка данных

Пользователь не должен писать свой номер телефона в поле ввода, где нужно указать свой электронный адрес, если пользователь это сделал, будет ошибка. Ограничение по количеству вводимых символов или в поле для ввода телефона можно писать только цифры, потому что телефон состоит из цифр. Чтобы все это выяснить, алгоритм использует новые атрибуты HTML min, max, step, pattern, и required для вводимых данных.

Для примера используем форму с пустым input с атрибутом required:

<form>
  <input type="text" required value="" />
  <input type="submit" value="Отправить" />
</form>

Если отправить форму пустой, браузер уведомляет о следующем:

Chrome 21

Ошибка ввода данных в Chrome
Отправлено пустое поле Chrome 21

Firefox 15

Firefox 15 Дисплей
Отправлено пустое поле Firefox 15

Internet Explorer 10

Ошибка ввода данных в Internet Explorer 10
Отправлено пустое поле Internet Explorer 10

Опера 12

Ошибка ввода данных в Opera
Отправлено пустое поле Опера 12

Opera Mobile

Opera Mobile дисплей
Отправлено пустое поле Opera Mobile

Chrome для Android

Chrome для Android дисплей
Отправлено пустое поле Chrome для Android

Firefox для Android

Firefox для Android дисплей
Отправлено пустое поле Firefox для Android

Спецификация не предусматривает полного DOM API, новые атрибуты HTML, CSS и хуки можно использовать только для вида формы. API ограничение проверки добавляет следующие свойства/методы DOM узлов.

к меню ↑

Willvalidate

Свойство WillValidate определяет, нужна ли этому узлу проверка.

Для элемента submittable будет установлено значение true. Если по какой то причине узлу нужно отключить проверку полей ввода, пишем атрибут disabled.

<div id="one"></div>
  <input id="two" type="text" />
  <input id="three" type="text" disabled="disabled" />
<script>
    document.getElementById('one').willValidate; //false
    document.getElementById('two').willValidate; //true
    document.getElementById('three').willValidate; //false
</script>
к меню ↑

validity

Свойство Validity для узла DOM возвращает объект ValidityState, содержащий ряд логических свойств, относящиеся к достоверности введенных данных в поле веб-формы.

CustomError: true, если для сообщений пользователя был установлен вызов setCustomValidity().

<input id="foo" type="text" />
<input id="bar" type="text" />
<script>
    document.getElementById('foo').validity.customError; //false
    document.getElementById('bar').setCustomValidity('Invalid');
    document.getElementById('bar').validity.customError; //true
</script>

patternMismatch: true, если ввод не соответствует значению атрибута pattern.

<input id="foo" type="text" pattern="[0-9]{4}" value="1234" />
<input id="bar" type="text" pattern="[0-9]{4}" value="ABCD" />
<script>
    document.getElementById('foo').validity.patternMismatch; //false
    document.getElementById('bar').validity.patternMismatch; //true
</script>

rangeOverflow: tue, если ввод превышает значение атрибута max.

<input id="foo" type="number" max="2" value="1" />
<input id="bar" type="number" max="2" value="3" />
<script>
    document.getElementById('foo').validity.rangeOverflow; //false
    document.getElementById('bar').validity.rangeOverflow; //true
</script>

rangeUnderflow: true, если ввод имеет значение меньше чем атрибут min.

<input id="foo" type="number" min="2" value="3" />
<input id="bar" type="number" min="2" value="1" />
<script>
    document.getElementById('foo').validity.rangeUnderflow; //false
    document.getElementById('bar').validity.rangeUnderflow; //true
</script>

stepMismatch: true, если ввод не имеет значение атрибута step.

<input id="foo" type="number" step="2" value="4" />
<input id="bar" type="number" step="2" value="3" />
<script>
    document.getElementById('foo').validity.stepMismatch; //false
    document.getElementById('bar').validity.stepMismatch; //true
</script>

tooLong: true, если ввод превышает значение атрибута maxlength.

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

<input id="foo" type="text" maxlength="1" value="A" />
<input id="bar" type="text" maxlength="1" value="AB" />
<script>
    document.getElementById('foo').validity.tooLong; //false
    document.getElementById('bar').validity.tooLong; //true в Opera, false для остальных браузеров
</script>

Ожидаем значения tooLong. typeMismatch: true, для WebKit и Firefox если ввод каждого атрибута type неправильный.

<input id="foo" type="url" value="http://" />
<input id="bar" type="url" value="foo" />
<input id="foo2" type="email" value="foo@foo.com" />
<input id="bar2" type="email" value="bar" />
<script>
    document.getElementById('foo').validity.typeMismatch; //false
    document.getElementById('bar').validity.typeMismatch; //true
 
    document.getElementById('foo2').validity.typeMismatch; //false
    document.getElementById('bar2').validity.typeMismatch; //true
</script>

valueMissing: true, из-за атрибута required ввод обязательный, но поле пустое.

<input id="foo" type="text" required value="foo" />
<input id="bar" type="text" required value="" />
<script>
    document.getElementById('foo').validity.valueMissing; //false
    document.getElementById('bar').validity.valueMissing; //true
</script>

valid: true, если все условия перечисленных выше, являются false.

<input id="valid-1" type="text" required value="foo" />
<input id="valid-2" type="text" required value="" />
<script>
    document.getElementById('valid-1').validity.valid; //true
    document.getElementById('valid-2').validity.valid; //false
</script>
к меню ↑

ValidationMessage

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

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

<input id="foo" type="text" required />
<script>
    document.getElementById('foo').validationMessage;
    //Chrome  --> 'Please fill out this field.'
    //Firefox --> 'Please fill out this field.'
    //Safari  --> 'value missing'
    //IE10    --> 'This is a required field.'
    //Opera   --> ''
</script>
к меню ↑

CheckValidity ()

Метод checkValidity для элементов узла (например, input, select, textarea) возвращает true, если элемент содержит достоверные данные. Форма возвращает true, если все вводы в форме допустимые.

<form id="form-1">
  <input id="input-1" type="text" required />
</form>
<form id="form-2"><input id="input-2" type="text" /></form>
<script>
    document.getElementById('form-1').checkValidity();  //false
    document.getElementById('input-1').checkValidity(); //false
 
    document.getElementById('form-2').checkValidity();  //true
    document.getElementById('input-2').checkValidity(); //true
</script>

Каждый раз когда с помощью checkValidity действия в элементах формы не удалось проверить, для этого узла вызывается событие invalid. Если нужен узел с идентификатором input-1, можно использовать следующие:

document.getElementById('input-1').addEventListener('invalid', function() {
    //...
}, false);

novalid можно использовать для изменения уведомлений.

к меню ↑

SetCustomValidity()

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

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

if (document.getElementById('password1').value != document.getElementById('password2').value) {
    document.getElementById('password1').setCustomValidity('Пароли должны совпадать');
} else {
    document.getElementById('password1').setCustomValidity('');
}

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

Сначала нужно подключить проверку пароля onchange.

<form name="ValidationForm">
   Пароль: <input type="password" id="password1"/>
   Подтверждение пароля:<input type="password" id="password2"/>
   <input type="submit" value="submit"/>
</form>

Если пароли совпали, в качестве аргумента вызываем setCustomValidity(). Это означает, что поле пароля помечено как допустимые и поэтому при отправке формы ошибки не будет.

Если пароли не совпадают, вызываем setCustomValidity() с сообщением об ошибке в качестве аргумента. Это означает, что поле с паролем недопустимые и отобразится сообщение об ошибке.

JavaScript реализует эту логику:

<script type="text/javascript">
window.onload = function () {
    document.getElementById("password1").onchange = validatePassword;
    document.getElementById("password2").onchange = validatePassword;
}
function validatePassword(){
var pass2=document.getElementById("password2").value;
var pass1=document.getElementById("password1").value;
if(pass1!=pass2)
    document.getElementById("password2").setCustomValidity("Пароли не совпадают");
else
    document.getElementById("password2").setCustomValidity(''); // пустая строка означает отсутствие ошибок
}
</script>
к меню ↑

Атрибуты для полей ввода

Кроме атрибутов для ограничения вводимых данных: maxlength, min, max, step, pattern, и type, есть еще два дополнительные атрибуты — novalidate и formnovalidate.

к меню ↑

Novalidate

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

<form novalidate><input type="text" required />
<input type="submit" value="Отправить" /></form>
к меню ↑

Formnovalidate

Логический атрибут formnovalidate рименяется для кнопки, кторая отключит проверку данных.

Например:

<form>
  <input type="text" required />
  <input type="submit" value="Проверить" />
  <input type="submit" formnovalidate value="Не проверять" />
</form>

Если нажать кнопку Проверить, обработка формы будут остановлена из-за пустого ввода. А если нажать кнопку Не проверять, форма будет обрабатываться несмотря на неправильные данные, из-за добавленного атрибута formnovalidate.

к меню ↑

:valid, :invalid

Псевдоклассы :valid, :invalid будут действовать на все указанные ограничения для элементов формы.

<form>
  <input id="foo" type="text" required />
  <input id="bar" type="text" />
</form>
<script>
  document.querySelectorAll('input[type="text"]:invalid'); //Matches input#foo
  document.querySelectorAll('input[type="text"]:valid');   //Matches input#bar
</script>
к меню ↑

Сделать стили по умолчанию

По умолчанию Firefox для поля ставит box-shadow, IE10 красный контур outline для :invalid полей.

Firefox 15

Firefox по умолчанию отображение поля ошибки
Отображение поля ошибки в Firefox 15

Internet Explorer 10

IE10 по умолчанию отображение поля ошибки
Отображение поля ошибки в Internet Explorer 10

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

:invalid {
    box-shadow: none; /* FF */
    outline: 0;       /* IE 10 */
}