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

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

JavaScript, представленный немного ниже, позволяет выполнять автоматическую проверку на стороне клиента. Чтобы воспользоваться этим кодом, достаточно просто подключить его к HTML-странице, определить CSS-стили для выделения полей, содержащих некорректную информацию, и добавить дополнительные атрибуты к элементам формы. Чтобы сделать поле обязательным к заполнению, достаточно просто добавить к нему атрибут required. Чтобы выполнить проверку правильности с помощью регулярного выражения, следует добавить атрибут pattern и присвоить ему текст регулярного выражения.

<script src="validate.js"></script> <!-- Подключить модуль проверки -->
<style type="text/css">
/*
Validate.js требует, чтобы были определены стили класса "invalid"
для отображения полей с некорректными данными, давая тем самым
пользователю отличать их визуально.
Для полей с корректными данными можно также определить необязательные стили.
*/
input.invalid { background: #faa } /* Красноватый фон для полей с ошибками */
input.valid { background: #afa } /* Зеленовытый фон для полей, заполненных правильно */
</style>
<!--
Теперь, чтобы включить проверку полей формы, нужно просто
установить атрибут required или pattern.
-->

<form>
<!-- Это поле должно быть заполнено -->
Имя: <input type="text" name="name" required /><br/>
<!--
\s* - означает необязательный пробел
\w+ - один или более алфавитно-цифровых символов
-->

Электронная почта: <input type="text" name="email" pattern="^\s*\w+@\w+\.\w+\s*" /><br/>
<!-- \d{6} означает, что должно быть введено ровно шесть цифр -->
Почтовый индекс: <input type="text" name="zip" pattern="^\s*\d{6}\s*" /><br/>
<!-- Следующее поле не проверяется -->
Непроверяемое поле: <input type="text" /><br/>
<input type="submit" value="Отправить" />
</form>

Обратите внимание: при подключении файла validate.js к HTML-файлу в глобальное пространство имен не добавляется ни одного имени, кроме того, скрипт автоматически регистрирует обработчик события onload, который выполняет обход всех форм документа, отыскивает поля с атрибутами required и pattern и в случае необходимости добавляет обработчики событий onchange и onsubmit. Эти обработчики устанавливают значение свойства className каждого элемента формы, который подвергается проверке, в значение “invalid” или “valid”, поэтому необходимо предусмотреть определение хотя бы “неправильного” (invalid) CSS-класса, чтобы обеспечить визуальное отличие полей с корректными и некорректными данными.

/**
validate.js: ненавязчивая проверка HTML-форм.

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

Если атрибут формы имеет атрибут "pattern", значение этого атрибута
используется регулярное JavaScript-выражение, а элементу назначается
обработчик события onchange, который проверяет ввод пользователя с помощью
этого шаблона. Если данные не соответствуют шаблону, цвет фона элемента
ввода изменяется, чтобы привлечь внимание пользователя.

По умолчанию текстовое поле должно содержать некоторую подстроку, которая
соответствует шаблону. Если требуется указать более строгое соответствие,
используйте якорные элементы ^ и $ в начале и конце шаблона.

Элемент формы с атрибутом "required" должен содержать какое-либо значение.
Если быть более точным, атрибут "reqiured" является краткой формой атрибута
pattern="\S". То есть этот атрибут требует, чтобы поле содержало хотя бы
один символ, отличный от пробела.

Если элемент формы прошел проверку, в атрибут "class" этого элемента
записывается значение "valid". В противном случае - значение "invalid".
Для коррекной работы validate.js необходимо вместе с ним использовать
таблицу CSS-стилей, где определяются стили для "неправильного" класса.
Например

<!-- Для привлечения внимания окрасить фон элементов формы,
     содержащих ошибки, в оранжевый цвет -->
<style type="text/css">input.invalid {background: #fa0; }</style>

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

Этот код не может использоваться для проверки форм или полей, в которых
вы определили собственный обработчик событий onchange или onsubmit,
а также полей, для которых вы определили свое значение атрибута class.

Весь программный код размещается внутри анонимной функции
и не определяет ни одного имени в глобальном пространстве имен.
**/


(function() { // Все, что требуется, выполняется внутри анонимной функции
    // По окончании загрузки документа вызвать функцию init()
    if (window.addEventListener)
        window.addEventListener("load", init, false);
    else if (window.attachEvent)
        window.attachEvent("onload", init);

    // Устанавливает обработчики событий для форм и элементов форм,
    // где это необходимо
    function init() {
        // Цикл по всем формам в документе
        for(var i = 0; i < document.forms.length; i++) {
            var f = document.forms[i]// текущая форма

            // Предположить, что форма не требует проверки
            var needsValidation = false;

            // Цикл по всем элементам текущей формы
            for(j = 0; j < f.elements.length; j++) {
                var e = f.elements[j]// текущий элемент

                // Интерес представляют только поля <input type="text">
                if (e.type != "text") continue;

                // Проверить, имеются ли атрибуты, требующие проверки
                var pattern = e.getAttribute("pattern");
                // Можно было бы использовать e.hasAttribute()
                // но MS IE не поддерживает его
                var required = e.getAttribute("required") != null;

                // Атрибут required - это лишь краткая форма записи
                // атрибута pattern
                if (required && !pattern) {
                    pattern = "\\S";
                    e.setAttribute("pattern", pattern);
                }

                // Если элемент требует проверки,
                if (pattern) {
                    // проверять при каждом изменении содержимого элемента
                    e.onchange = validateOnChange;
                    // Запомнить, чтобы потом добавить обработчик onsubmit
                    needsValidation = true;
                }
            }

            // Если хотя бы один элемент формы требует проверки,
            // то необходимо установить обработчик события onsubmit формы
            if (needsValidation) f.onsubmit = validateOnSubmit;
        }
    }
         
    // Эта функция - обработчик события onchange для текстового поля, которое
    // требует проверки. Не забывайте, что в функции init() мы преобразовали
    // атрибут required в pattern
    function validateOnChange() {
        var textfield = this;                            // текстовое поле
        var pattern = textfield.getAttribute("pattern"); // шаблон
        var value = this.value;                          // данные, введенные пользователем

        // Если значение не соответствует шаблону, установить
        // значение атрибута сдфыы равным "invalid"
        if (value.search(pattern) == -1) textfield.className = "invalid";
        else textfield.className = "valid";
    }

    // Эта функция - обработчик события onsubmit для любой формы,
    // требующей проверки
    function validateOnSubmit() {
        // Перед отправкой формы выполнить проверку всех полей в форме
        // и установить их свойства className в соответствующее значение.
        // Если хотя бы одно из этих полей содержит ошибку, вывести диалоговое
        // окно и заблокировать отправку данных формы.
        var invalid = false// Предполагаем, что все правильно
        // Цикл по всем элементам формы
        for(var i = 0; i < this.elements.length; i++) {
            var e = this.elements[i];
            // Если элемент - это текстовое поле, для которого установлен
            // наш обработчик события onchange
            if (e.type == "text" && e.onchange == validateOnChange) {
                e.onchange(); // Вызвать обработчик для повторной проверки
                // Если проверка не пройдена - значит вся форма не прошла проверку
                if (e.className == "invalid") invalid = true;
            }
        }

        // Если форма не прошла проверку, вывести диалоговое окно
        // и заблокировать отправку формы
        if (invalid) {
            alert("Форма заполнена не полностью или были введены некорректные данные.\n" +
                  "Пожалуйста, проверьте правильность выделенных полей и повторите попытку.");
            return false;
        }
    }
})();

Комментариев: 12

  1. admin:

    Алексей, у меня на сайте нет формы обратной связи. Если Вы говорите о комментариях, то я просто использовал плагин для WordPress. Создать защиту от спама, какая используется в комментариях, совсем не сложно. Надо записать в файл несколько вопросов и правильных ответов:
    два плюс три|5
    семь минус пять|2
    четыре плюс пять|9
    Когда формируем форму, выбираем из файла случайную запись, разделяем ее функцией explode(): $row[0] - это вопрос, который надо вывести в форме, а $row[1] - правильный ответ, который надо записать в сессию. Когда пользователь заполнит форму, мы в обработчике проверяем, совпадает ли значение, сохраненное в сессии, с тем, что ввел пользователь. Если совпадает - считаем, что это человек, если нет - значит робот.
    О том, как защитить форму с помощью картинки, я уже писал:
    Защитное изображение для HTML-формы

  2. Motorist:

    Напишите регулярное выражение для проверки поля целого числа.
    Пишу в pattern=^[\d]*$ . При заполнении формы поле не является обязательны.
    Что нужно дописать в регулярное выражение?

  3. admin:

    Motorist, не уверен, что правильно понял. Нужно чтобы поле обязательно содержало число? Тогда используйте квантор +, а не *.

  4. Motorist:

    Работает! Спасибо. Не силен в регулярных выражения.))

  5. Таня:

    А как проверить, что все нужные поля были заполнены? Если не заполнены - чтобы выводилось предупреждение.. Спасибо заранее.

  6. кадровик:

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

  7. admin:

    кадровик, боюсь, я мало что понял. Здесь нет проверки конкрентно e-mail. Но для полей формы мы можем устроить любую проверку. Или, если говорить точнее, соответствие поля формы любому шаблону. Для этого добавляем атрибут pattern=”рег.выражение” для тега <input type=”text” …/>

  8. Goss:

    Опера 9.21 пишет в красном квадратике у правильно заполненного проверяемого поля: “…is not in the format this page requires”. В других брузерах работает. Доктип не влияет.

  9. Корвин:

    не понимает мылы с тире типа : asd@asd-asd.ru

  10. admin:

    Корвин, по-моему, в заметке ясно сказано - атрибут pattern должен содержать шаблон (регулярное выражение) для проверки поля

    Электронная почта: <input type="text" name="email" pattern="^\s*\w+@\w+\.\w+\s*" />

    Замените шаблон, и будет Вам счастье.

  11. Viper:

    Классный способ! ушёл реализовывать у себя! Побольше бы таких интересных статьей!

  12. Дмитрий:

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

Оставьте свой отзыв