验证框架的JavaScript代码
测试页面HTML代码
/*
* 使用方法:
* 提交表单前验证:jQuery('.validate').validate({submit:true}) 返回:true | false;
* 内置验证:在class中加入属性
* required:必需字段
* min:最小值,使用:min-32,或min--32
* max:最大值,使用:max-50
* minlength:最小长度,使用:minlength-15
* maxlength:最大长度,使用:maxlength-30
* word:英文字符、数字、下划线
* methodname:英文字符、数字、下划线,数字不能开头
* javamethodname:中英文字符、数字、下划线,数字不能开头
* url、email、date、dateiso、accept、
* datecn:日期格式:yyyy-MM-dd
* dateau:日期格式:dd-MM-yyyy
* chinese:中文
* number:数字
* filename:文件名[中英文数字下划线.英文]
* tolowercase:自动转换为小写字符
* touppercase:自动转换为大写字符
*/
;jQuery(document).ready(function(){
jQuery('.validate').validate();
});
;(function($){
$.fn.extend({
validate: function(options) {
if(options && options.submit==true){
var validator = new $.validator();
var test = true;
$(this).each(function(index){
var a = validator.element(this);
test = test && a;
});
return test;
}else{
var validator = new $.validator();
function delegate(event) {
validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );
}
$(this)
.delegate("focusin focusout keyup click change", ":text, :password, :file, select, textarea", delegate)
.delegate("click", ":radio, :checkbox", delegate);
}
return false;
}
});
})(jQuery);
//validator
;(function($){
$.extend({
format : function(source, params) {
if ( arguments.length == 1 )
return function() {
var args = $.makeArray(arguments);
args.unshift(source);
return $.format.apply( this, args );
};
if ( arguments.length > 2 && params.constructor != Array ) {
params = $.makeArray(arguments).slice(1);
}
if ( params.constructor != Array ) {
params = [ params ];
}
$.each(params, function(i, n) {
source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
});
return source;
}
});
})(jQuery);
//custome selector
;(function($){
$.extend({
validator : function( options, form ) {
this.settings = $.extend( {}, $.validator.defaults, options );
}
});
$.extend($.validator,{
defaults: {
messages: {},
groups: {},
rules: {},
errorClass: "error",
errorElement: "label",
focusInvalid: true,
errorContainer: $( [] ),
errorLabelContainer: $( [] ),
onsubmit: true,
ignore: [],
ignoreTitle: false,
onfocusin: function(element) {
this.element(element);
},
onfocusout: function(element) {
this.element(element);
},
onkeyup: function(element) {
if(!document.all){
this.element(element);
}
},
onclick: function(element) {
this.element(element);
},
onchange: function(element) {
if(document.all){
this.element(element);
}
}
},
prototype: {
init: function(){
},
getClasses: function(element){
return $(element).attr('class').toLowerCase().split(/\s/);
},
element: function(element){
var $this = this;
var valid=true;
var debug ="";
var classes = $this.getClasses(element);
var message="";
debug+=", classes=["+classes.join(",")+"]"
for(var index=0;index<classes.length;index++){
var method = classes[index];
debug +=", class:"+method;
if($.validator.methods[method]){
var test = $.validator.methods[method].call(this,element.value,element);
valid = valid && test;
message = $.validator.messages[method];
}else if(method.indexOf('-')>0){
for (var i in $.validator.tests){
var result = $.validator.tests[i].call($this,method);
debug+=", method="+method;
if(result != null){
var param = result.slice(1);
var test = $.validator.methods[result[0]].call(this,element.value,element,param);
valid = valid && test;
message = $.format($.validator.messages[result[0]],param);
debug+=", result[0]="+result[0]+", param=["+result.slice(1).join(",")+"], valid="+(valid==true);
}
if(!valid){break;}
}
}
if(!valid){break;}
}
//$("#description").val(debug);
$this.checkError(valid,element,message);
return valid;
},
trimValue: function(element){
return element.value;
},
checkable: function( element ) {
return /radio|checkbox/i.test(element.type);
},
checkError: function(valid,element,message){
var after="<span class='validatemessage' style='background-color:red;font-weight:bold;color:white;cursor:pointer;'> ? </span>";
if(!valid){
if(!$(element).hasClass('invalid')){
$(element).addClass('invalid');
}
if($(element).next().is(".validatemessage")){
$(element).next().remove();
}
var error = $(after).attr('title',message);
$(element).after(error);
}else{
$(element).removeClass('invalid');
if($(element).next().is(".validatemessage")){
$(element).next().remove();
}
}
},
utf8Length: function(value){
if(!value||value.length==0){
return 0;
}
var cArr = value.match(/[^\x00-\xff]/ig);
var length = value.length + (cArr == null ? 0 : cArr.length)*2;
cArr = null;
return length;
},
optional: function(element){
return !$(element).hasClass("required");
},
length: function(value){
if(!value){
return 0;
}
return value.length;
}
},
methods: {
tolowercase: function(value, element, param){
element.value=value.toLowerCase();
return true;
},
touppercase: function(value, element, param){
element.value=value.toUpperCase();
return true;
},
required: function(value, element, param) {
switch( element.nodeName.toLowerCase() ) {
case 'select':
var options = $("option:selected", element);
return options.length > 0 && ( element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
case 'input':
if ( this.checkable(element) )
return this.getLength(value, element) > 0;
default:
return $.trim(value).length > 0;
}
},
word: function(value, element, param){
if(this.length(value)>0){
var reg = new RegExp("^[\\w]*$");
return reg.test(value);
}
return this.optional(element);
},
methodname: function(value, element, param){
var reg = new RegExp("^[a-zA-Z_]{1}[\\w]*$");
return reg.test(value);
},
javamethodname: function(value, element, param){
var test = new RegExp("^\\D+");
var reg = new RegExp("^[\u4e00-\u9fa5\\w]+$");
return test.test(value) && reg.test(value);
},
min: function(value, element, param){
if(this.length(value)<1){
return this.optional(element);
}
var val = parseFloat(value);
if(val == NaN){
return false;
}
if(param && param[0]){
var min = parseFloat(param[0]);
return val >= min;
}
},
max: function(value, element, param){
if(this.length(value)<1){
return this.optional(element);
}
var val = parseFloat(value);
if(val == NaN){
return false;
}
if(param && param[0]){
var max = parseFloat(param[0]);
return val <= max;
}
return this.optional(element);
},
minlength: function(value, element, param){
if(param && param[0]){
var min = parseInt(param[0]);
if(min==NaN){
return true;
}
return this.utf8Length(value) >= min;
}
return this.optional(element);
},
maxlength: function(value, element, param){
if(param && param[0]){
var max = parseInt(param[0]);
if(max==NaN||max<1){
return true;
}
return this.utf8Length(value) <= max;
}
return this.optional(element);
},
url: function(value, element, param){
return this.optional(element) || /^(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(value);
},
email: function(value, element, param){
return this.optional(element) || /^((([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(value);
},
date: function(value, element, param){
return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
},
dateiso: function(value, element, param){
return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
},
accept: function(value, element, param){
param = typeof param == "string" ? param : "png|jpe?g|gif";
return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
},
equalto: function(value, element, param){
if(param && param[0]){
return value == $("#"+param[0]).val();
}
return false;
},
datecn: function(value, element, param){
if(this.length(value)>0){
var reg = new RegExp("^(\\d{4})-(\\d{1,2})-(\\d{1,2})$");
if(!reg.test(value)){return false;}
var d = new Date(value.replace(reg, '$1/$2/$3'));
return (parseInt(RegExp.$2, 10) == (1+d.getMonth())) &&
(parseInt(RegExp.$3, 10) == d.getDate()) &&
(parseInt(RegExp.$1, 10) == d.getFullYear() );
}
return this.optional(element);
},
dateau: function(value, element, param){
if(this.length(value)>0){
var reg = new RegExp("^(\\d{2})\\/(\\d{2})\\/(\\d{4})$");
if(!reg.test(value)){return false;}
var d = new Date(value.replace(reg, '$3/$2/$1'));
return (parseInt(RegExp.$2, 10) == (1+d.getMonth())) &&
(parseInt(RegExp.$1, 10) == d.getDate()) &&
(parseInt(RegExp.$3, 10) == d.getFullYear() );
}
return this.optional(element);
},
chinese: function(value, element, param){
if(this.length(value)>0){
var reg = new RegExp("^[\u4e00-\u9fa5]+$");
return reg.test(value);
}
return this.optional(element);
},
number: function(value, element, param){
if(this.length(value)>0){
var reg = new RegExp("^\\d+$");
return reg.test(value);
}
return this.optional(element);
},
filename: function(value, element, param){
if(this.length(value)>0){
var reg = new RegExp("^[\u4e00-\u9fa5\\w]+\\.[\\w]+$");
return reg.test(value);
}
return this.optional(element);
}
},
tests: {
min: function(method){
var reg = new RegExp("^min-([-\\d]+)$");
if(!reg.test(method)){
return null;
}
var arr = new Array();
arr[0]="min";
arr[1]=$.trim(RegExp.$1);
return arr;
},
max: function(method){
var reg = new RegExp("^max-([-\\d]+)$");
if(!reg.test(method)){
return null;
}
var arr = new Array();
arr[0]="max";
arr[1]=$.trim(RegExp.$1);
return arr;
},
minlength: function(method){
var reg = new RegExp("^minlength-([-\\d]+)$");
if(!reg.test(method)){
return null;
}
var arr = new Array();
arr[0]="minlength";
arr[1]=$.trim(RegExp.$1);
return arr;
},
maxlength: function(method){
var reg = new RegExp("^maxlength-([-\\d]+)$");
if(!reg.test(method)){
return null;
}
var arr = new Array();
arr[0]="maxlength";
arr[1]=$.trim(RegExp.$1);
return arr;
},
equalto: function(method){
var reg = new RegExp("^equalto-(\\w+)$");
if(!reg.test(method)){
return null;
}
var arr = new Array();
arr[0]="equalto";
arr[1]=$.trim(RegExp.$1);
return arr;
}
},
messages: {
required: "该项是必填项",
word: "请输入字符为:英文字符、数字及下划线",
methodname: "请输入字符:以英文字符或下划线开头,以及与数字组合的字符串",
javamethodname: "请输入字符:以中文或英文字符或下划线开头,以及与数字组合的字符串",
min: "最小值为:{0}",
max: "最大值为:{0}",
minlength: "最小长度为:{0},其中非ASCII字符占三个长度",
maxlength: "最大长度为:{0},其中非ASCII字符占三个长度",
url: "请输入正确的URL地址",
email: "请输入正确的Email地址",
date: "请输入正确的日期格式",
dateiso: "请输入正确的日期格式",
accept: "只允许上传:png|jpe?g|gif",
equalto: "两次输入的值不相等",
datecn: "请使用这样的日期格式: yyyy-mm-dd. 例如:2006-03-17",
dateau: "请使用这样的日期格式: dd/mm/yyy. 例如:17/03/2009,表示2009年3月17日",
chinese: "请输入中文",
number: "请输入数字",
filename: "请输入文件名,不含空格"
}
});
})(jQuery);
// Custom selectors
;(function($){
$.extend($.expr[":"], {
// http://docs.jquery.com/Plugins/Validation/blank
blank: function(a) {return !$.trim(a.value);},
// http://docs.jquery.com/Plugins/Validation/filled
filled: function(a) {return !!$.trim(a.value);},
// http://docs.jquery.com/Plugins/Validation/unchecked
unchecked: function(a) {return !a.checked;}
});
})(jQuery);
//format
;(function($){
$.extend({
format : function(source, params) {
if ( arguments.length == 1 )
return function() {
var args = $.makeArray(arguments);
args.unshift(source);
return $.format.apply( this, args );
};
if ( arguments.length > 2 && params.constructor != Array ) {
params = $.makeArray(arguments).slice(1);
}
if ( params.constructor != Array ) {
params = [ params ];
}
$.each(params, function(i, n) {
source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
});
return source;
}
});
})(jQuery);
// provides cross-browser focusin and focusout events
// IE has native support, in other browsers, use event caputuring (neither bubbles)
// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
// provides triggerEvent(type: String, target: Element) to trigger delegated events
;(function($) {
$.each({
focus: 'focusin',
blur: 'focusout'
}, function( original, fix ){
$.event.special[fix] = {
setup:function() {
if ( $.browser.msie ) return false;
this.addEventListener( original, $.event.special[fix].handler, true );
},
teardown:function() {
if ( $.browser.msie ) return false;
this.removeEventListener( original,
$.event.special[fix].handler, true );
},
handler: function(e) {
arguments[0] = $.event.fix(e);
arguments[0].type = fix;
return $.event.handle.apply(this, arguments);
}
};
});
$.extend($.fn, {
delegate: function(type, delegate, handler) {
return this.bind(type, function(event) {
var target = $(event.target);
if (target.is(delegate)) {
return handler.apply(target, arguments);
}
});
},
triggerEvent: function(type, target) {
return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);
}
})
})(jQuery);
//
;(function($){
$(".validatemessage").live('click',function(){
alert(this.title);
});
})(jQuery);
测试页面HTML代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.iff.validate.js"></script>
</HEAD>
<BODY>
<form action="" method="POST">
<table width="100%">
<tr>
<td>必需字段 class="validate required"</td>
<td><input type="text" class="validate required"></td>
</tr>
<tr>
<td>最小值 class="validate min-32"</td>
<td><input type="text" class="validate min-32"></td>
</tr>
<tr>
<td>最大值 class="validate max-32"</td>
<td><input type="text" class="validate max-32"></td>
</tr>
<tr>
<td>最小长度 class="validate minlength-32"</td>
<td><input type="text" class="validate minlength-32"></td>
</tr>
<tr>
<td>最大值 class="validate maxlength-32"</td>
<td><input type="text" class="validate maxlength-32"></td>
</tr>
<tr>
<td>英文字符、数字、下划线 class="validate word"</td>
<td><input type="text" class="validate word"></td>
</tr>
<tr>
<td>英文字符、数字、下划线,数字不能开头 class="validate methodname"</td>
<td><input type="text" class="validate methodname"></td>
</tr>
<tr>
<td>中英文字符、数字、下划线,数字不能开头 class="validate javamethodname"</td>
<td><input type="text" class="validate javamethodname"></td>
</tr>
<tr>
<td>日期格式:yyyy-MM-dd class="validate datecn"</td>
<td><input type="text" class="validate datecn"></td>
</tr>
<tr>
<td>日期格式:dd-MM-yyyy class="validate dateau"</td>
<td><input type="text" class="validate dateau"></td>
</tr>
<tr>
<td>中文:dd-MM-yyyy class="validate chinese"</td>
<td><input type="text" class="validate chinese"></td>
</tr>
<tr>
<td>数字: class="validate number"</td>
<td><input type="text" class="validate number"></td>
</tr>
<tr>
<td>文件名[中英文数字下划线.英文]: class="validate filename"</td>
<td><input type="text" class="validate filename"></td>
</tr>
<tr>
<td>自动转换为小写字符: class="validate tolowercase"</td>
<td><input type="text" class="validate tolowercase"></td>
</tr>
<tr>
<td>自动转换为大写字符: class="validate touppercase"</td>
<td><input type="text" class="validate touppercase"></td>
</tr>
<tr>
<td>提交表单前验证</td>
<td>
jQuery(document).ready(
function(){
jQuery("form").submit(function(){
return jQuery('.validate').validate({submit:true});
});
}
);
</td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="取消"></td>
</tr>
</table>
</form>
<hr/>
扩展:
validate.js中有三个数组属性methods:{},tests: {},messages: {}
其中验证的方法都放在methods:{}中,如果带有参数的验证那么需要在tests: {}中添加方法把参数分离出来
而messages: {}中放置错误信息(未有国际化)
</BODY>
<script type="text/javascript">
jQuery(document).ready(
function(){
jQuery("form").submit(function(){
return jQuery('.validate').validate({submit:true});
});
}
);
</script>
</HTML>