Валидация полей произвольных форм и контейнеров на jQuery

Валидация полей произвольных форм и контейнеров на jQuery

Вам когда-нибудь приходилось искать скрипты и плагины для валидации произвольных форм и контейнеров? Когда тэг "form" не используемая конструкция? И когда необходимо проверять корректность полей в любое время, а не по зашитым концептуальным механизмам? Можно долго спорить о необходимости соблюдать стандартны и поддерживать отправку данных через полную перезагрузку страницы. Тем не менее, сегодня, большинство web-приложений уже не возможно представить без поддержки javascript-a. Отключите javascript - и сервисы станут бесполезными, несмотря на то, что вы сможете зарегистрироваться, войти и пройтись по нескольким страницам.

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

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

 

Рассмотрим существующие плагины для валидации форм на jQuery

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

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

  • Жесткая привязка к тэгу "form". Поэтому если у вас есть несколько десятков форм, построенных на div-ах или таблицах, и вы твердо решили использовать популярные решения, то готовьтесь потратить кучу времени на ручное добавление тегов и корректировку скриптов и стилей.  
  • Привязка к именам полей. Некоторые валидаторы привязываются к названиям полей, а это значит написание простыней javasript-а для каждого случая. Если для пары форм это не страшно, то для коллекции это уже означает длительную ручную генерацию кода.
  • Отсутствие валидации по требованию, без необходимости инициализации плагина. Вы не можете взять и один раз вручную проверить форму. Нужно правильно составить форму (правда, это везде нужно, но суть не в этом), затем инициализировать движок плагина, который в обязательном порядке привяжет кучу скриптов к элементам формы. И уже после этого вызвать метод isValid, который не всегда доступен в явном виде. Иногда, этот метод еще нужно "как-то" вытащить из внутренних механизмов.

Примечание: С одной стороны, вполне логично, что привязка идет к тегу форм, так как плагины появились "после". С другой стороны, сегодня скрипты позволяют быстро создавать и собирать данные из любых произвольных форм. При определенном уровне любопытства и настойчивости, вы можете легко создать форму только на тэгах "span"(div) и "input", при этом выглядеть она будет точно так же, как и все другие.

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

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

Если раньше красивая анимация и навороченный механизм сами по себе были достаточно вескими аргументами в пользу использования того или иного плагина, то сегодня это уже не совсем так. Найти готовые регулярные выражения для проверок большинства известных типов полей - задача не очень сложная. Большое число разнотипных проверок уже не столь актуально, как раньше. Стремление к минимализму форм ведет к уменьшению количества проверок. Попробуйте вспомнить, когда вы в последний раз встречали проверки, которые бы отличались от валидации текста, исключая повторение пароля? Необходимость в создании собственных валидаторов, при обилии уже готовых регулярных выражений, встречается все реже и реже. Красивая анимация и всплывающие подсказки в окошках когда-то будоражили фантазию и придавали приложениям очарование и неповторимость. Тем не менее, сегодня, достаточно пометить красным цветом хорошо известные всем поля, и большинство пользователей сами поймут, что именно необходимо исправить. 

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

 

Пишем скрипт для валидации произвольных форм на jQuery

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

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

  • Форма хранится в одном произвольном контейнере. Это может быть span, div, table и так далее. Важно то, что форма это отдельный элемент DOM. Сохранение данных с 15 разных контейнеров - это уже не обычная форма, с любой точки зрения.
  • Скрипт должен поддерживать как валидацию на лету, так и произвольную проверку любых форм или даже отдельных полей, без каких-либо привязок скриптов или других ограничений.
  • Плагин должен быть простым как с точки зрения настройки и запуска, так и с точки зрения организации и кода.
  • Необходимо, чтобы его можно было расширить в любое время. Добавить валидаторы. Встроить всплывающие сообщения. И многое другое.
  • Настройка валидаторов полей должна быть не только универсальной, но и простой

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

Примечание: К сожалению, даже обилие javascript проверок и обработчиков событий не уберегут ни одно приложение от необходимости валидации данных на серверной стороне. Помните, что можно без особых усилий составить и вызвать отправку данных практически на любом браузере. 

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

Теперь, составим тестовый проект со следующей структурой:

  • css - каталог со стилями
    • template.css - файл стилей
  • images - каталог для картинок для стилей валидации
    • icon-fail.png - иконка для некорректно заполненного поля
    • icon-ok.png - иконка для правильно заполненного поля
  • js - каталог для скриптов
    • jquery-validate.js - скрипт валидации произвольных форм
  • index.html - тестовая форма

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

