Валидация форм

83

»» В данной статье используется исходный код для примеров. Сохраните эту страницу для тестирования приведенных ниже примеров.

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

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

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

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

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

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

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

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

Настройка параметров проверки

Первое, что вы должны сделать — это добавить в документ подключаемый модуль Validation, как показано ниже:

...
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="jquery.validate.js"></script>
...

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

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

$(function() {
	
    $('form').validate({
        highlight: function(element, errorClass) {
            $(element).add($(element).parent()).addClass("invalidElem");
        },
        unhighlight: function(element, errorClass) {
            $(element).add($(element).parent()).removeClass("invalidElem");
        },
        errorElement: "div",
        errorClass: "errorMsg"
    });
		
});

Здесь задаются значения четырех параметров (highlight, unhighlight, errorElement и errorClass), назначение которых мы обсудим позднее.

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

В примере, представленном в примере ниже, создается одно правило:

$(function() {
	
    $('form').validate({
        highlight: function(element, errorClass) {
            $(element).add($(element).parent()).addClass("invalidElem");
        },
        unhighlight: function(element, errorClass) {
            $(element).add($(element).parent()).removeClass("invalidElem");
        },
        errorElement: "div",
        errorClass: "errorMsg"
    });
	
    $.validator.addClassRules({
        flowerValidation: {
            min: 0
        }
    })
		
});

В данном случае создается правило, которое будет применяться ко всем элементам, принадлежащим классу flowerValidation. Правило состоит в том, что значение должно быть больше или равно 0. Данное условие выражено в правиле путем указания контрольной проверки min. Это лишь один из многих удобных предопределенных видов контрольной проверки, предоставляемых модулем Validation, и все они будут описаны далее.

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

$(function() {
	
    ...
	
    $('input').addClass("flowerValidation").change(function(e) {
        $('form').validate().element($(e.target));
    });
		
});

Здесь также используется функция, привязанная к событию change. Она непосредственно выполняет проверку элемента, значение которого было изменено. Это гарантирует немедленную обратную связь с пользователем в случае исправления им ошибки.

Также необходимо добавить CSS-правила в разметку документа, для классов, идентифицирующих ошибки:

div.errorMsg {color: red}
.invalidElem {border: medium solid red}

Результат работы подключаемого модуля Validation представлен на рисунке:

Использование подключаемого модуля Validation

Для получения рисунка я ввел -1 в поле ввода и щелкнул на кнопке "Заказать". Текст сообщения, выводимого для пользователя, генерируется модулем проверки. О возможности изменения текста сообщений говорится далее.

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

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

Подключаемый модуль Validation поддерживает большое количество встроенных проверок данных, введенных в полях формы. С одним из них (min) вы уже познакомились в предыдущем примере. Полный список встроенных проверок представлен в таблице ниже:

Встроенные проверки, предусмотренные в модуле Validation
Проверка Описание
creditcard: true Значение должно содержать номер кредитной карты
date: true Значение должно быть действительной датой JavaScript
digits: true Значение должно содержать лишь цифры
email: true Значение должно быть действительным адресом электронной почты
max: maxVal Значение не должно превышать maxVal
maxlength: length Значение должно содержать не более length символов
min: minVal Значение не должно быть меньше minVal
minlength: length Значение должно содержать не менее length символов
number: true Значение должно быть десятичным числом
range: [minVal, maxVal] Значение должно находиться в пределах указанного диапазона
rangelength: [minLen, maxLen] Значение должно содержать не менее minLen и не более maxLen символов
required: true Значение обязательно должно быть указано
url: true Значение должно быть URL-адресом

Несколько правил могут быть объединены в одно. Тем самым обеспечиваются компактность и наглядность кода, осуществляющего проверку. Эти правила могут применяться к элементам несколькими способами. Все они описаны в следующих разделах.

Применение правил проверки на основании принадлежности классам

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

$(function() {
	
    $('form').validate({
        highlight: function(element, errorClass) {
            $(element).add($(element).parent()).addClass("invalidElem");
        },
        unhighlight: function(element, errorClass) {
            $(element).add($(element).parent()).removeClass("invalidElem");
        },
        errorElement: "div",
        errorClass: "errorMsg"
    });
	
    $.validator.addClassRules({
        flowerValidation: {
			required: true,
			digits: true,
			min: 0,
			max: 100
        }
    })
	
    $('input').addClass("flowerValidation").change(function(e) {
        $('form').validate().element($(e.target));
    });
		
});

В этом примере проверки required, digits, min и max объединены в одно правило, позволяющее убедиться в том, что предоставленное пользователем значение является обязательным для ввода, включает только цифры и находится в интервале от 0 до 100.

Обратите внимание на то, что для связывания правила с классом используется метод addClassRules(). Аргументами этого метода являются один или несколько наборов проверок и имя класса, к которому они применяются. Как видно из примера, метод addClassRules() вызывается для свойства validator основной функции jQuery $().

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

Одновременное применение нескольких видов проверки к элементам формы

Здесь введено несколько значений, каждое из которых не проходит одного из видов проверки. Важно отметить, что проверки выполняются в том порядке, в каком они определены в правиле. Если вы посмотрите на сообщение для продукта "Пион", то увидите, что оно не прошло проверку digits. Изменив порядок определения проверок, вы получите другое сообщение.

Применение правил проверки непосредственно к элементам

Следующая методика позволяет применять правила к определенным элементам, как показано в примере ниже:

...
   
    $.validator.addClassRules({
        flowerValidation: {
			required: true,
			digits: true,
            min: 0,
			max: 100
        }
    })
	
    $('#row1 input').each(function(index, elem) {
        $(elem).rules("add", {
            min: 10,
            max: 20
        })
    });
    
...

Обратите внимание: мы вызываем метод, определяющий правила, для объекта jQuery и передаем ему строку add и объект отображения данных с видами проверок, которые хотим выполнить, и их аргументами. Метод rules() воздействует лишь на первый элемент выбранного набора, и поэтому для расширения сферы его действия мы должны использовать метод each(). В данном случае выбираются все элементы input, являющиеся потомками элемента row1, к которым и применяются указанные проверки.

При вызове метода rules() можно добавлять и удалять отдельные проверки, используя соответственно методы add() и remove().

Правила, применяемые к элементам с использованием методов rules(), интерпретируются до того, как будут интерпретироваться правила, применяемые с использованием классов. В контексте нашего примера это означает, что элементы верхнего ряда будут проверяться с использованием значения min, равного 10, и значения max, равного 20, в то время как к другим элементам input будут применяться соответственно значения 0 и 100. Результат представлен на рисунке:

Применение правил непосредственно к элементам

Изменение диагностических сообщений проверки

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

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

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

...
   
    $.validator.addClassRules({
        flowerValidation: {
			required: true,
			digits: true,
            min: 0,
			max: 100
        }
    })
	
    $('#row1 input').each(function(index, elem) {
        $(elem).rules("add", {
            min: 10,
            max: 20,
			messages: {
				max: "Вы заказали больше 20 цветов",
				min: "Вы заказали меньше 10 цветов"
			}
        })
    });
    
...
Определение сообщений, получаемых из объекта данных
Пройди тесты
Лучший чат для C# программистов