Показать сообщение отдельно
  #1 (permalink)  
Старый 06.08.2011, 18:37
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Скриптик валидации форм (jQuery)
Для своих рабочих нужд я написал маленький скриптик (в гзипе и 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: нашёл одну багу, исправил
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 06.08.2011 в 20:50.
Ответить с цитированием