Файл стилей - template.css

Большую часть файла стилей занимают стили самой формы, что бы демонстрационный пример выглядел привлекательно. Для самого же плагина нужны только первые два правила ".field-input.input-ok" и ".field-input.input-error"

Примечание: Старайтесь добавлять даже к тестовым формам хотя бы минимальны дизайн. Чем ближе тестовый проект будет к реальному, тем больше шансов отловить ошибки и скрытые проблемы. Например, картинка в "background" для проверенных полей будет занимать часть поля. Это означает, что для полей с большим объемом текста необходимо предусматривать отступы в стилях.

.field-input.input-ok{
    background: url(../images/icon-ok.png) no-repeat right center #e3ffe5;
    border: 1px solid #96b796;line-height: 19px;
}
.field-input.input-error{
    background: url(../images/icon-fail.png) no-repeat right center #ffebef;
    border: 1px solid red;line-height: 19px;
}
.clear{clear:both;}body{width: 1000px;margin:auto;}
.form{float: left;width: 490px;margin-right: 5px;}
.form .header{color: blue;font-size: 20px;font-family: georgia;margin-bottom: 10px}
.form .label{padding: 5px;padding-left: 0px;font-size: 18px;}
.form .field{margin-bottom: 10px;}
.form .field-input{padding: 5px;font-size: 15px;width: 400px;}
.form .save-button{cursor: pointer;margin-top: 10px;color: white;background: green;border: 1px solid #ddd;padding: 5px 10px;}
.form .save-button:hover{background: rgb(60, 176, 60);}

Файл скрипта валидации произвольных форм на jQuery - jquery-valiate.js 

Так как скрипт достаточно простой и в самих комментариях подробно описана вся необходимая информация, то файл приводится целиком:

 
(function (parentObject) {

    // Проверяем на повторную инициализацию

    if (parentObject.validation)

        return;

 

    ////////////////////////////////////////////////

    // Создаем общий интерфейс для валидации форм

    ////////////////////////////////////////////////

    parentObject.validation = {

        _defaultOptions: {

            // Контейнер. Может быть селектором или элементом

            container: '',

            // Селектор для поиска полей

            fieldSelector: '.field-input',

            // Проверка в режиме онлайн

            liveCheck: true,

            // Селектор для кнопок сабмита

            submitSelector: '.save-button',

            // Обработчик, который вызывается после успешной валидации

            submitHandler: null,

            // Класс полей с ошибками

            errorClass: 'input-error',

            // Класс верных полей

            okClass: 'input-ok',

            // Список валидаторов

            // Примечание: так как валидатор пустых полей вынесен отдельно,

            // то пустые строки в других валидаторах считаются как прошедшие

            validators: {

                'required': function (str) {

                    return str.length > 0;

                },

                'numeric': function (str) {

                    var regExp = new RegExp('\\-?\\d+((\\.|\\,)\\d{0,})?');

                    return regExp.test(str) || !str;

                },

                'alpha': function (str) {

                    var regExp = new RegExp('^[а-яА-ЯёЁa-zA-Z\\s]+$');

                    return regExp.test(str) || !str;

                },

                'alphanumeric': function (str) {

                    var regExp = new RegExp('^[а-яА-ЯёЁa-zA-Z0-9\\s]+$');

                    return regExp.test(str) || !str;

                },

                'date': function (str) {

                    var regExpISO = new RegExp('(19|20)\\d\\d-((0[1-9]|1[012])-(0[1-9]|[12]\\d)|(0[13-9]|1[012])-30|(0[13578]|1[02])-31)'),

                        regExpRU = new RegExp('((0[1-9]|[12]\\d)\\.(0[1-9]|1[012])|30\\.(0[13-9]|1[012])|31\\.(0[13578]|1[02]))\\.(19|20)\\d\\d');

                    return (regExpISO.test(str) | regExpRU.test(str)) || !str;

                },

                'datetime': function (str) {

                    var regExpISO = new RegExp('(19|20)\\d\\d-((0[1-9]|1[012])-(0[1-9]|[12]\\d)|(0[13-9]|1[012])-30|(0[13578]|1[02])-31) (\\d+):(\\d+)'),

                        regExpRU = new RegExp('((0[1-9]|[12]\\d)\\.(0[1-9]|1[012])|30\\.(0[13-9]|1[012])|31\\.(0[13578]|1[02]))\\.(19|20)\\d\\d (\\d+):(\\d+)');

                    return (regExpISO.test(str) | regExpRU.test(str)) || !str;

                },

                'time': function (str) {

                    var regExp = new RegExp('(\\d+):(\\d+)');

                    return regExp.test(str) || !str;

                },

                'digit': function (str) {

                    var regExp = new RegExp('^[0-9]+$');

                    return regExp.test(str) || !str;

                },

                'password': function (str) {

                    var regExp = new RegExp('^[а-яА-ЯёЁa-zA-Z0-9\\s]+$');

                    return regExp.test(str) || !str;

                },

                'email': function (str) {

                    var regExp = new RegExp('^([a-z0-9_-]+\\.)*[a-z0-9_-]+@[a-z0-9_-]+(\\.[a-z0-9_-]+)*\\.[a-z]{2,6}$');

                    return regExp.test(str) || !str;

                },

                'url': function (str) {

                    var regExp = new RegExp('^((https?|ftp)\\:\\/\\/)?([a-z0-9]{1})((\\.[a-z0-9-])|([a-z0-9-]))*\\.([a-z]{2,6})(\\/?)$');

                    return regExp.test(str) || !str;

                }

            }

        },

 

        // Функция инициализации

        // Создает каркас для форм

        init: function (_options) {

            var options = $.extend({}, this._defaultOptions, (_options || {})),

                self = this;

 

            // Если указан контейнер (или его селектор), 

            // а так же селектор для полей,

            // то создаем каркас

            if (options.container && options.fieldSelector) {

                // Если есть селектор для кнопок,

                // то вещаем обработчик на щелчек

                if (options.submitSelector) {

                    $(options.container).find(options.submitSelector).on('click', function () {

                        if (self.isValid(options)) {

                            // Если указан обработчик, после успешной валиадции,

                            // то вызываем его

                            if (typeof (options.submitHandler) === 'function')

                                options.submitHandler();

                            return true;

                        }

                        else {

                            return false;

                        }

                    });

                }

 

                // Если нужна проверка в режиме онлайн

                if (options.liveCheck) {

                    // Проходимся по всем полям и вешаем проверку валидности

                    $(options.container).find(options.fieldSelector).each(function (cnt, item) {

                        $(item).on('click', function () {

                            self.validItem($(item), options)

                        }).on('blur', function () {

                            self.validItem($(item), options)

                        }).on('change', function () {

                            self.validItem($(item), options)

                        }).on('keyup', function () {

                            self.validItem($(item), options)

                        });

                    });

                }

            }

        },

 

        // Функция для валидации отдельного элемента

        validItem: function (item, _options) {

            var options = $.extend({}, this._defaultOptions, (_options || {})),

                classList = $(item).attr('class').split(/\s+/),

                validResult = true;

            // Проходимся по всем классам в атрибуте "class", 

            // и если находим класс с именем валидатора, то вызываем его

            $.each(classList, function (index, cl) {

                // Проверка для повторяющихся полей,

                // имя поля, которое должно повториться указывается в атрибуте "confirm-field"

                if (cl === 'confirmfield') {

                    validResult 

                        &= ($(options.container).find('[Name="' + $(item).attr('confirm-field') + '"]').val()

                            == $(item).val());

                }

                // Иначе обычная проверка

                else if (typeof (options.validators[cl]) === 'function') {

                    validResult &= options.validators[cl](item.val());

                }

            });

 

            // Если поле не прошло валидацию

            if (!validResult)

                $(item).addClass(options.errorClass).removeClass(options.okClass);

            // Поле прошло валидацию

            else

                $(item).addClass(options.okClass).removeClass(options.errorClass);

 

            // Возвращаем результат

            return validResult;

        },

 

        // Проверка всех полей произвольной формы

        isValid: function (_options) {

            var options = $.extend({}, this._defaultOptions, (_options || {})),

                validResult = true,

                self = this;

            // Если указан контейнер (или его селектор), а так же селектор для полей,

            // то проверяем все поля

            if (options.container && options.fieldSelector) {

                $(options.container).find(options.fieldSelector).each(function (cnt, item) {

                    validResult &= self.validItem($(item), options);

                });

            }

 

            // Возвращаем результат проверки

            return validResult;

        },

 

        // Очищаем поля от всех классов стилей, которые были добавлены во время проверки

        clear: function (_options) {

            var options = $.extend(true, {}, this._defaultOptions, (_options || {}));

            if (options.container && options.fieldSelector) {

                $(options.container).find(options.fieldSelector)

                .removeClass(options.errorClass).removeClass(options.okClass);

            }

        }

    }

})(window);

Тестовая страница с формами - index.html

Тестовая страница достаточно проста. Ее основное пространство занимает html-код самих форм демонстрационного примера. Сам же вызов плагина для создания валидации на лету, а так же запуск ручной валидации по нажатию на кнопку, занимают всего несколько строк. 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>

    <head>

        <meta http-equiv="content-type" content="text/html; charset=utf-8">

        <link href="/css/template.css" rel="stylesheet" type="text/css"/>

 

        <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>

        <script src="/js/jquery-validate.js"></script>

    </head>

 

    <script type=text/javascript>

        $(function () {

            // Валидация через механизм

            window.validation.init({

                container: '.form-1',

                submitHandler: function () {

                    alert('Валидация первой формы прошла успешно!');

                }

            });

            

            // Ручная валидация, доступная в любой момент

            $('.form-2 .save-button').on('click', function () {

                if(window.validation.isValid({ container: '.form-2' })) {

                    alert('Валидация второй формы прошла успешно!');

                }

            });

            

        });

    </script>

 

    <body>

        <br/>

        <br/>

        <br/>

        <div class="form-1 form">

            <div class="header">Валидации формы в режиме реального времени</div>

            <div class="label">Имя</div>

            <div class="field"><input type="text" name="UserName" class="field-input required alphanumeric" /></div>

            <div class="label">Email</div>

            <div class="field"><input type="text" name="Email" class="field-input required email" /></div>

            <div class="label">Пароль (цифры, буквы и пробел)</div>

            <div class="field"><input type="password" name="Password" class="field-input required password" /></div>

            <div class="label">Подтверждение пароля</div>

            <div class="field"><input type="password" name="CheckPass" class="field-input required confirmfield" confirm-field="Password" /></div>

            <div class="label">URL</div>

            <div class="field"><input type="text" name="Url" class="field-input url" /></div>

            <div class="label">Дата форматы ГГГГ-ММ-ДД и ДД.ММ.ГГГГ</div>

            <div class="field"><input type="text" name="Date" class="field-input date" /></div>

            

            <div class="clear"></div>

            <div class="btn-panel">

                <button class="save-button" >Отправить форму </button>

            </div>

        </div>

        <div class="form-2 form">

            <div class="header">Пример ручной валидации формы</div>

            <div class="label">Имя</div>

            <div class="field"><input type="text" name="UserName" class="field-input required alphanumeric" /></div>

            <div class="label">Email</div>

            <div class="field"><input type="text" name="Email" class="field-input required email" /></div>

            <div class="label">Пароль (цифры, буквы и пробел)</div>

            <div class="field"><input type="password" name="Password" class="field-input required password" /></div>

            <div class="label">Подтверждение пароля</div>

            <div class="field"><input type="password" name="CheckPass" class="field-input required confirmfield" confirm-field="Password" /></div>

            <div class="label">URL</div>

            <div class="field"><input type="text" name="Url" class="field-input url" /></div>

            <div class="label">Дата форматы ГГГГ-ММ-ДД и ДД.ММ.ГГГГ</div>

            <div class="field"><input type="text" name="Date" class="field-input date" /></div>

            

            <div class="clear"></div>

            <div class="btn-panel">

                <button class="save-button" >Отправить форму </button>

            </div>

        </div>

 

    </body>

</html>

Теперь, сохраняем все файлы в проекте, открываем index.html в любом браузере и переходим к первичному тестированию результата.

 

Смотрим результат выполнения скрипта валидации на jQuery в тестовом проекте

После того как вы откроете файл, перед вами должна появится следующего вида страница:

Составленные формы для тестового проекта - Валидация полей произвольных форм и контейнеров на jQuery 

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

Теперь, убедимся, что валидация происходит в те моменты, когда это необходимо, и что формы никак не влияют друг на друга. Выглядеть это будет примерно так:

Тестирование форм с валидацией - Валидация полей произвольных форм и контейнеров на jQuery

Как видно, в форма слева проводилась валидация на лету. А в форме слева валидация происходила только по нажатию на кнопку "Отправить форму."

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

  • Форма хранится в одном произвольном контейнере. - Выполнено. Форма не зависит от конкретного элемента. Обрабатывает произвольный контейнер
  • Валидация как на лету, так и вручную. - Выполнено. Валидацию можно производить как на лету, так и вручную
  • Плагин должен быть простым - Выполнено. Код очень простой. Настройка форм заняла не более 5 минут. Для запуска плагина понадобилось всего пара строчек
  • Можно было расширить в любое время - Выполнено. Добавление валидаторов элементарное. Можно добавить как в опции по умолчанию, так и во время запуска плагина. Так как код простой, то добавить функциональность то же просто.
  • Настройка валидаторов должна быть универсальной и простой - Выполнено. Валидаторы указываются через классы стилей. 

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

Ссылка для скачивания плагина с тестовым проектом находится тут:

validate.zip 

☕ Понравился обзор? Поделитесь с друзьями!

Комментарии / отзывы  

0 # Юрий К. 26.03.2015 14:50
Привет.
Спасибо за великолепную статью.
Как можно прикрутить сообщение об ошибке которое показывается над или под полем ввода?
Я так понял, надо как-то прикрутить инфу из статьи "Как сделать всплывающие окна на jQuery (информеры)?", но там всё построено на кнопках, а как пименить это к валидации полей в реальном времени?
К сожалению в кодах я не силён... :-?
Во, хотя бы ка у Вас на сайте в этой форме!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь (Администратор) 26.03.2015 20:38
Нет, вы не совсем верно мыслите.
Всплывающие окна на jQuery - это не то, что нужно. Вам нужно смотреть в сторону tooltip (всплывающие подсказки). И, к сожалению, если вы не очень сильны в кодах, то будет не так просто.
Тем не менее, tooltip можно добавить в функцию validItem.
Достаточно проверять результат validResult перед отправкой.
Например:
if (!validResult) {
// Здесь идет код, который добавляет tooltip c сообщением к полю
$(item).tooltip('Заполните поле')
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Юрий К. 26.03.2015 15:24
Загрузил Ваш файл на локалхост (Winginx) Но на первое поле первой формы (имя) вообще никак не реагирует(Хром, опера, мозилла). А сайт testform/validate/ (на локалхосте) вообще валидным не считает!
Жаль нет возможности скиншот прицепить.
Эту форму в которой пишу сами написали? Есть статья как её сделать?
Или напишите как сделать скрипт внизу этого поля "осталось столько-то символов".
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь (Администратор) 26.03.2015 20:41
Первый момент, локалхост не доступен из других компьютеров, поэтому результат просто никак не увидеть.
Второй момент. Эта форма для отправки основана на модуле jComments. Поэтому немного другое.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Юрий К. 28.03.2015 02:50
Доброе утро!
Валидация заработала. у меня на инпуте висит виртуальная клавиатура. Она у меня заглючила, потом "выздоровела", и после этого всё стало работать!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Николай 13.11.2015 00:56
Спасибо за хорошую статью. На мой взгляд, все функции валидации стоило бы дополнить контролем длины строки - от минимально допустимого значения до максимально допустимого значения, вроде такого {6,18}. Минимальное может быть равно 0. Не хотите проапдейтить скрипт?
Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
+1 # Игорь (Администратор) 13.11.2015 15:39
Пожалуйста

Так, а в чем проблема? Пишется данная функция за 5 минут. Вот пример:
--------------------------------------------
// Проверка для повторяющихся полей,
// имя поля, которое должно повториться указывается в атрибуте "confirm-field"
if (cl === 'confirmfield') {
validResult
&= ($(options.container).find('[Name="' + $(item).attr('confirm-field') + '"]').val()
== $(item).val());
}
else if (cl.substring(0, cl.length > 'rangelen'.length ? 8 : cl.length) === 'rangelen') {
var params = cl.split('-');
if(params.length === 3) {
var minlen = parseInt(params[1]),
maxlen = parseInt(params[2]);
if (!isNaN(minlen) && !isNaN(maxlen) && minlen <= maxlen) {
validResult &= (($(item).val().length >= minlen) && ($(item).val().length <= maxlen));
}
}
}
// Иначе обычная проверка
else if (typeof (options.validators[cl]) === 'function') {
validResult &= options.validators[cl](item.val());
}
--------------------------------------------
Ну и используете для проверки классы вида "rangelen-3-12"

П.С. Кстати, в русском языке достаточно много хороших слов. Например, расширить, добавить, увеличить и так далее :)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Николас 14.11.2015 02:06
Спасибо, попробую этот кусок кода. Если такая доработка делается за пять минут - это очень впечатляет. Так сложилось, что php и javascript - это не то, чем я занимаюсь, и даже не хобби, просто мне нужно немного в них разбираться, чтобы иногда что-то улучшить. Что касается слов - да, я знаю, в русском языке много подходящих слов, но русский для меня - иностранный, и я могу употребить такие слова, как проапдейтить просто потому, что корень этого слова мне ближе, и еще - так говорят, я точно это слышал. Хоть это и не чисто по-русски, как я понимаю. Но вот слово скрипт - оно тоже вряд ли русское, не так ли? И валидация тоже, мне кажется. Еще в транспорте я слышал по-русски такое: валидация тикета. Даже не знаю, как это правильнее сказать, но и так вроде все ясно. Купил билет, теперь нужно сделать валидацию.

Позволю себе вопрос по существу. Похоже, в результате работы скрипта валидации очищается массив $_POST, или я ошибаюсь? Дело в том, что я хотел после валидации формы сделать ее отправку с использованием ajax. Для этого взял где-то такую функцию:

function call() {
var msg = $('#formid').serialize();
$.ajax({
type: 'POST',
url: 'logger.php',
data: msg,
success: function(data) {
$('.results').html(data);
},
error: function(xhr, str){
alert('Error Code: ' + xhr.responseCode);
}
});
}

и сделал ее вызов сразу после этого алерта:

alert('Валидация первой формы прошла успешно!');
call();
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь (Администратор) 15.11.2015 20:34
Цитата:
Похоже, в результате работы скрипта валидации очищается массив $_POST, или я ошибаюсь?
- Тут вы ошибаетесь. $_POST - это серверная переменная, к клиентскому коду она не имеет отношения.

По скрипту ответ ниже

П.С. По поводу русского языка, не будем развивать тему, для этого есть другие сайты.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Николас 14.11.2015 02:07
Обработчик logger.php благополучно вызывается, но записывает массив $_POST без имен переменных и без их значений. Логгер пишет так:

$logline.=' | ';
foreach($_POST as $key => $value)
{
$logline .= $key.' - '.$_POST[$key].' ';
};

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

Возможно, я не прав, или call() нужно делать из другого места - был бы признателен за рекомендации. Либо, если это не слишком обременительно для Вас, возможно, Вы могли бы дополнить Ваш пример отправкой формы после успешной валидации с использованием ajax. Но для меня было бы более чем достаточно рекомендации, откуда именно лучше вызывать call().

Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь (Администратор) 15.11.2015 20:40
Проблема не в логгере. Проблема в функции serialize, которая применима только для тегов "form". В случае данного js-скрита, показывается валидация для произвольно составленных форм (в данном примере это был div), соответственно, serialize использовать нельзя. Вместо нее используйте функцию по типу следующей:
--------------------------------------
function getArray(container) {
var sendArray = [];

$(container).find('input, textarea').each(function () {
sendArray.push({
name: $(this).attr('name'),
value: $(this).val()
});
});

return sendArray;
}
--------------------------------------

И тогда в коде call изменяйте строчку
--------------------------------------
var msg = $('#formid').serialize();
--------------------------------------
на
--------------------------------------
var msg = getArray('#formid');
--------------------------------------

Единственно, сейчас функция getArray рассчитана только на input и textarea (в их текстовом представлении). Для select, чекбоксов и радиобаттонов, функцию нужно доделать.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Николас 16.11.2015 23:43
Большое спасибо. И проверка диапазона длины, и отправка массива вместо serialize работают прекрасно. И Вы абсолютно правы насчет $_POST, безусловно.

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

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

2. И после этого хорошо бы выдать сообщение об успешной отправке. Например, в пределах div с формой добавим div с текстом:

Текст до отправки формы

и после отправки формы он должен поменяться. Я пробую так:

document.getElementById(msg2user).innerHTML = "Форма успешно получена";

На вид вроде бы так и должно быть, но текст не обновляется. Очевидно, моих скромных познаний недостаточно, и/или этот оператор стоит не там, где нужно. У меня это здесь:

function call() {
var msg = getArray('#formx');
$.ajax({
type: 'POST',
url: 'logger_cz.php',
data: msg,
success: function(data) {
$('.results').html(data);
document.getElementById(msg2user).innerHTML = "Форма успешно получена";
},
error: function(xhr, str){
alert('Error Code: ' + xhr.responseCode);
}
});
}

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

Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
-1 # Николас 17.11.2015 00:33
Вроде как напрасно я Вас снова побеспокоил. По п. 2 был мой недосмотр, нужны апострофы для значения id. По п. 1 нашел кусок кода, с запасом на будущее, стоит в конце call().

function call() {
var msg = getArray('#formx');
$.ajax({
type: 'POST',
url: 'logger.php',
data: msg,
success: function(data) {
document.getElementById('msg2user').innerHTML = "Данные получены";
$('.results').html(data);
},
error: function(xhr, str){
alert('Error Code: ' + xhr.responseCode);
}
});
$(':input','#formx')
.not(':button, :submit, :reset, :hidden')
.val('')
.removeAttr('checked')
.removeAttr('selected');
}

В общем, все отлично, большое спасибо. Если надумаете доделать функцию для select, чекбоксов и радиобаттонов - это будет вообще предел мечтаний. Спасибо еще раз, и успехов Вам.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь (Администратор) 17.11.2015 01:32
Пожалуйста.

Насчет функции для select, checkbox и radiobutton. Эта задача не совсем относится к скрипту. Поясню о чем речь. Обычно, валидация накладывается на уже существующие механизмы отправки данных, ну или в крайнем случае делается совместно со сбором данных.

Тем не менее, в зависимости от того, как сделаны формы сбор информации, очистка и прочее могут быть жутко специфичны.

Так, к примеру, если речь идет о стандартной отправке данных через post, то валидация и не должна ничего собирать, так как все данные идут в теге form.

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

Поэтому, такие функции обычно пишутся под конкретные задачи, а скрипт валидации рассчитан для использования как "универсальную" и "легко добавляемую" функциональность.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Дмитрий 05.04.2018 07:39
Здравствуйте. Почти что нужно, только вот не желаете от жейквери избавить все это?)
Ну и в коментах убило "под них уникальный скрипт - это уже целая библиотека", а на фига тогда jquery тут? Для замещения только querySelectorAll и смены классов полей довольно глупо выглядит. имхо.
Достало засилье прямо скажем не без багов надстройки над багами...
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь (Администратор) 06.04.2018 17:22
Здравствуйте
jQuery используется в очень многих сайтах. И тому много причин. Удобство, куча плагинов и прочее.

