//==================================================================================================== // [插件名称] jquery formvalidator //---------------------------------------------------------------------------------------------------- // [描 述] jquery formvalidator表单验证插件,它是基于jquery类库,实现了js脚本于页面的分离。对一个表 // 单对象,你只需要写一行代码就可以轻松实现20种以上的脚本控制。现支持一个表单元素累加很多种 // 校验方式,采用配置信息的思想,而不是把信息写在表单元素上,能比较完美的实现ajax请求。 //---------------------------------------------------------------------------------------------------- // [作者网名] 猫冬 // [邮 箱] wzmaodong@126.com // [作者博客] http://wzmaodong.cnblogs.com // [更新日期] 2008-01-24 // [版 本 号] ver3.3 //==================================================================================================== var jquery_formvalidator_initconfig; (function($) { $.formvalidator = { //各种校验方式支持的控件类型 sustaintype : function(id,setting) { var elem = $("#"+id).get(0); var srctag = elem.tagname; var stype = elem.type; switch(setting.validatetype) { case "initvalidator": return true; case "inputvalidator": if (srctag == "input" || srctag == "textarea" || srctag == "select"){ return true; }else{ return false; } case "comparevalidator": if (srctag == "input" || srctag == "textarea") { if (stype == "checkbox" || stype == "radio"){ return false; }else{ return true; } } return false; case "ajaxvalidator": if (stype == "text" || stype == "textarea" || stype == "file" || stype == "password" || stype == "select-one"){ return true; }else{ return false; } case "regexvalidator": if (srctag == "input" || srctag == "textarea") { if (stype == "checkbox" || stype == "radio"){ return false; }else{ return true; } } return false; case "functionvalidator": return true; } }, initconfig : function(controloptions) { var settings = { debug:false, validatorgroup : "1", alertmessage:false, validobjectids:"", forcevalid:false, onsuccess: function() {return true;}, onerror:function() {}, submitonce:false, formid:"", autotip: false, tidymode:false, errorfocus:true, wideword:true }; controloptions = controloptions || {}; $.extend(settings, controloptions); //如果是精简模式,发生错误的时候,第一个错误的控件就不获得焦点 if(settings.tidymode){settings.errorfocus=false}; if(settings.formid!=""){$("#"+settings.formid).submit(function(){return $.formvalidator.pageisvalid("1");})}; if (jquery_formvalidator_initconfig == null ){jquery_formvalidator_initconfig = new array();} jquery_formvalidator_initconfig.push( settings ); }, //如果validator对象对应的element对象的validator属性追加要进行的校验。 appendvalid : function(id, setting ) { //如果是各种校验不支持的类型,就不追加到。返回-1表示没有追加成功 if(!$.formvalidator.sustaintype(id,setting)) return -1; var srcjo = $("#"+id).get(0); //重新初始化 if (setting.validatetype=="initvalidator" || srcjo.settings == undefined ){srcjo.settings = new array();} var len = srcjo.settings.push( setting ); srcjo.settings[len - 1].index = len - 1; return len - 1; }, //如果validator对象对应的element对象的validator属性追加要进行的校验。 getinitconfig : function( validatorgroup ) { if(jquery_formvalidator_initconfig!=null) { for(i=0;i= 0x4e00 && val.charcodeat(i) <= 0x9fa5){ len += 2; }else { len++; } } } else{ len = val.length; } break; case "checkbox": case "radio": len = $("input[@type='"+stype+"'][@name='"+srcjo.attr("name")+"'][@checked]").length; break; case "select-one": len = elem.options ? elem.options.selectedindex : -1; break; case "select-multiple": len = $("select[@name="+elem.name+"] option[@selected]").length; break; } return len; }, //结合empty这个属性,判断仅仅是否为空的校验情况。 isempty : function(id) { if($("#"+id).get(0).settings[0].empty && $.formvalidator.getlength(id)==0){ return true; }else{ return false; } }, //对外调用:判断单个表单元素是否验证通过,不带回调函数 isonevalid : function(id) { return $.formvalidator.oneisvalid(id,1).isvalid; }, //验证单个是否验证通过,正确返回settings[0],错误返回对应的settings[i] oneisvalid : function (id,index) { var returnobj = new object(); returnobj.id = id; returnobj.ajax = -1; returnobj.errormsg = ""; //自定义错误信息 var elem = $("#"+id).get(0); var settings = elem.settings; var settingslen = settings.length; //只有一个formvalidator的时候不检验 if (settingslen==1){settings[0].bind=false;} if(!settings[0].bind){return null;} for ( var i = 0 ; i < settingslen ; i ++ ) { if(i==0){ if($.formvalidator.isempty(id)){ returnobj.isvalid = true; returnobj.setting = settings[0]; break; } continue; } returnobj.setting = settings[i]; if(settings[i].validatetype!="ajaxvalidator") { $.formvalidator.triggervalidate(returnobj); }else{ returnobj.ajax = i; } if(!settings[i].isvalid) { returnobj.isvalid = false; returnobj.setting = settings[i]; break; }else{ returnobj.isvalid = true; returnobj.setting = settings[0]; if(settings[i].validatetype=="ajaxvalidator") break; } } return returnobj; }, //验证所有需要验证的对象,并返回是否验证成功。 pageisvalid : function (validatorgroup) { if(validatorgroup == null || validatorgroup == undefined){validatorgroup = "1"}; var isvalid = true; var thefirstid = "",thefirsterrmsg; var returnobj,setting; var error_tip = "^"; var initconfig = $.formvalidator.getinitconfig(validatorgroup); var jqobjs = $(initconfig.validobjectids); jqobjs.each(function(i,elem) { if(elem.settings[0].bind){ returnobj = $.formvalidator.oneisvalid(elem.id,1); if(returnobj) { var tipid = elem.settings[0].tipid; //校验失败,获取第一个发生错误的信息和id if (!returnobj.isvalid) { isvalid = false; if (thefirstid == ""){ thefirstid = returnobj.id; thefirsterrmsg = (returnobj.errormsg==""?returnobj.setting.onerror:returnobj.errormsg) } } //为了解决使用同个tip提示问题:后面的成功或失败都不覆盖前面的失败 if (!initconfig.alertmessage){ if (error_tip.indexof("^" + tipid + "^") == -1) { if (!returnobj.isvalid) { error_tip = error_tip + tipid + "^"; } $.formvalidator.showmessage(returnobj); } } } } }); //成功或失败后,进行回调函数的处理,以及成功后的灰掉提交按钮的功能 if(isvalid) { isvalid = initconfig.onsuccess(); if(initconfig.submitonce){$("input[@type='submit']").attr("disabled",true);} } else { var obj = $("#"+thefirstid).get(0); initconfig.onerror(thefirsterrmsg,obj); if(thefirstid!="" && initconfig.errorfocus){$("#"+thefirstid).focus();} } return !initconfig.debug && isvalid; }, //ajax校验 ajaxvalid : function(returnobj) { var id = returnobj.id; var srcjo = $("#"+id); var elem = srcjo.get(0); var settings = elem.settings; var setting = settings[returnobj.ajax]; var ls_url = setting.url; if (srcjo.size() == 0 && settings[0].empty) { returnobj.setting = settings[0]; returnobj.isvalid = true; $.formvalidator.showmessage(returnobj); setting.isvalid = true; return; } if(setting.addidvalue) { var parm = "clientid="+id+"&"+id+"="+encodeuricomponent(srcjo.val()); ls_url = ls_url + (ls_url.indexof("?")>0?("&"+ parm) : ("?"+parm)); } $.ajax( { mode : "abort", type : setting.type, url : ls_url, cache : setting.cache, data : setting.data, async : setting.async, datatype : setting.datatype, success : function(data){ if(setting.success(data)) { $.formvalidator.settipstate(elem,"oncorrect",settings[0].oncorrect); setting.isvalid = true; } else { $.formvalidator.settipstate(elem,"onerror",setting.onerror); setting.isvalid = false; } }, complete : function(){ if(setting.buttons && setting.buttons.length > 0){setting.buttons.attr({"disabled":false})}; setting.complete; }, beforesend : function(xhr){ //再服务器没有返回数据之前,先回调提交按钮 if(setting.buttons && setting.buttons.length > 0){setting.buttons.attr({"disabled":true})}; var isvalid = setting.beforesend(xhr); if(isvalid) { setting.isvalid = false; //如果前面ajax请求成功了,再次请求之前先当作错误处理 $.formvalidator.settipstate(elem,"onload",settings[returnobj.ajax].onwait); } setting.lastvalid = "-1"; return isvalid; }, error : function(){ $.formvalidator.settipstate(elem,"onerror",setting.onerror); setting.isvalid = false; setting.error(); }, processdata : setting.processdata }); }, //对正则表达式进行校验(目前只针对input和textarea) regexvalid : function(returnobj) { var id = returnobj.id; var setting = returnobj.setting; var srctag = $("#"+id).get(0).tagname; var elem = $("#"+id).get(0); //如果有输入正则表达式,就进行表达式校验 if(elem.settings[0].empty && elem.value==""){ setting.isvalid = true; } else { var regexpress = setting.regexp; if(setting.datatype=="enum"){regexpress = eval("regexenum."+regexpress);} if(regexpress==undefined || regexpress==""){ setting.isvalid = false; return; } setting.isvalid = (new regexp(regexpress, setting.param)).test($("#"+id).val()); } }, //函数校验。返回true/false表示校验是否成功;返回字符串表示错误信息,校验失败;如果没有返回值表示处理函数,校验成功 functionvalid : function(returnobj) { var id = returnobj.id; var setting = returnobj.setting; var srcjo = $("#"+id); var lb_ret = setting.fun(srcjo.val(),srcjo.get(0)); if(lb_ret != undefined) { if(typeof lb_ret == "string"){ setting.isvalid = false; returnobj.errormsg = lb_ret; }else{ setting.isvalid = lb_ret; } } }, //对input和select类型控件进行校验 inputvalid : function(returnobj) { var id = returnobj.id; var setting = returnobj.setting; var srcjo = $("#"+id); var elem = srcjo.get(0); var val = srcjo.val(); var stype = elem.type; var len = $.formvalidator.getlength(id); var empty = setting.empty,emptyerror = false; switch(stype) { case "text": case "hidden": case "password": case "textarea": case "file": if (setting.type == "size") { empty = setting.empty; if(!empty.leftempty){ emptyerror = (val.replace(/^[ \s]+/, '').length != val.length); } if(!emptyerror && !empty.rightempty){ emptyerror = (val.replace(/[ \s]+$/, '').length != val.length); } if(emptyerror && empty.emptyerror){returnobj.errormsg= empty.emptyerror} } case "checkbox": case "select-one": case "select-multiple": case "radio": var lb_go_on = false; if(stype=="select-one" || stype=="select-multiple"){setting.type = "size";} var type = setting.type; if (type == "size") { //获得输入的字符长度,并进行校验 if(!emptyerror){lb_go_on = true} if(lb_go_on){val = len} } else if (type =="date" || type =="datetime") { var isok = false; if(type=="date"){lb_go_on = isdate(val)}; if(type=="datetime"){lb_go_on = isdate(val)}; if(lb_go_on){val = new date(val);setting.min=new date(setting.min);setting.max=new date(setting.max);}; }else{ stype = (typeof setting.min); if(stype =="number") { val = (new number(val)).valueof(); if(!isnan(val)){lb_go_on = true;} } if(stype =="string"){lb_go_on = true;} } setting.isvalid = false; if(lb_go_on) { if(val < setting.min || val > setting.max){ if(val < setting.min && setting.onerrormin){ returnobj.errormsg= setting.onerrormin; } if(val > setting.min && setting.onerrormax){ returnobj.errormsg= setting.onerrormax; } } else{ setting.isvalid = true; } } break; } }, comparevalid : function(returnobj) { var id = returnobj.id; var setting = returnobj.setting; var srcjo = $("#"+id); var desjo = $("#"+setting.desid ); var ls_datatype = setting.datatype; setting.isvalid = false; curvalue = srcjo.val(); ls_data = desjo.val(); if(ls_datatype=="number") { if(!isnan(curvalue) && !isnan(ls_data)){ curvalue = parsefloat(curvalue); ls_data = parsefloat(ls_data); } else{ return; } } if(ls_datatype=="date" || ls_datatype=="datetime") { var isok = false; if(ls_datatype=="date"){isok = (isdate(curvalue) && isdate(ls_data))}; if(ls_datatype=="datetime"){isok = (isdatetime(curvalue) && isdatetime(ls_data))}; if(isok){ curvalue = new date(curvalue); ls_data = new date(ls_data) } else{ return; } } switch(setting.operateor) { case "=": if(curvalue == ls_data){setting.isvalid = true;} break; case "!=": if(curvalue != ls_data){setting.isvalid = true;} break; case ">": if(curvalue > ls_data){setting.isvalid = true;} break; case ">=": if(curvalue >= ls_data){setting.isvalid = true;} break; case "<": if(curvalue < ls_data){setting.isvalid = true;} break; case "<=": if(curvalue <= ls_data){setting.isvalid = true;} break; } }, localtooltip : function(e) { e = e || window.event; var mousex = e.pagex || (e.clientx ? e.clientx + document.body.scrollleft : 0); var mousey = e.pagey || (e.clienty ? e.clienty + document.body.scrolltop : 0); $("#fvtt").css({"top":(mousey+2)+"px","left":(mousex-40)+"px"}); } }; //每个校验控件必须初始化的 $.fn.formvalidator = function(cs) { var setting = { validatorgroup : "1", empty :false, submitonce : false, automodify : false, onshow :"请输入内容", onfocus: "请输入内容", oncorrect: "输入正确", onempty: "输入内容为空", defaultvalue : null, bind : true, validatetype : "initvalidator", tipcss : { "left" : "10px", "top" : "1px", "height" : "20px", "width":"250px" }, triggerevent:"blur", forcevalid : false }; //获取该校验组的全局配置信息 cs = cs || {}; if(cs.validatorgroup == undefined){cs.validatorgroup = "1"}; var initconfig = $.formvalidator.getinitconfig(cs.validatorgroup); //如果为精简模式,tipcss要重新设置初始值 if(initconfig.tidymode){setting.tipcss = {"left" : "2px","width":"22px","height":"22px","display":"none"}}; //先合并整个配置(深度拷贝) $.extend(true,setting, cs); return this.each(function(e) { var jqobj = $(this); var setting_temp = {}; $.extend(true,setting_temp, setting); var tip = setting_temp.tipid ? setting_temp.tipid : this.id+"tip"; //自动形成tip if(initconfig.autotip) { //获取层的id、相对定位控件的id和坐标 if($("body [id="+tip+"]").length==0) { aftertip = setting_temp.relativeid ? setting_temp.relativeid : this.id; var obj = gettopleft(aftertip); var y = obj.top; var x = getelementwidth(aftertip) + obj.left; $("
").appendto($("body")).css({left: x+"px", top: y+"px"}).prepend($('
').css(setting_temp.tipcss)); } if(initconfig.tidymode){jqobj.showtooltips()}; } //每个控件都要保存这个配置信息 setting.tipid = tip; $.formvalidator.appendvalid(this.id,setting); //保存控件id var validobjectids = initconfig.validobjectids; if(validobjectids.indexof("#"+this.id+" ")==-1){ initconfig.validobjectids = (validobjectids=="" ? "#"+this.id : validobjectids + ",#" + this.id); } //初始化显示信息 if(!initconfig.alertmessage){ $.formvalidator.settipstate(this,"onshow",setting.onshow); } var srctag = this.tagname.tolowercase(); var stype = this.type; var defaultval = setting.defaultvalue; //处理默认值 if(defaultval){ jqobj.val(defaultval); } if(srctag == "input" || srctag=="textarea") { //注册获得焦点的事件。改变提示对象的文字和样式,保存原值 jqobj.focus(function() { if(!initconfig.alertmessage){ //保存原来的状态 var tipjq = $("#"+tip); this.lastshowclass = tipjq.attr("class"); this.lastshowmsg = tipjq.html(); $.formvalidator.settipstate(this,"onfocus",setting.onfocus); } if (stype == "password" || stype == "text" || stype == "textarea" || stype == "file") { this.validoldvalue = jqobj.val(); } }); //注册失去焦点的事件。进行校验,改变提示对象的文字和样式;出错就提示处理 jqobj.bind(setting.triggerevent, function(){ var settings = this.settings; var returnobj = $.formvalidator.oneisvalid(this.id,1); if(returnobj==null){return;} if(returnobj.ajax >= 0) { $.formvalidator.showajaxmessage(returnobj); } else { var showmsg = $.formvalidator.showmessage(returnobj); if(!returnobj.isvalid) { //自动修正错误 var auto = setting.automodify && (this.type=="text" || this.type=="textarea" || this.type=="file"); if(auto && !initconfig.alertmessage) { alert(showmsg); $.formvalidator.settipstate(this,"onshow",setting.onshow); } else { if(initconfig.forcevalid || setting.forcevalid){ alert(showmsg);this.focus(); } } } } }); } else if (srctag == "select") { //获得焦点 jqobj.bind("focus", function(){ if(!initconfig.alertmessage){ $.formvalidator.settipstate(this,"onfocus",setting.onfocus); } }); //失去焦点 jqobj.bind("blur",function(){jqobj.trigger("change")}); //选择项目后触发 jqobj.bind("change",function() { var returnobj = $.formvalidator.oneisvalid(this.id,1); if(returnobj==null){return;} if ( returnobj.ajax >= 0){ $.formvalidator.showajaxmessage(returnobj); }else{ $.formvalidator.showmessage(returnobj); } }); } }); }; $.fn.inputvalidator = function(controloptions) { var settings = { isvalid : false, min : 0, max : 99999999999999, type : "size", onerror:"输入错误", validatetype:"inputvalidator", empty:{leftempty:true,rightempty:true,leftemptyerror:null,rightemptyerror:null}, wideword:true }; controloptions = controloptions || {}; $.extend(true, settings, controloptions); return this.each(function(){ $.formvalidator.appendvalid(this.id,settings); }); }; $.fn.comparevalidator = function(controloptions) { var settings = { isvalid : false, desid : "", operateor :"=", onerror:"输入错误", validatetype:"comparevalidator" }; controloptions = controloptions || {}; $.extend(true, settings, controloptions); return this.each(function(){ $.formvalidator.appendvalid(this.id,settings); }); }; $.fn.regexvalidator = function(controloptions) { var settings = { isvalid : false, regexp : "", param : "i", datatype : "string", onerror:"输入的格式不正确", validatetype:"regexvalidator" }; controloptions = controloptions || {}; $.extend(true, settings, controloptions); return this.each(function(){ $.formvalidator.appendvalid(this.id,settings); }); }; $.fn.functionvalidator = function(controloptions) { var settings = { isvalid : true, fun : function(){this.isvalid = true;}, validatetype:"functionvalidator", onerror:"输入错误" }; controloptions = controloptions || {}; $.extend(true, settings, controloptions); return this.each(function(){ $.formvalidator.appendvalid(this.id,settings); }); }; $.fn.ajaxvalidator = function(controloptions) { var settings = { isvalid : false, lastvalid : "", type : "get", url : "", addidvalue : true, datatype : "html", data : "", async : true, cache : false, beforesend : function(){return true;}, success : function(){return true;}, complete : function(){}, processdata : false, error : function(){}, buttons : null, onerror:"服务器校验没有通过", onwait:"正在等待服务器返回数据", validatetype:"ajaxvalidator" }; controloptions = controloptions || {}; $.extend(true, settings, controloptions); return this.each(function() { $.formvalidator.appendvalid(this.id,settings); }); }; $.fn.defaultpassed = function(onshow) { return this.each(function() { var settings = this.settings; for ( var i = 1 ; i < settings.length ; i ++ ) { settings[i].isvalid = true; if(!$.formvalidator.getinitconfig(settings[0].validatorgroup).alertmessage){ var ls_style = onshow ? "onshow" : "oncorrect"; $.formvalidator.settipstate(this,ls_style,settings[0].oncorrect); } } }); }; $.fn.unformvalidator = function(unbind) { return this.each(function() { this.settings[0].bind = !unbind; if(unbind){ $("#"+this.settings[0].tipid).hide(); }else{ $("#"+this.settings[0].tipid).show(); } }); }; $.fn.showtooltips = function() { if($("body [id=fvtt]").length==0){ fvtt = $("
"); $("body").append(fvtt); fvtt.before(""); } return this.each(function() { jqobj = $(this); s = $(""); b = $(""); this.tooltip = $("").append(s).append(b).css({"filter":"alpha(opacity:95)","khtmlopacity":"0.95","mozopacity":"0.95","opacity":"0.95"}); //注册事件 jqobj.mouseover(function(e){ $("#fvtt").append(this.tooltip); $("#fv_content").html(this.tooltip); $.formvalidator.localtooltip(e); }); jqobj.mouseout(function(){ $("#fvtt").empty(); }); jqobj.mousemove(function(e){ $("#fv_content").html(this.tooltip); $.formvalidator.localtooltip(e); }); }); } })(jquery); function getelementwidth(objectid) { x = document.getelementbyid(objectid); return x.offsetwidth; } function gettopleft(objectid) { obj = new object(); o = document.getelementbyid(objectid); oleft = o.offsetleft; otop = o.offsettop; while(o.offsetparent!=null) { oparent = o.offsetparent; oleft += oparent.offsetleft; otop += oparent.offsettop; o = oparent; } obj.top = otop; obj.left = oleft; return obj; }