Для своих рабочих нужд я написал маленький скриптик (в гзипе и gcc всего 700 байт) валидации элементов форм (знаю, что подобного добра в нете навалом, но я люблю писать всё сам
) и решил выложить тут, вдруг кому понадобится.
Как использовать: очень просто, нужно всего лишь установить нашим элементам соответствующие data-атрибуты, например:
<form id="MyForm">
<input type="text" name="name" data-vf_empty="true" />
<input type="text" name="mail" data-vf_mail="true" />
</form>
Обратите внимание, что все атрибуты валидатора задаются с префиксом
vf_. После этого в JS нужно просто применить этот плагинчик на наши элементы ($(наши элементы).validateForm()
и он вернёт логическое значение true/false в зависимости от ситуации. Разумеется выполнение плага можно повесить на любое событие JS, а атрибуты можно комбинировать.
Помимо возврата логического значения мой скриптик также может выполнить некоторые действия в зависимости от результата, а именно:
- Применить к элементу формы новый CSS класс;
- Вывести текстовое (html) сообщение в специально указанный блок.
Для того чтобы задать блок вывода информации нужно указать в конструктор первый параметр: либо объект jQuery, либо строка в Sizzle синтаксисе, однако можно указать дополнительную информацию в строчном виде, а именно, чтобы поиск по DOM шёл относительно нашего элемента форма, для этого нужно написать что-то типа: find::.MyClass (до разделителя :: идёт названия метода jQuery, после селектор, можно применять и так: next:: (выберет следующий элемент после элемента формы)). Расширенные строчные селекторы отталкиваются от каждого элемента формы, который проходит валидацию, т.е. например next:: у каждого свой. Есть также альтернативный способ задания блока вывода информации - напрямую в элементе через data-атрибут, для этого пропишем что-то типа: data-vfp_target="next::" (можно задавать только строками, вид строки такой же, как в конструкторе). Обратите внимание на префикс
vfp_ - так задаются все дополнительные параметры.
Вторым параметром в конструкторе можно указать тип добавления в DOM (по умолчанию: html), имя которого совпадает с методом jQuery.
Изначально валидатор умеет проверять только обязательные поля, формат почты и url (мне пока просто больше не нужно). Но его очень просто расширять, нужно всего лишь расширить соответствующие объекты ($.fn.validateForm.rule и $.fn.validateForm.msg, выделил в коде), посмотрите в код и сразу поймёте, что и как)
Разумеется я проверял код на работу, но т.к. все ошибаются, то и у меня могут быть ошибки
буду рад за багрепорт.
Собственно сам скрипт (сжать можно тут:
http://closure-compiler.appspot.com/home)
/**
* $.validateForm - плагин для JavaScript фреймворка jQuery для валидации форм
*
* Автор: Кобец Андрей Александрович (kobezzza)
* Дата: 06.09.2011
*
* Дополнение:
* Код документирован в соответствие со стандартом jsDoc
* Специфичные типы данных:
* 1) jQuery Object является сокращённой формой [Object] и означает экземпляр jQuery
* 2) ExSelector является сокращённой формой [String] и означает селектор CSS (Sizzle синтаксис) c возможностью установки метода выбора, относительно объекта формы (например: next:: или find::.myClass)
* --
* Запись, типа: [prop=undefined] означает, что данный параметр не обязательный и если не указан явно, то не определён (не имеет значения по умолчанию)
*
* @class
* @autor kobezzza (kobezzza@gmail.com | [url]http://kobezzza.com[/url])
* @version 1.0
*/
(function ($) {
// Включение ECMAScript 5 "strict mode"
"use strict";
/**
* Валидация формы
*
* @this {jQuery Object}
* @param {ExSelector|jQuery Object} [target=undefined] - ссылка на элемент для вставки дополнительной информации
* @param {String} [appendType="html"] - тип добавления в DOM
* @return {Boolean}
*/
$.fn.validateForm = function (target, appendType) {
appendType = appendType || "html";
var finResult = true;
this.each(function () {
var
$this = $(this),
$data = $this.data(),
//
vf = $.fn.validateForm,
rule = vf.rule,
action = vf.action,
//
key, keyV,
//
result;
// Валидация
for (key in $data) {
if ($data.hasOwnProperty(key)) {
for (keyV in rule) {
if (rule.hasOwnProperty(keyV)) {
if (key === keyV && $data[key] === true) {
if (rule[keyV] instanceof RegExp) { result = rule[keyV].test($this.val()); }
else { result = rule[keyV]($this); }
if (result === false && finResult !== false) { finResult = false; }
action($this, keyV, result, target || null, appendType);
}
}
}
}
}
});
return finResult;
};
*!*
// Правила
$.fn.validateForm.rule = {
// Проверка на заполненность
vf_empty: function ($this) {
if (!$.trim($this.val())) { return false; }
return true;
},
// Проверка формата почты
vf_mail: new RegExp("^[_\\.0-9a-z-]+@([_0-9a-z][0-9a-z_-]+\\.)+[a-z]{2,4}$", "i"),
// Проверка формата ссылки
vf_url: new RegExp("^http:\\/\\/(?:www\\.|)[_\\.0-9a-z-]{2,}\\.[a-z]{2,4}[_\\/0-9a-z-]*$", "i")
};
// Сообщения
$.fn.validateForm.msg = {
// Проверка на заполненность
vf_empty: {success: " ", error: "Заполните поле"},
// Проверка формата почты
vf_mail: {success: " ", error: "Не верный формат почты!"},
// Проверка формата ссылки
vf_url: {success: " ", error: "Не верный формат URL!"},
// По умолчанию
vf_default: {sClass: "vf_success", eClass: "vf_error"}
};
*/!*
// Действие валидатора
$.fn.validateForm.action = function ($this, rule, result, target, appendType) {
var
msg = $.fn.validateForm.msg,
defMsg = {},
dTarget = $this.data("vfp_target");
$.extend(true, defMsg, msg["vf_default"], msg[rule]);
if (!dTarget) {
if (target) {
if (!target.jquery) {
target = target.split("::");
if (target.length === 2) {
target = $this[target[0]](target[1]);
} else { target = $(target[0]); }
}
} else { target = $(); }
} else {
target = dTarget.split("::");
if (target.length === 2) {
target = $this[target[0]](target[1]);
} else { target = $(target[0]); }
}
if (result === true) {
if (defMsg.success) { target[appendType](defMsg.success); }
if (defMsg.sClass) { $this.addClass(defMsg.sClass); }
if (defMsg.eClass) { $this.removeClass(defMsg.eClass); }
} else {
if (defMsg.error) { target[appendType](defMsg.error); }
if (defMsg.eClass) { $this.addClass(defMsg.eClass); }
if (defMsg.sClass) { $this.removeClass(defMsg.sClass); }
}
return true;
};
})(jQuery);
Надеюсь данный скриптик окажется вам полезным или хотя бы интересным
UPD: нашёл одну багу, исправил