Кроме того, какой смысл, если многие берут готовые скрипты, а потом просто допиливают. Например, можно тултипы добавить, сделать подсказки, добавить анимацию и много чего другого.

Если же вас не устраивает jQuery, то, как вы сами сказали, можете переписать и добавить свои методы - дело не такое уж сложное под конкретный сайт. Достаточно взять из скрипта его основу. Проблема больше в кроссбраузерности. Зачем писать велосипед, если есть готовое и популярное решение.

По поводу "Ну и в коментах убило "под них уникальный скрипт - это уже целая библиотека", а на фига тогда jquery тут". Тут все просто. Если заглянуть чуть глубже, то вылезет немало проблем и пожеланий. А это значит, что скрипт будет расти как грибы.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 03.09.2022 08:32
Приветствую!
На странице множество форм и отправляются каждая форма одной кнопкой на которой прикручена одна функция:


Сама функция отправки формы:

function saveForm(){
var data=[]
data.push(formartForm($('*[data-type="config"][dat a-id="page"]').find('form').serializeArray()))
data.push(formartForm($('*[data-type="config"][dat a-id="jump"]').find('form').serializeArray()))
data.push(formartForm($('*[data-type="config"][dat a-id="button"]').find('form').serializeArray()))
$('*[data-type="html"]').each(function(){
data.push(formartForm($('*[data-type="config"][dat a-id='+$(this).attr('data-id')+']').find('form').s erializeArray()))
})
var msg = getArray({config_list:data});
$.ajax({
type: "POST",
url : EDITABLE_PAGE_URL+'/config_edit?if_h5=1&page_id={$ Request.param.editable_page_id}',
dataType : 'json',
data : {config_list:data},
success : function (data, status) {
layer.msg(data.message)
}
})
}


