Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

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

Предпосылки: Компьютерная грамотность, разумное понимание HTML, CSS, и JavaScript.
Задача: Понимать что такое проверка формы (валидация) формы, почему это важно и как это реализовать.

Что такое валидация формы?

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

  • "Это поле обязательно для заполнения" (вы не можете оставить это поле пустым)
  • "Пожалуйста введите ваш телефонный номер в формате xxx-xxxx" (вводит три цифры разделенные тире, за ними слеуют четыре цифры)
  • "Пожалуйста введите настоящий адрес электронной почты" (если ваша запись не в формате"somebody@example.com")
  • "Ваш пароль должен быть от 8 до 30 символов длиной, и содержать одну заглавную букву, один символ, и число"

Это называется валидация формы — когда вы вводите данные,  веб-прилолжение проверяет, что данные корректны. Если данные верны, приложение позволяет данным быть отправленными на сервер и (как правило) быть сохраненными в базе данных; если нет -  оно выдает вам сообщение об ошибке, обьясняющее какие исправления необходимо внести. Проверка формы может быть реализована несколькими различными способами.

Мы хотим сделать заполнение веб-форм максимально простым. Итак, почему мы настаиваем на подтверждении наших форм? Существуют три основные причины:

  • Мы хотим получить нужные данные в нужном формате — наши приложения не будут работать должным образом, если данные нашего пользователя хранятся в неправильном формате, если они вводят неправильную информацию или вообще не передают информацию.
  • Мы хотим защитить учетные записи наших пользователей — заставляя наших пользователей вводить защищенные пароли, это упрощает защиту информации об их учетной записи.
  • Мы хотим обезопасить себя — существует множество способов, которыми злоумышленники могут злоупотреблять незащищенными формами, чтобы повредить приложение, в которое они входят (см. Безопасность веб-сайта).

Различные типы валидации формы

Существует два разных типа проверки формы, с которыми вы столкнетесь в Интернете:

  • Проверка на стороне клиента - это проверка, которая происходит в браузере, прежде чем данные будут отправлены на сервер. Это удобнее, чем проверка на стороне сервера, так как дает мгновенный ответ. Ее можно далее подразделить на:
    • JavaScript проверка выполняется с использованием JavaScript. Полностью настраиваемая.
    • Встроенная проверка формы, используя функции проверки формы HTML5. Для этого обычно не требуется JavaScript. Встроенная проверка формы имеет лучшую производительность, но она не такая настраиваемая, как с использованием JavaScript.
  • Проверка на стороне сервера - это проверка, которая возникает на сервере после отправки данных. Серверный код используется для проверки данных перед их сохранением в базе данных. Если данные не проходят проверку валидности, ответ отправляется обратно клиенту, чтобы сообщить пользователю, какие исправления должны быть сделаны. Проверка на стороне сервера не такая удобная, как проверка на стороне клиента, поскольку она не выдает ошибок до тех пор, пока не будет отправлена вся форма. Тем не менее, проверка на стороне сервера - это последняя линия защиты вашего приложения от неправильных или даже вредоносных данных. Все популярные серверные фреймворки имеют функции для проверки и очистки данных (что делает их безопасными).

В реальном мире разработчики склонны использовать комбинацию проверки на стороне клиента и сервера.

Использование встроенной проверки формы

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

Когда элемент валидный:

  • Элемент соответствует CSS псевдо-классу :valid ; это позволяет вам применить конкретный стиль к валидным элементам.
  • Если пользователь пытается отправить данные, браузер отправит форму, если нет ничего, остановит отправку (например, JavaScript).

Если элемент невалидный:

  • Элемент соответствует CSS псевдо-классу :invalid; это позволяет вам применить конкретный стиль к невалидным элементам.
  • Если пользователь пытается отправить данные, браузер заблокирует форму и выдаст сообщение об ошибке.

Ограничения проверки элементов input - простое начало

В этом разделе мы рассмотрим некоторые функции HTML5, которые можно использовать для проверки <input> элементов.

Начнем с простого примера - input, который позволяет вам выбирать ваш любимый плод между бананом и вишней. Он включает простой текст <input> соответствующий ярлык (label) и отправку (submit) <button>. Вы можете найти исходный код на GitHub fruit-start.html,и живой пример ниже:

Для начала сделаем копию fruit-start.htmlв новом каталоге на жестком диске.

Требуемый атрибут (required)

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

Добавьте атрибут required в ваш input, как показано ниже:

