Валидация форм на стороне клиента
 

Проверка форм на стороне клиента с использованием JavaScript ни для кого не является новым изобретением. Но использование технологии HTML DOM возможно является таковым для многих людей. Заинтересовал? Тогда вперед!

Я предположу, что вы уже читали некоторые статьи о методах проверки правильности форм, и со стороны клиента и со стороны сервера, но этот метод имеет несколько новое направление в данной теме. То, о чем я собираюсь рассказать, это – включение объектно-ориентируемого программирования в проверку правильности форм. Этот метод работает с браузерами, которые поддерживают JavaScript и HTML DOM от W3C, типа Internet Explorer 6, Netscape 6 и Opera 6, и в некоторой степени более ранние версии. Хотя я не проверял Konqueror, но судя по его спецификациям это должно работать нормально и в нем тоже.

Предупреждение: вы должны быть относительно опытными в работе с JavaScript, чтобы полностью понять суть статьи.

Теги и объекты

Каждая форма представляет собой набор input-тегов, которые обычно имеют аттрибуты name и value. Текстовые поля ввода могут также иметь аттрибуты size и maxsize. В этой статье я добавил еще пару аттрибутов, которые вы не часто встретите: pattern и errorMsg. Эти аттрибуты не являются стандартными, но они не мешают работе броузеров. В объектно-ориентируемом программировании эти аттрибуты ведут себя подобно членам класса, а классом в этом случае является input-тег.

Обычный input-тег:

<input type="text" name="firstname" size="20" maxsize="20" />

Модифицированный input-тег:

<input type="text" name="firstname" size="20" maxsize="20" pattern="[^A-Za-z]+" errorMsg="Недопустимый символ в имени" />

Эквивалентый класс на Java:

public class Input { String type = "text"; String name = "firstname"; String size = "20"; String maxsize = "20"; String pattern = "[^A-Za-z]+"; String errorMsg = "Недопустимый символ в имени"; }

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

DOM (Объектная модель документа)

Большинство аттрибутов представлены как объекты в DHTML, но эти добавленные аттрибуты - нет. Поэтому, для того чтобы иметь возможность получить значения мы должны использовать DOM (ссылки по теме в конце статьи). Законченная HTML страница , как и в DHTML, называется document. Один из методов, доступных документу - getElementsByTagName(String). Этот метод используется для того, чтобы найти все input-теги:

var elements = document.getElementsByTagName('input');

Если бы elements был обычным объектом в JavaScript, то это был бы обычный массив, содержащий все input-теги. Но не в DOM: здесь это NodeList. В отличие от простого массива, элементом которого является myarray[i], NodeLists имеет совокупность элементов item (например elements.item(i)).

Можно пройтись по всем элементам массива, используя простой цикл for:

for (var i = 0; i < elements.length; i++) {

Настало время для аттрибута pattern:

 var pattern = elements.item(i).getAttribute('pattern');

Мы должны заставить образец этого поля смочь его (поле) проверить. В этой статье только необходимые элементы имеют аттрибут образца (проверка правильности, как всегда, выполняется регэкспами). Поэтому, мы берем значение из поля ввода и проверяем, все ли символы соответствуют образцу. Другими словами, мы ищем «неправильные» символы.

 var value = elements.item(i).value; var offendingChar = value.match(pattern);

Если мы встретим недопустимое значение, то сформируем сообщение об ошибке:

 str += elements.item(i).getAttribute('errorMsg') + "\n" + "Недопустимый символ в имени: '" + offendingChar + "' \n";

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

 elements.item(i).style.background ="red"; 

Внимательный читатель может заметить, что value в elements.item[i].value представлен как объект. Но может ли он быть доступен с помощью elements.item(i).getAttribute('value')? Нет, это только показывает значение по умолчанию (если есть такое) в теге, но не значение, введенное пользователем!

Вспомогательные функции

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

function DOMCheck() { if(!document.getElementsByTagName('html')) { alert("Извините! Ваш броузер не поддерживает W3C HTML DOM!"); } }

Эта функия проверяет, есть ли элемент html. Обратите внимание, что если <html> теги опущены, Internet Explorer будет отдавать страницу как HTML, но значение, возвращенное сценарием будет равняться нулю, таким образом давая неправильное сообщение об ошибке. Поэтому, будьте добры и всегда включайте <html> теги в ваш документ.

Во-вторых, мы должны очистить цвет фона, когда пользователь вводит новое значение в input-теги:

function changeColor(th) { //заменяем цвет фона на белый th.style.background = "white"; }

Обратите внимание, что это не работает в Опере. Этот метод вызывается из input-тега, используя обработчик события onfocus.

Исходный код

Законченный вариант кода функции валидации нашей формы выглядит так:

function validate() { var str = ""; var elements = document.getElementsByTagName('input'); // цикл по всем элементам формы for(var i = 0; i < elements.length; i++) { // проверяем, имеется ли образец var pattern = elements.item(i).getAttribute('pattern'); if (pattern != null) { var value = elements.item(i).value; // валидация значения элемента, используя образец var offendingChar = value.match(pattern); // если встечен недопустимый символ или элемент оставлен пустым if(offendingChar != null || value.length == 0) { // показываем сообщения об ошибках str += elements.item(i).getAttribute('errorMsg') + "\n" + "Найдено недопустимое значение: '" + offendingChar + "' \n"; // подсказка пользователю путем смены цвета фона; здесь красный elements.item(i).style.background = "red"; } } } if (str != "") { // не посылаем форму alert("ERROR ALERT!!\n" +str); return false; } else { // значения формы правильны; посылаем return true; } }

Дальнейшие расширения

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

Возраст: <input type="text" name="age" maxlength="2" size="2" min_reqs="18" max_reqs="30" errorMsg="Возраст должен быть в пределе 18-30 лет" />

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

 var min_reqs = elements.item(i).getAttribute('min_reqs'); var max_reqs = elements.item(i).getAttribute('max_reqs'); if (min_reqs != null && max_reqs != null) { var value = elements.item(i).value; if (value < min_reqs || value > max_reqs) { str += elements.item(i).getAttribute('errorMsg') + '\n'; } }

Заключение

Стоит ли идти этим путем? Возможно не сейчас, но в самом ближайшем будущем, когда все или большинство пользователей будут использавать современные браузеры. Безусловно есть и другие выгоды от наличия объединенной модели объектов (DOM) для браузеров, но надеюсь этот небольшой совет поможет некоторым веб-мастерам сделать себе жизнь более легкой.

Ссылки по теме:
Internet Explorer 6, Part I: DOM Standards Support
Regular Expressions

 
Автор: Denveroid
 
Оригинал статьи: http://www.woweb.ru/publ/62-1-0-347