Браузерная валидация формы без js. Простая валидация формы без JS. Добавление дополнительных условий

Вам когда-нибудь приходилось искать скрипты и плагины для валидации произвольных форм и контейнеров? Когда тэг "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)-(0|\\d)|(0|1)-30|(0|1)-31)"), regExpRU = new RegExp("((0|\\d)\\.(0|1)|30\\.(0|1)|31\\.(0|1))\\.(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)-(0|\\d)|(0|1)-30|(0|1)-31) (\\d+):(\\d+)"), regExpRU = new RegExp("((0|\\d)\\.(0|1)|30\\.(0|1)|31\\.(0|1))\\.(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("^+$"); 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("^(+\\.)* +(\\.+)*\\.{2,6}$"); return regExp.test(str) || !str; }, "url": function (str) { var regExp = new RegExp("^((https?|ftp)\\:\\/\\/)?({1})((\\.)|())*\\.({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("").val() == $(item).val()); } // Иначе обычная проверка else if (typeof (options.validators) === "function") { validResult &= options.validators(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-код самих форм демонстрационного примера. Сам же вызов плагина для создания валидации на лету, а так же запуск ручной валидации по нажатию на кнопку, занимают всего несколько строк.

$(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("Валидация второй формы прошла успешно!"); } }); });


Валидации формы в режиме реального времени Имя Email Подтверждение пароля URL Отправить форму Пример ручной валидации формы Имя Email Пароль (цифры, буквы и пробел) Подтверждение пароля URL Дата форматы ГГГГ-ММ-ДД и ДД.ММ.ГГГГ Отправить форму

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

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

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

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

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

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

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

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

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

Вы также можете установить определенное требуемое значение. Вроде email или number.

