Frontend Validation via jQuery

Osbes

Staff member
Administrator
Ex-Admin
UF Supporter
Joined
Oct 24, 2003
Messages
11,481
Points
325
Aktueller Arbeitsstand:
JavaScript:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="de">
<head>
<title>Validation</title>
<script type="text/javascript" src="http://www.united-forum.de/tools/jquery.js"></script>
<script type="text/javascript">
/**
 * sprintf and vsprintf for jQuery
 * somewhat based on http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
 * 
 * Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details. 
 *
 * @license http://www.gnu.org/licenses/gpl.html 
 * @project jquery.sprintf
 */
(function($)
{
	$.extend({
		sprintf: function(format)
		{
			var formats = {
				'%': function(val) {return '%';},
				'b': function(val) {return  parseInt(val, 10).toString(2);},
				'c': function(val) {return  String.fromCharCode(parseInt(val, 10));},
				'd': function(val) {return  parseInt(val, 10) ? parseInt(val, 10) : 0;},
				'u': function(val) {return  Math.abs(val);},
				'f': function(val, p) {return  (p > -1) ? Math.round(parseFloat(val) * Math.pow(10, p)) / Math.pow(10, p): parseFloat(val);},
				'o': function(val) {return  parseInt(val, 10).toString(8);},
				's': function(val) {return  val;},
				'x': function(val) {return  ('' + parseInt(val, 10).toString(16)).toLowerCase();},
				'X': function(val) {return  ('' + parseInt(val, 10).toString(16)).toUpperCase();}
			};

			var re = /%(?:(\d+)?(?:\.(\d+))?|\(([^)]+)\))([%bcdufosxX])/g;

			var dispatch = function(data)
			{
				if(data.length == 1 && typeof data[0] == 'object')
				{ //python-style printf
					data = data[0];
					return function(match, w, p, lbl, fmt, off, str)
					{
						return formats[fmt](data[lbl]);
					};
				}
				else
				{ // regular, somewhat incomplete, printf
					var idx = 0; // oh, the beauty of closures :D
					return function(match, w, p, lbl, fmt, off, str)
					{
						return formats[fmt](data[idx++], p);
					};
				}
			};
			
			var argv = Array.apply(null, arguments).slice(1);
			return format.replace(re, dispatch(argv));
		}
	});
})(jQuery);