Как прикрутить к ajax функции saveForm() проверку валидации вашего кода?
Заранее, спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь 05.09.2022 15:11
Так прикрутите несколько проверок

window.validation.isValid({ container: '[ТУТ СЕЛЕКТОР НУЖНОЙ ФОРМЫ]' })

И так для каждой формы. И если все формы прошли валидацию, то отправляете ajax запрос.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 05.09.2022 16:42
Цитирую Игорь:

window.validation.isValid({ container: '[ТУТ СЕЛЕКТОР НУЖНОЙ ФОРМЫ]' })

Это не блокирует отправку формы через ajax, а нужно блокировать отправку формы, если форма не прошла валидацию.
Нужно проверку валидации прикрутить к ajax. Как это сделать?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 05.09.2022 16:57
И мне нужно не все формы разом проверять, а только ту форму, которая активна. Из функции saveForm() это наверное можно понять.
Если бы для каждой формы была бы своя кнопка отправки формы, то это бы не вызвало у меня затруднений написать проверку для каждой формы отдельно.
Но в данном случае форм много, а функция saveForm() одна для всех ворм на странице, которая отправляет только одну, активную форму, а не все формы разом.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь 06.09.2022 03:19
Как вариант

var checkValid = true;
$('*[data-type="html"]').each(function(){
data.push(formartForm($('*[data-type="config"][dat a-id='+$(this).attr('data-id')+']').find('form').serializeArray()))
if ($('*[data-type="config"][dat a-id='+$(this).attr('data-id')+']').find('form').l ength > 0) {
checkValid &= window.validation.isValid({ container: '*[data-type="config"][dat a-id='+$(this).attr('data-id')+'] form' });
}
})