Это поле является обязательным для заполнения и вводимая информация будет проверяться на соответствие адресу электронной почты. Давайте улучшим UX:

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

    Проверяем заполнено поле или нет

    Мы хотим провернуть фокус с :valid и :invalid , но мы не хотим опережать события и считать поле невалидным до того, как оно было заполнено.

    Есть ли CSS-селектор для проверки пустоты поля? Вообще-то нет! Вы можете подумать на :empty ,но ошибетесь. Этот псевдокласс предназначен для проверки ситуаций когда элемент не содержит в себе ничего. Поля ввода и так пусты по умолчанию.

    Трюк в том, чтобы проверить поле на видимость атрибута placeholder :

    CSS
    input:not(:placeholder-shown) { }

    Мы не использовали плейсхолдер в нашем примере, но это правило сработает, если мы зададим значение из одного пробела:

    :placeholder-shown супер полезен для нас! Это в целом секретный селектор, позволяющий проверить, есть ли в поле значение или нет.

    IE и Firefox пока не поддерживают его, что немного осложняет задачу. Обычно спасителем является новая функция @supports , но…

    CSS /* Это не сработает */
    @supports (input:placeholder-shown) {
    input:not(:placeholder-shown) {
    }
    }

    Вы не можете использовать @supports для селекторов, только для свойства/значения (например @supports (display: flex)).

    Проверить плейсхолдер при помощи JavaScript довольно легко:

    JavaScript var i = document.createElement(‘input’);
    if (‘placeholder’ in i) { }

    Но это не кажется самым простым способом имитации :placeholder-shown . Поэтому…возможно, просто стоит подождать поддержки всеми браузерами.

    Представим, что поддержка уже повсеместная и посмотрим, как это будет выглядеть…

    SCSS form { > div {

    > input,
    > input,
    > input {

    // Когда поле ввода…
    // 1. НЕ пустое
    // 2. НЕ в фокусе
    // 3. НЕ валидно &:invalid:not(:focus):not(:placeholder-shown) {
    // Покажем напоминание background: pink;
    & + label {
    opacity: 0;
    }
    }

    // Когда в невалидное поле устанавливается фокус (и оно по прежнему не пустое) &:invalid:focus:not(:placeholder-shown) {
    // Покажем более настойчивое напоминание
    & ~ .requirements {
    max-height: 200px;
    padding: 0 30px 20px 50px;
    }
    }
    }

    // ~
    // ~
    //
    .requirements {
    padding: 0 30px 0 50px;
    color: #999;
    max-height: 0;
    transition: 0.28s;
    overflow: hidden;
    color: red;
    font-style: italic;

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

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

    Посмотрите на онлайн-пример валидации формы и прочитайте небольшую шпаргалку по основам валидации форм в HTML5.

    Специальные типы элемента Input

    В HTML5 представлены несколько новых типов элемента input. Они могут быть использованы для создания полей ввода, которые будут принимать только определенный вид данных. Вот новые типы, которые появились в HTML5:

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

    < input type = "email" / >

    Если браузер не поддерживает данный тип элемента input, то текущий элемент будет вести себя, как обычное текстовое поле ввода. Также, вам будет полезно узнать о том, что некоторые типы полей (например, «email» и «tel») приводят к открытию на мобильных устройствах специальных клавиатур с ограниченным набором клавиш, а не полной раскладки QWERTY. Более подробную информацию обо всех типах элемента input вы найдете на сайте MDN – .

    Обязательные поля

    Простое добавление атрибута «required» для элемента input, select или textarea сообщит браузеру о том, что у данного поля должно быть значение. Воспринимайте это, как красную звездочку*, которую мы видим в большинстве регистрационных форм.

    < input type = "checkbox" name = "terms" required >

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

    Когда вы указываете атрибут required для полей типа email или url, браузер ожидает наличия определенного шаблона, по которому он сможет проверить информацию, но подобная проверка очень снисходительна и пропускает e-mail адреса вроде «z@zz» (читайте далее, чтобы узнать, как с этим бороться).

    Лимиты

    Мы можем установить базовые ограничения, такие как максимальная длина или минимальное и максимальное значение для числовых полей. Чтобы ограничить длину элементов input или textarea, используйте атрибут «maxlength». Это делается для того, чтобы вообще нельзя было ввести строку длиннее, чем значение атрибута «maxlength». Если вы попробуете вставить строку, которая превышает лимит, то форма просто обрежет ее.

    Оформление

    CSS3 псевдо-классы позволяют нам оформить любое поле формы в зависимости от его состояния. Вот данные псевдо-классы:

    Это означает, что обязательные поля у вас могут выглядеть одним образом, необязательные - другим и т.д. В нашем демо-примере мы скомбинировали селекторы «valid» и «invalid» с псевдо-классом «focus», чтобы раскрасить поля формы в красный и зеленый цвета, когда пользователь выбирает их и начинает в них что-нибудь вводить.

    input:focus:invalid, textarea:focus:invalid{ border:solid 2px #F5192F; } input:focus:valid, textarea:focus:valid{ border:solid 2px #18E109; background-color:#fff; }

    input : focus : invalid ,

    textarea : focus : invalid {

    border : solid 2px #F5192F;

    input : focus : valid ,

    textarea : focus : valid {

    border : solid 2px #18E109;

    background - color : #fff;

    Всплывающие подсказки

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

    Обратите внимание на то, что разные браузеры по-своему отображают всплывающие подсказки. В браузере Chrome значение атрибута title появится под основным текстом сообщения об ошибке и будет иметь меньший размер шрифта, чем текст об ошибке. Браузер Firefox вообще не будет отображать ваш текст для всплывающей подсказки до тех пор, пока вы не будете использовать атрибут «pattern», который будет использован для информации о шаблоне.

    Добрый день, уважаемый читатель. В этой статье я бы хотел обратиться к теме проверки содержимого форм на стороне клиента. На заре становления языков, работающих на клиенте, эта задача была основной. Со временем эти языки обросли новыми возможностями (манипуляция DOM, управление стилями и пр.), но задача проверки форм не исчезла. Правда с появлением HTML5 стало возможным указывать такой тип поля формы, как email, и браузер сам возьмет на себя его проверку. Такая возможность на данный момент реализована в Opera, так что расчитывать на нее пока особо не приходится. Поэтому я бы и хотел рассмотреть этот вопрос основательно. В большинстве случаев валидация проводится так: каждому полю раздаётся id, и затем при submit"е вытаскиваем их, попутно проверяя содержимое. И всем хорош данный подход, кроме отсутствия в нем системности. Поэтому хочу предложить вашему вниманию свое решение данной проблемы.Итак понеслася! В качестве примера приведена несложная форма, содержащая поля для имени, почтового ящика и пола.
    HTML-код файла:
    input { border: 1px solid #D4E2F7; } input { margin: 3px 0px 3px 15px; } ....

    male
    female

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

    Function createField() { var members = new Array("required", "regexp"); for(var i = 0; i < arguments.length; i++) { this] = arguments[i]; } } // absolute regexp createField.prototype.regexp = /^{1,}$/ig; createField.prototype.valid = false; createField.prototype.required = true; createField.prototype.nullify = function() { this.valid = false; };

    Далее в прототипе укажем значения по умолчанию полей.
    regexp - регулярка, которой должно удовлетворять значение соответствующего поля.
    valid - результат проверки значения поля регулярным выражением regexp .
    required - индикатор того: требуется ли данное поле (можно ли оставить поле незаполненным).
    nullify() - метод, возвращающий поле valid в исходное состояние.

    Var single = new Array(); single["name"] = new createField(); single["email"] = new createField(true, /^+@+\.{2,4}$/); single["sex"] = new createField(true, /male$/ig);
    Создаем как бы праобраз нашей формы. В ней будет 3 поля с именами name, email и sex, каждое из которых не может остаться незаполненным. Притом значения 2х последних полей должны удовлетворять указанным во втором параметре регулярном выражении.
    var Singleton = { fields: single, regForm: false, nullify_values: function() { for(i in this.fields) { this.fields[i].nullify(); } }, ... };
    В данном участке кода мы объявляем объект Singleton. Назначение поля fields понятно. Поле regForm - объект, содержащий форму. Через него мы и будем получать доступ к полям формы и их значениям.
    Метод nullify_values() возвращает значение поля valid у «подобъектов» (т.к. fields это массив объектов) в исходное состояние.

    И напоследок самое интересное. Метод submit() , который и заключает в себе основной функционал.
    submit: function() { if(this.regForm) { // set property valid to false for every form field this.nullify_values(); var i = null; // walks through the form fields, pick and if required check their values for(i = 0; i < this.regForm.elements.length; i++) { // current field var oField = this.regForm.elements[i]; switch (oField.type) { case "button": case "submit": case "reset": break; case "checkbox": case "radio": if(!oField.checked) { break; } default: // javascript trim function analogue oField.value = oField.value.replace(/^\s*/, "").replace(/\s*$/, ""); if(!oField.value) { oField.value = ""; } // if this field is out of interest if(!this.fields.required) { this.fields.valid = true; this.regForm[i].style.border=""; } // if this field is required else { var match = this.fields.regexp.test(oField.value); // ... and fits regular expression if(match) { this.fields.valid = true; this.regForm[i].style.border=""; } this.fields.regexp.test(oField.value); } } } // now all we need is to check if the whole form is valid // we perform it by comparing number of form fields and number of valid fields // they should be equal var validForm = 0; var fieldsLength = 0; for(i in this.fields) { fieldsLength++; if(this.fields[i].valid) { validForm++; } else { this.regForm[i].style.border="1px solid #FF0000"; break; } } if(validForm == fieldsLength) { this.regForm.submit(); } else { this.nullify_values(); return false; } } }
    Сначала обнуляем значения valid. Затем проходимся по полям формы. Если поле не несет особой смысловой нагрузки (типа reset) или не является помеченным галочкой - пропускаем его. Удаляем ведущие и замыкающие пробелы. И если поле является необходимым - проверяем его содержимое с помощью регулярного выражения. Если нет - идем дальше. Теперь осталось посчитать общее количество полей и количество валидных полей. И если они совпадают, то форму можно отправлять.
    single = null; window.onload = function() { var regForm = document.forms; Singleton.regForm = regForm; Singleton.regForm.onsubmit = function() { return Singleton.submit(); }; };
    И в самом конце мы «занулляем» объект single , чтобы невзначай не изменить значений Singleton.fields , выхватываем форму и даем ей обработчик события submit .

    Остренькое1 . Если мы зануляем single , то не уничтожим ли мы попутно и Singleton.fields ? Нет. И вот почему. Присваивая переменной fields объект мы не передаем сам объект, а лишь ссылку на него. Физически объект хранится в так называемой Memory Heap . И не будет удален оттуда garbage collector"ом до тех пор, пока есть хотя бы одна ссылка на него. Таким образом мы лишь удалили ссылку на массив, и объекты не были уничтожены, т.к. существует еще одна ссылка на них, а именно Singleton.fields .

    2 . В случае большого количества полей, не требующих валидации, не получится ли так, что создается много объектов, свойства которых по большому счету не нужны? Нет. И вот почему. Когда мы достаем поле объекта интерпретатор JS сначала смотрит в самом объекте и если не находит - в прототипе. Таким образом значения по умолчанию хранятся в прототипе в единственном экземпляре, что не есть накладно.

    3 . Почему когда содержимое поля удовлетворяет регулярному выражению я делаю проверку еще раз? На это вразумительного ответа у меня нет. Опытным путем я заметил, что когда применяется функция RegExp.test() , то сначала она возвращает результат ожидаемый, а потом прямо противоположный. Попробуйте закомментировать эту строку и сами увидите, как поведение станет непредсказуемым. В обычном случае такого не наблюдается.

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

    Посмотреть работу скрипта можно