(function($)
{
	$.fn.validator = function(options)
	{
		if (!$(this).length)
		{
			return false;
		}
		
		var form = this;
		var option = $.extend({}, $.fn.validator.defaults, options);

		bindCheckAll();
		
		if(option.submit)
		{
			
			form.bind("submit.first", function (e)
			{
				option.event.focus = true;
				option.event.blur = true;
				option.event.change = true;
				option.event.keypress = true;
				option.event.click = true;
				
				bindCheckAll();
				$(this).unbind("submit.first");
			});

			form.submit(function(event)
			{
				checkAll();
				
				if($(".uf_error:not(:hidden)").length < 1)
				{
					option.submitHandler();
				}
				
				return false;
			});
		}
		
		form.bind("reset", function (e)
		{
			$(".uf_invalid", form).removeClass("uf_invalid");
			$(".uf_errormessage", form).parent().remove();
			$(".uf_error:not(:hidden)", form).hide();
			
			option.event.focus = false;
			option.event.blur = false;
			option.event.change = false;
			option.event.keypress = false;
			option.event.click = false;
			
			bindCheckAll();
			
			form.bind("submit.first", function (e)
			{
				option.event.focus = true;
				option.event.blur = true;
				option.event.change = true;
				option.event.keypress = true;
				option.event.click = true;
				
				bindCheckAll();
				$(this).unbind("submit.first");
			});
		});
		
		function getElementByNameAttr(name)
		{
			return $("[name=" + name + "]", form);
		}
		
		function bindCheckAll()
		{
			$.each(option.validate, function(name)
			{
				$.each(option.event, function(event, bind)
				{
					if(bind)
					{
						bindCheck(name, event);
					}
					else
					{
						$("[name=" + name + "]", form).unbind();
					}
				});
			});
		}
		
		function bindCheck(name, event)
		{
			var element = $("[name=" + name + "]", form);
			element.bind(event, function(e)
			{
				check($(this).attr("name"));
			});
		}
		
		function checkAll()
		{
			$.each(option.validate, function(name)
			{
				check(name);
			});
		}
		
		function check(name)
		{
			$.each(option.validate[name], function(rule, attr)
			{
				var ul = $("[title=" + name + "]", form);
				
				if(!option.rules[rule].func(form, name, attr))
				{
					option.displayErrorMsg(form, name, rule, $.sprintf(option.rules[rule].message, attr));
				}
				else
				{
					option.removeErrorMsg(form, name, rule);
				}
			});
		}
	}
	
	$.fn.validator.defaults = {
		validate: {},
		submit: true,
		event:
		{
			focus: false,
			blur: false,
			change: false,
			keypress: false,
			click: false
		},
		rules:
		{
			required: 
			{
				func:
					function (form, name)
					{
						if($.trim($("[name=" + name + "]", form).val()).length > 0)
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Dieses Feld muss gefüllt sein."
			},
			minlength: 
			{
				func:
					function (form, name, minlength)
					{
						if($.trim($("[name=" + name + "]", form).val()).length < minlength)
						{
							return false;
						}
						else
						{
							return true;
						}
					},
				message: "Geben Sie bitte maximal %d Zeichen ein."
			},
			maxlength: 
			{
				func:
					function (form, name, maxlength)
					{
						if($.trim($("[name=" + name + "]", form).val()).length > maxlength)
						{
							return false;
						}
						else
						{
							return true;
						}
					},
				message: "Geben Sie bitte mindestens %d Zeichen ein."
			},
			rangelength: 
			{
				func:
					function (form, name, range)
					{
						var length = $.trim($("[name=" + name + "]", form).val()).length;
						
						if(length < range[0] || length > range[1])
						{
							return false;
						}
						else
						{
							return true;
						}
					},
				message: "Geben Sie bitte mindestens %d und maximal %dZeichen ein."
			},
			email: 
			{
				func:
					function (form, name)
					{
						if(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($("[name=" + name + "]", form).val()))
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Geben Sie bitte eine gültige E-Mail Adresse ein."
			},
			url: 
			{
				func:
					function (form, name)
					{
						if(/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test($("[name=" + name + "]", form).val()))
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Geben Sie bitte eine gültige E-Mail Adresse ein."
			},
			date: 
			{
				func:
					function (form, name)
					{
						if(/^\d\d?\.\d\d?\.\d\d\d?\d?$/.test($("[name=" + name + "]", form).val()))
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Bitte geben Sie ein gültiges Datum ein."
			},
			number: 
			{
				func:
					function (form, name)
					{
						if(/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test($("[name=" + name + "]", form).val()))
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Geben Sie bitte eine Zahl ein."
			},
			digits: 
			{
				func:
					function (form, name)
					{
						if(/^\d+$/.test($("[name=" + name + "]", form).val()))
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Geben Sie bitte nur Ziffern ein."
			},
			equalTo: 
			{
				func:
					function (form, name, dependency)
					{
						if($("[name=" + name + "]", form).val() == $(dependency, form).val())
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Bitte denselben Wert wiederholen."
			},
			notEqualTo: 
			{
				func:
					function (form, name, dependency)
					{
						if($("[name=" + name + "]", form).val() != $(dependency, form).val())
						{
							return true;
						}
						else
						{
							return false;
						}
					},
				message: "Bitte denselben Wert nicht wiederholen."
			},
			range: 
			{
				func:
					function (form, name, range)
					{
						var value = $("[name=" + name + "]", form).val();
						
						if(value < range[0] || value > range[1])
						{
							return false;
						}
						else
						{
							return true;
						}
					},
				message: "Geben Sie bitten einen Wert zwischen %d und %d."
			},
			max: 
			{
				func:
					function (form, name, max)
					{
						if($("[name=" + name + "]", form).val() > max)
						{
							return false;
						}
						else
						{
							return true;
						}
					},
				message: "Geben Sie bitte einen Wert kleiner oder gleich %d ein."
			},
			min: 
			{
				func:
					function (form, name, min)
					{
						if($("[name=" + name + "]", form).val() > min)
						{
							return false;
						}
						else
						{
							return true;
						}
					},
				message: "Geben Sie bitte einen Wert größer oder gleich %d ein."
			},
		},
		displayErrorMsg: function (form, name, rule, message)
		{
			var ul = $("[title=" + name + "]", form);
			var element = $("[name=" + name + "]", form);

			$(".uf_error:hidden", form).show();
					
			if(!element.hasClass("uf_invalid"))
			{
				element.addClass("uf_invalid");
			}
			
			if(message && $("[title=" + rule + "]", ul).length < 1)
			{
				var li = document.createElement('li');
				$(li)
					.attr("title", rule)
					.append(message);
				
				if(ul.length > 0)
				{
					ul.append(li);
				}
				else
				{
					var ul = document.createElement('ul');
					$(ul)
						.addClass("uf_errormessage")
						.attr("title", name)
						.append(li);
						
					var div = document.createElement("div");
					$(div)
						.css("clear", "both")
						.append(ul);
						
					$(element).parent("div").after(div);
				}
			}
		},
		removeErrorMsg: function(form, name, rule)
		{
			var ul = $("[title=" + name + "]", form);
			var element = $("[name=" + name + "]", form);
			
			if($("li", ul).length > 1)
			{
				$("[title=" + rule + "]", ul).remove();
			}
			else
			{
				element.removeClass("uf_invalid");
				ul.parent().remove();
				
				if($(".uf_errormessage", form).length < 1)
				{
					$(".uf_error:not(:hidden)", form).hide();
				}
			}
		},
		submitHandler: function ()
		{
			alert("send");
			
		}
	};
})(jQuery);

$(document).ready(function()
{
	$("#uf_formular").validator({
		validate:
		{
			"eingabe":
			{
				required: true
			},
			"ausgabe":
			{
				required: true,
				minlength: 12
			}
		},
		submitHandler: function ()
		{
			alert("send - new");
			alert(form);
		}
	});
	
	$("#uf_formular2").validator({
		validate:
		{
			"eingabe":
			{
				required: true,
				minlength: 10
			},
			"ausgabe":
			{
				required: true
			}
		}
	});
});
</script>
<style type="text/css">
.uf_error
{
	display:			none;
}

.uf_invalid
{
	border:				2px solid red;
}
</style>
</head>
<body>
<form id="uf_formular" action="" method="post">
	<div class="uf_error ui-widget">
		<div class="ui-state-error ui-corner-all" style="padding: 0 0.7em;"> 
			<span class="ui-icon ui-icon-alert" style="float: left; margin-right: 0.3em;"><img src="./images/styles/standard/spacer.gif" alt="" /></span> 
			<strong>Fehler: Es ist mindestens ein Fehler aufgetreten!</strong>
			<br /><br />
			<strong>Bitte beachte die Fehlermeldungen bei den jeweiligen Eingabebereichen und berichtige diese.</strong>
		</div>
	</div>	
	<fieldset class="ui-widget-content">
		<legend class="ui-widget-header">Eingabe</legend>
		<div class="uf_eingabe">
			<input type="text" name="eingabe" />
		</div>
	</fieldset>
	<fieldset class="ui-widget-content">
		<legend class="ui-widget-header">Ausgabe</legend>
		<div class="uf_ausgabe">
			<input type="text" name="ausgabe" />
		</div>
	</fieldset>
	<fieldset class="ui-widget-content">
		<legend class="ui-widget-header">Daten abschicken</legend>
		<input type="submit" class="uf_submit" value="Abschicken" />
		<input type="reset" class="uf_reset" value="Eingaben zurücksetzen" />
	</fieldset>
</form>

<form id="uf_formular2" action="" method="post">
	<div class="uf_error ui-widget">
		<div class="ui-state-error ui-corner-all" style="padding: 0 0.7em;"> 
			<span class="ui-icon ui-icon-alert" style="float: left; margin-right: 0.3em;"><img src="./images/styles/standard/spacer.gif" alt="" /></span> 
			<strong>Fehler: Es ist mindestens ein Fehler aufgetreten!</strong>
			<br /><br />
			<strong>Bitte beachte die Fehlermeldungen bei den jeweiligen Eingabebereichen und berichtige diese.</strong>
		</div>
	</div>	
	<fieldset class="ui-widget-content">
		<legend class="ui-widget-header">Eingabe</legend>
		<div class="uf_eingabe">
			<input type="text" name="eingabe" />
		</div>
	</fieldset>
	<fieldset class="ui-widget-content">
		<legend class="ui-widget-header">Ausgabe</legend>
		<div class="uf_ausgabe">
			<input type="text" name="ausgabe" />
		</div>
	</fieldset>
	<fieldset class="ui-widget-content">
		<legend class="ui-widget-header">Daten abschicken</legend>
		<input type="submit" class="uf_submit" value="Abschicken" />
		<input type="reset" class="uf_reset" value="Eingaben zurücksetzen" />
	</fieldset>
</form>
</body>
</html>

ToDo:
  • Bessere Umsetzung des MVC Pattern
    Ein gutes Beispiel dafür ist
    JavaScript:
    if($(".uf_error:not(:hidden)").length < 1)
    dies sollte durch eine Variable geprüft werden.
  • Einbinden der "reset"-Funktion
 
Wie läufts bei dir Lunak ?
 
Langsam, bin sehr viel am Nachlesen.
(Wenn ich mal daheim bin und Ruhe hab, scheiß Weihnachten)
 
Back
Top Bottom