if (!checkValid) {
return;
}

Ну и разметьте форму маркерами CSS
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 18.09.2022 06:04
Как в это условие добавить создание и удаление псевдоэлемента after?
Цитата:
// Если поле не прошло валидацию if (!validResult) // Здесь идет код, который добавляет tooltip c сообщением к полю //$(item).tooltip(options), $(item).addClass(options.errorClass).removeClass(options.okClass); // Поле прошло валидацию else $(item).addClass(options.okClass).removeClass(options.errorClass);
В файл .css добавил
Цитата:
.field-input.input-error:after{ font: 17px/1 iconfont;position: absolute; top: 50%; right: 0; margin-top: -10.5px; width: 27px; height: 21px; background: red; content: '\e658'; display: block; pointer-events: none;}
.field-input.input-ok:after{
font: 17px/1 iconfont;position: absolute;
top: 50%;
right: 0;
margin-top: -10.5px;
width: 27px;
height: 21px;
background: red;
content: '\e64d';
display: block;
pointer-events: none;}
Но это не подходит. Нужно, чтобы JS создавал псевдоэлементы.
Поможете ответом?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 18.09.2022 07:33
Вот так нормально .field-input.input-ok + *:after{}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь 18.09.2022 14:00
Хорошо, что сами нашли ответ. Но на всякий случай, after это псевдоэлемент, поэтому он не добавляется JS. Это примочка CSS
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 18.09.2022 16:28
Я переделал, так добавляет нужный em перед input:
if (!validResult)
$(item).addClass(options.errorClass).removeClass(options.okClass).prev("em").remove(),
$(item).before("");
// Поле прошло валидацию
else
$(item).addClass(options.okClass).removeClass(options.errorClass).prev("em").remove(),
$(item).before("");