<form>
  <label for="choose">Would you prefer a banana or cherry?</label>
  <input id="choose" name="i_like" required>
  <button>Submit</button>
</form>

Также обратите внимание на CSS, включенный в файл примера:

input:invalid {
  border: 2px dashed red;
}

input:valid {
  border: 2px solid black;
}

В этом случае к input будет применяться ярко-красный пунктирный border, когда он невалидный, и более тонкая черная граница, когда он валидный. Попробуйте новое поведение в приведенном ниже примере:

Проверка с регулярными выражениями

Другой очень распространенной функцией проверки является aтрибут pattern, который ожидает Regular Expression в качестве значения. Регулярное выражение (regex) - это шаблон который используется для соответсвия комбинаций символов в текстовых строках, поэтому он идеально подходит для проверки формы (а также для многих других целей в JavaScript). Регулярные выражения довольно сложны, и мы не будем подробно разбирать их в этой статье.

Ниже приведены некоторые примеры, чтобы вы представляли себе, как они работают:

  • a — соответствует одному символу a (не b, не aa, итд.)
  • abc — соответствует a, далее b, далее  c.
  • a* — соответствует символу a, 0 или более раз (+ соответствует символу один или несколько раз).
  • [^a] — соответствует одному символу, не a.
  • a|b — соответствует одному символу a или b.
  • [abc] — соответствует одному символу a, b, или c.
  • [^abc] — соответствует одному символу кроме a, b, или c.
  • [a-z] — соответствует одному символу в диапазоне a–z, только в нижнем регистре (вы можете использовать [A-Za-z] для заглавных и прописных букв, и[A-Z] только для заглавных букв).
  • a.c — соответсвует a, за ним следует любой элемент, за ним следует c.
  • a{5} — соответствует a, 5 раз.
  • a{5,7} — соответствует a, от 5 до 7 раз, но не больше и не меньше.

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

  • [ -] — соответствует пробелу или тире.
  • [0-9] — соответствует любой цифре в диапазоне от 0 до 9.

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

  • [Ll].*k — Один символ  L, в верхнем или нижнем регистре, за ним следует ни одного или более символов любого типа за которыми следует k в нижнем регистре.
  • [A-Z][A-Za-z' -]+ — Один символ верхнего регистра, за которым следует один или несколько символов, которые представляют собой букву верхнего или нижнего регистра, тире, апостроф или пробел. Это можно использовать для проверки названия городов / городов англоязычных стран, которые должны начинаться с заглавной буквы, но не содержать других символов. Примеры из UK включая Manchester, Ashton-under-lyne, и Bishop's Stortford.
  • [0-9]{3}[ -][0-9]{3}[ -][0-9]{4} — Внутренний телефонный номер США — три цифры, затем пробел или тире, затем три цифры,затем пробел или тире, затем четыре цифры. Возможно, вам придется сделать это более сложным, поскольку некоторые люди пишут свой код области в круглых скобках, но это работает для простой демонстрации.

В любом случае, давайте реализуем пример - обновим ваш HTML, чтобы добавить атрибут шаблона, например:

<form>
  <label for="choose">Would you prefer a banana or a cherry?</label>
  <input id="choose" name="i_like" required pattern="banana|cherry">
  <button>Submit</button>
</form>

В этом примере <input> элемент принимает одно из двух возможных значений: строку "banana" или строку "cherry".

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

Примечание: Некоторые <input> типы элементов не нуждаются в атрибуте pattern чтобы быть валидными. Указание типа email например, проверяет введенное значение через регулярное выражение, соответствующее хорошо сформированному адресу электронной почты (или списку email адресов, разделенных запятыми, если в нем присутствует атрибут multiple attribute). В качестве еще одного примера, поле с типом url автоматически требует правильно сформированного URL.

Примечание: Элемент <textarea> не поддерживает атрибут pattern.

Ограничение длины ваших записей

Все текстовые поля, созданные с помочью элементов (<input> или  <textarea>) могут быть ограничены по размеру, используя атрибуты minlength иmaxlength. Поле невалидно если его значение короче чем minlength или значение длиннее значения maxlength. Браузеры часто не позволяют пользователю вводить более длинное значение, чем ожидалось, в текстовые поля в любом случае, но полезно иметь этот мелкозернистый элемент управления.

Для числовых полей (например <input type="number">), атрибуты min и max также обеспечивают ограничение валидации. Если значение поля меньше атрибута min или больше атрибута max, поле будет невалидным.

Давайте посмотрим на другой пример. Создайте новую копию файла fruit-start.html.

Теперь удалите содержимое элемента <body>, и замените его следующим:

<form>
  <div>
    <label for="choose">Would you prefer a banana or a cherry?</label>
    <input id="choose" name="i_like" required minlength="6" maxlength="6">
  </div>
  <div>
    <label for="number">How many would you like?</label>
    <input type="number" id="number" name="amount" value="1" min="1" max="10">
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
  • Здесь вы увидите, что мы задали полю text minlength maxlength равную 6 — такая же длина, как banana и cherry. Ввод меньшего количества символов будет отображаться как невалидный, а вводить больше в большинстве браузеров невозможно.
  • Мы также дали полю number min 1 и max 10 - числа введенные вне этого диапазона будут отображаться как невалидные, и вы не сможете использовать стрелки приращения / уменьшения, чтобы переместить значение за пределами этого диапазона.

Вот живой пример:

Примечание: <input type="number"> (и другие типы, например range) могут также содержать атрибут step который указывает, какой инкремент будет увеличиваться или уменьшаться, когда используются элементы управления входом (например, номерные кнопки вверх и вниз)

Полный пример

Вот полный пример, чтобы показать использование встроенных функций проверки HTML:

<form>
  <p>
    <fieldset>
      <legend>Title<abbr title="This field is mandatory">*</abbr></legend>
      <input type="radio" required name="title" id="r1" value="Mr"><label for="r1">Mr.</label>
      <input type="radio" required name="title" id="r2" value="Ms"><label for="r2">Ms.</label>
    </fieldset>
  </p>
  <p>
    <label for="n1">How old are you?</label>
    <!-- The pattern attribute can act as a fallback for browsers which
         don't implement the number input type but support the pattern attribute.
         Please note that browsers that support the pattern attribute will make it
         fail silently when used with a number field.
         Its usage here acts only as a fallback -->
    <input type="number" min="12" max="120" step="1" id="n1" name="age"
           pattern="\d+">
  </p>
  <p>
    <label for="t1">What's your favorite fruit?<abbr title="This field is mandatory">*</abbr></label>
    <input type="text" id="t1" name="fruit" list="l1" required
           pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
    <datalist id="l1">
      <option>Banana</option>
      <option>Cherry</option>
      <option>Apple</option>
      <option>Strawberry</option>
      <option>Lemon</option>
      <option>Orange</option>
    </datalist>
  </p>
  <p>
    <label for="t2">What's your e-mail?</label>
    <input type="email" id="t2" name="email">
  </p>
  <p>
    <label for="t3">Leave a short message</label>
    <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
  </p>
  <p>
    <button>Submit</button>
  </p>
</form>
body {
  font: 1em sans-serif;
  padding: 0;
  margin : 0;
}

form {
  max-width: 200px;
  margin: 0;
  padding: 0 5px;
}

p > label {
  display: block;
}

input[type=text],
input[type=email],
input[type=number],
textarea,
fieldset {
/* требуется для правильной формы формы
    элементов в браузерах на основе WebKit*/
  -webkit-appearance: none;
  
  width : 100%;
  border: 1px solid #333;
  margin: 0;
  
  font-family: inherit;
  font-size: 90%;
  
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

input:invalid {
  box-shadow: 0 0 5px 1px red;
}

input:focus:invalid {
  outline: none;
}

Индивидуальные сообщения об ошибках

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

Эти автоматизированные сообщения имеют два недостатка:

  • Нет стандартного способа изменить внешний вид используя CSS.
  • Они зависят от языка браузера, что означает, что у вас может быть страница на одном языке, но сообщение об ошибке отображаться на другом языке.
Французская версия сообщений обратной связи на странице на английском языке
Браузер Отображение
Firefox 17 (Windows 7) Example of an error message with Firefox in French on an English page
Chrome 22 (Windows 7) Example of an error message with Chrome in French on an English page
Opera 12.10 (Mac OSX) Example of an error message with Opera in French on an English page

Чтобы настроить внешний вид и текст этих сообщений, вы должны использовать JavaScript; нет способа сделать это, используя только HTML и CSS.

HTML5 предоставляет API проверки ограничений (API - Application Programing interface, программный интерфейс приложения, англ.) для проверки и настройки состояния элемента формы. Помимо прочего, можно зменить текст сообщения об ошибке. Давайте посмотрим на небольшой пример:

<form>
  <label for="mail">I would like you to provide me an e-mail</label>
  <input type="email" id="mail" name="mail">
  <button>Submit</button>
</form>

В JavaScript вы вызываете метод setCustomValidity():

var email = document.getElementById("mail");

email.addEventListener("input", function (event) {
  if (email.validity.typeMismatch) {
    email.setCustomValidity("I expect an e-mail, darling!");
  } else {
    email.setCustomValidity("");
  }
});

Проверка форм с использованием JavaScript

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

API проверки валидности HTML5

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

Свойства API проверки валидности

Свойство Описание
validationMessage Локализованное сообщение, описывающее ограничения валидности, которым элемент управления не соответствует (если есть), или пустая строка, если элемент управления не является кандидатом для проверки ограничений (willValidate is false), или значение элемента удовлетворяет его ограничениям.
validity объект ValidityState , описывающий состояние действительности элемента.
validity.customError Возвращает true если элемент содержит пользовательскую ошибку; false в противном случае.
validity.patternMismatch Возвращает true если значение элемента не соответствует предоставленному шаблону; false в противном случае.

если возвращает true, элемент будет соответствовать CSS псевдо-классу :invalid.
validity.rangeOverflow Возвращает true если значение элемента выше заданного максимума; false в противном случае.

Если возвращает true, элемент будет соответствовать :invalid и CSS псевдо-классу. :out-of-range.
validity.rangeUnderflow Возвращаетtrue если значение элемента меньше заданного минимума; false в противном случае.

Если возвращает true, элемент будет соответствовать :invalid и CSS псевдо-классу :out-of-range.
validity.stepMismatch Возвращаетtrue, если значение элемента не соответствует правилам, предоставляемым атрибутом step; в противном случае false .

Если возвращает true, элемент будет соответствовать :invalid и CSS псевдоклассу :out-of-range.
validity.tooLong Возвращает true если значение элемента больше заданной максимальной длины; иначе будет false

Если возвращает true, элемент будет соответствовать :invalid и CSS псевдоклассу :out-of-range.
validity.typeMismatch Возвращает true если значение элемента не соответствует правильному синтаксису; в противном случае - false.
Если возвращает true, элемент будет соответствовать CSS псевдоклассу :invalid.
validity.valid Возвращае true если значение элемента не имеет проблем с валидностью; в противном случае false.

Если возвращает true, элемент будет соответствовать CSS псевдоклассу :valid ; CSS псевдоклассу :invalid в противном случае.
validity.valueMissing Возвращает true если элемент не имеет значения, но является обязательным полем; в противном случае false.

Если возвращает true, элемент будет соответствовать CSS псевдоклассу :invalid.
willValidate Возвращает true если элемент будет проверен при отправке формы; в противном случае false.

Методы API проверки ограничений

Метод Описание
checkValidity() Возвращает true если значение элемента не имеет проблем с валидностью; иначе false. Если элемент невалидный, этот метод также вызывает событие invalid в элементе .
setCustomValidity(message) Добавляет настраиваемое сообщение об ошибке в элемент; если вы установили собственное сообщение об ошибке, элемент считается невалидным, и отображается указанная ошибка. Это позволяет использовать код JavaScript для установления ошибки валидации, отличного от тех, которые предлагаются стандартным API ограничений валидности. Сообщение показывается пользователю при возникновении проблемы.

Если аргументом является пустая строка, пользовательская ошибка очищается.

Для устаревших браузеров можно использовать полифилл как Hyperform чтобы компенсировать отсутствие поддержки API ограничений валидности. Поскольку вы уже используете JavaScript, использование полифилла не является дополнительным бременем для вашего веб-сайта или дизайна или реализации веб-приложения.

Пример использования API проверки ограничений

Давайте посмотрим, как использовать этот API для создания настраиваемых сообщений об ошибках. Сначала HTML:

<form novalidate>
  <p>
    <label for="mail">
      <span>Please enter an email address:</span>
      <input type="email" id="mail" name="mail">
      <span class="error" aria-live="polite"></span>
    </label>
  </p>
  <button>Submit</button>
</form>

Эта простая форма использует атрибут novalidate для отключения автоматической валидации браузера, что позволяет нашему скрипту контролировать валидацию. Однако это не отключает поддержку API ограничений валидации или применения псевдоклассов CSS :valid, :invalid, :in-range и :out-of-range. Это означает, что, хотя браузер не проверяет правильность формы перед отправкой своих данных, вы все равно можете сделать это самостоятельно и соответствующим образом сформировать форму.

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

CSS

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

/* Это просто, чтобы сделать пример более приятным */
body {
  font: 1em sans-serif;
  padding: 0;
  margin : 0;
}

form {
  max-width: 200px;
}

p * {
  display: block;
}

input[type=email]{
  -webkit-appearance: none;

  width: 100%;
  border: 1px solid #333;
  margin: 0;

  font-family: inherit;
  font-size: 90%;

  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/* Наш стиль для невалидных полей */
input:invalid{
  border-color: #900;
  background-color: #FDD;
}

input:focus:invalid {
  outline: none;
}

/* Это стиль для сообщений об ошибке */
.error {
  width  : 100%;
  padding: 0;
 
  font-size: 80%;
  color: white;
  background-color: #900;
  border-radius: 0 0 5px 5px;
 
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.error.active {
  padding: 0.3em;
}
JavaScript

Следующий код JavaScript обрабатывает выборочную проверку ошибок.

//Существует много способов выбрать DOM узел; здесь мы получаем форму и электронную почту
//поле ввода, а также элемент span, в который мы поместим сообщение об ошибке.
var form  = document.getElementsByTagName('form')[0];
var email = document.getElementById('mail');
var error = document.querySelector('.error');

email.addEventListener("input", function (event) {
 // Каждый раз, когда пользователь вводит что-либо, мы проверяем,
  // является ли корректным поле электронной почты.
  if (email.validity.valid) {
    // В случае появления сообщения об ошибке, если поле
    // является корректным, мы удаляем сообщение об ошибке.
    error.innerHTML = ""; // Сбросить содержимое сообщения
    error.className = "error"; // Сбросить визуальное состояние сообщения
  }
}, false);
form.addEventListener("submit", function (event) {
  // Каждый раз, когда пользователь пытается отправить данные, мы проверяем
   // валидность поля электронной почты.
  if (!email.validity.valid) {
    
    // Если поле невалидно, отображается пользовательское
    // сообщение об ошибке.
    error.innerHTML = "I expect an e-mail, darling!";
    error.className = "error active";
    // И мы предотвращаем отправку формы путем отмены события
    event.preventDefault();
  }
}, false);

Вот живой результат:

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

Проверка форм без встроенного API

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

Чтобы проверить форму, вы должны задать себе несколько вопросов:

Какую проверку я должен выполнить?
Вам нужно определить, как проверить ваши данные: операции со строками, преобразование типов, регулярные выражения и т. д. Это зависит от вас. Просто помните, что данные формы всегда являются текстовыми и всегда предоставляются вашему скрипту как строки.
Что делать, если форма не проверяется?
Это явно вопрос интерфейса. Вы должны решить, как будет выглядеть форма: формально ли отправляет данные? Должны ли вы выделять поля, которые содержат ошибки? Должны отображаться сообщения об ошибках?
Как я могу помочь пользователю исправить невалидные данные?
Чтобы уменьшить разочарование пользователя, очень важно предоставить как можно больше полезной информации, чтобы помочь им в исправлении их исходных данных. Вы должны предлагать предварительные предложения, чтобы они знали, что ожидается, а также ясные сообщения об ошибках. Если вы хотите вникнуть в требования к пользовательскому интерфейсу проверки формы, есть некоторые полезные статьи, которые вы должны прочитать:

Пример, который не использует API валидации ограничений

Чтобы проиллюстрировать это, давайте перестроим предыдущий пример, чтобы он работал с устаревшими браузерами:

<form>
  <p>
    <label for="mail">
        <span>Please enter an email address:</span>
        <input type="text" class="mail" id="mail" name="mail">
        <span class="error" aria-live="polite"></span>
    </label>
  <p>
  <!-- Some legacy browsers need to have the `type` attribute
       explicitly set to `submit` on the `button`element -->
  <button type="submit">Submit</button>
</form>

Как вы можете видеть, HTML почти такой же; мы просто удалили функции проверки HTML. Обратите внимание, что ARIA является независимой спецификацией, которая специально не связана с HTML5.

CSS

Аналогично, CSS не нужно сильно менять; мы просто переводим CSS-псевдокласс :invalid в настоящий класс и избегаем использования селектора атрибутов, который не работает в Internet Explorer 6.

/* This is just to make the example nicer */
body {
  font: 1em sans-serif;
  padding: 0;
  margin : 0;
}

form {
  max-width: 200px;
}

p * {
  display: block;
}

input.mail {
  -webkit-appearance: none;

  width: 100%;
  border: 1px solid #333;
  margin: 0;

  font-family: inherit;
  font-size: 90%;

  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/* This is our style for the invalid fields */
input.invalid{
  border-color: #900;
  background-color: #FDD;
}

input:focus.invalid {
  outline: none;
}

/* This is the style of our error messages */
.error {
  width  : 100%;
  padding: 0;
 
  font-size: 80%;
  color: white;
  background-color: #900;
  border-radius: 0 0 5px 5px;
 
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.error.active {
  padding: 0.3em;
}
JavaScript

Большие изменения в коде JavaScript, которые должны сделать намного больше тяжелой работы.

// Существует меньше способов выбрать узел DOM с устаревшими браузерами
var form  = document.getElementsByTagName('form')[0];
var email = document.getElementById('mail');

// Ниже приведен трюк для достижения следующего узла Element Element в DOM
// Это опасно, потому что вы можете легко построить бесконечный цикл.
// В современных браузерах вам следует использовать элемент element.nextElementSibling
var error = email;
while ((error = error.nextSibling).nodeType != 1);

// As per the HTML5 Specification
var emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;

// Многие устаревшие браузеры не поддерживают метод addEventListener.
// Вот простой способ справиться с этим; это далеко не единственный.
function addEvent(element, event, callback) {
  var previousEventCallBack = element["on"+event];
  element["on"+event] = function (e) {
    var output = callback(e);

    // Обратный вызов, который возвращает `false`, останавливает цепочку обратного вызова
     // и прерывает выполнение обратного вызова события.
    if (output === false) return false;

    if (typeof previousEventCallBack === 'function') {
      output = previousEventCallBack(e);
      if(output === false) return false;
    }
  }
};

// Теперь мы можем перестроить наше ограничение валидации
// Поскольку мы не полагаемся на псевдо-класс CSS, мы должны
// явно установить допустимый / недопустимый класс в поле электронной почты
addEvent(window, "load", function () {
// Здесь мы проверяем, пусто ли поле (помните, что поле не требуется)
   // Если это не так, мы проверяем, является ли его контент корректным адресом электронной почты.
  var test = email.value.length === 0 || emailRegExp.test(email.value);

  email.className = test ? "valid" : "invalid";
});

// Это определяет, что происходит, когда пользователь вводит в поле
addEvent(email, "input", function () {
  var test = email.value.length === 0 || emailRegExp.test(email.value);
  if (test) {
    email.className = "valid";
    error.innerHTML = "";
    error.className = "error";
  } else {
    email.className = "invalid";
  }
});

// Это определяет, что происходит, когда пользователь пытается отправить данные
addEvent(form, "submit", function () {
  var test = email.value.length === 0 || emailRegExp.test(email.value);

  if (!test) {
    email.className = "invalid";
    error.innerHTML = "I expect an e-mail, darling!";
    error.className = "error active";

    // Некоторые устаревшие браузеры не поддерживают метод event.preventDefault ()
    return false;
  } else {
    email.className = "valid";
    error.innerHTML = "";
    error.className = "error";
  }
});

Результат выглядит следующим образом:

Как вы можете видеть, создать собственную систему проверки не сложно. Трудная часть состоит в том, чтобы сделать его достаточно общим, чтобы использовать его как в кросс-платформенной, так и в любой форме, которую вы могли бы создать. Существует множество библиотек для проверки формы; вы не должны колебаться, чтобы использовать их. Вот несколько примеров:

Удаленная проверка

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

Выполнение такой проверки требует принятия нескольких мер предосторожности:

  • Для этого требуется публиковать API и некоторые данные; убедитесь, что это не конфиденциальные данные.
  • Сетевое отставание требует выполнения асинхронной проверки. Это требует некоторой работы пользовательского интерфейса, чтобы быть уверенным, что пользователь не будет заблокирован, если проверка не будет выполнена должным образом.

Заключение

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

  • Отображать явные сообщения об ошибках.
  • Будьте правдоподобны в отношении формата ввода.
  • Укажите, где именно происходит ошибка (особенно на больших формах).

В этом модуле

Метки документа и участники

Внесли вклад в эту страницу: LbIdarka, ivandoroshenko
Обновлялась последний раз: LbIdarka,