Если на странице 7-10 форм, то валидация в режиме онлайн тормозит или совсем не делает проверку, типа виснет.
Функционирует только с кнопки.
А если 3-4 формы, то хорошо.
В общем не панацея эта валидация на классах .css.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь 20.09.2022 13:45
Не совсем понял зачем вы постоянно удаляете em (смотрите код внимательно).

7-10 форм. Ну зависит от объемов и того как применяется. В этом смысле код
for(var cnt = 0; cnt < 100000000; cnt++) {
for(var cnt2 = 0; cnt2 < 100000000; cnt2++) {
//something
}
}
легко подвесит любую страницу.

Кроме кнопки, еще существует параметр liveCheck для валидации каждого отдельного поля в онлайн режиме.

Ну и плагин писался для общих задач. Чаще всего это одна форма с десятком полей.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 20.09.2022 17:26
В before("") содержатся разного названия классы, ваш редактор, на этом сайте, режет содержимое кода и вырезал названия этих классов.
Поэтому вы не поняли зачем каждый раз удалять em.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Васка 20.09.2022 17:31
.before("");
.before("");
вот разные.
Но ваш редактор может снова удалить код и вы не увидите содержание .before("");
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
0 # Игорь 20.09.2022 17:47
А понял, вы добавляете em, а перед этим удаляете.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору

Добавить комментарий / отзыв

Комментарий - это вежливое и наполненное смыслом сообщение (правила).



* Нажимая на кнопку "Отправить", Вы соглашаетесь с политикой конфиденциальности.
Присоединяйтесь
 

 

Программы (Freeware, OpenSource...)