/*
通用表单验证方法
validform version 5.3.2
by sean during april 7, 2010 - march 26, 2013
for more information, please visit http://validform.rjboy.cn
validform is available under the terms of the mit license.
demo:
$(".demoform").validform({//$(".demoform")指明是哪一表单需要验证,名称需加在form表单上;
btnsubmit:"#btn_sub", //#btn_sub是该表单下要绑定点击提交表单事件的按钮;如果form内含有submit按钮该参数可省略;
btnreset:".btn_reset",//可选项 .btn_reset是该表单下要绑定点击重置表单事件的按钮;
tiptype:1, //可选项 1=>pop box,2=>side tip(parent.next.find; with default pop),3=>side tip(siblings; with default pop),4=>side tip(siblings; none pop),默认为1,也可以传入一个function函数,自定义提示信息的显示方式(可以实现你想要的任何效果,具体参见demo页);
ignorehidden:false,//可选项 true | false 默认为false,当为true时对:hidden的表单元素将不做验证;
dragonfly:false,//可选项 true | false 默认false,当为true时,值为空时不做验证;
tipsweep:true,//可选项 true | false 默认为false,只在表单提交时触发检测,blur事件将不会触发检测(实时验证会在后台进行,不会显示检测结果);
label:".label",//可选项 选择符,在没有绑定nullmsg时查找要显示的提示文字,默认查找".validform_label"下的文字;
showallerror:false,//可选项 true | false,true:提交表单时所有错误提示信息都会显示,false:一碰到验证不通过的就停止检测后面的元素,只显示该元素的错误信息;
postonce:true, //可选项 表单是否只能提交一次,true开启,不填则默认关闭;
ajaxpost:true, //使用ajax方式提交表单数据,默认false,提交地址就是action指定地址;
datatype:{//传入自定义datatype类型,可以是正则,也可以是函数(函数内会传入一个参数);
"*6-20": /^[^\s]{6,20}$/,
"z2-4" : /^[\u4e00-\u9fa5\uf900-\ufa2d]{2,4}$/,
"username":function(gets,obj,curform,regxp){
//参数gets是获取到的表单元素值,obj为当前表单元素,curform为当前验证的表单,regxp为内置的一些正则表达式的引用;
var reg1=/^[\w\.]{4,16}$/,
reg2=/^[\u4e00-\u9fa5\uf900-\ufa2d]{2,8}$/;
if(reg1.test(gets)){return true;}
if(reg2.test(gets)){return true;}
return false;
//注意return可以返回true 或 false 或 字符串文字,true表示验证通过,返回字符串表示验证失败,字符串作为错误提示显示,返回false则用errmsg或默认的错误提示;
},
"phone":function(){
// 5.0 版本之后,要实现二选一的验证效果,datatype 的名称 不 需要以 "option_" 开头;
}
},
useplugin:{
swfupload:{},
datepicker:{},
passwordstrength:{},
jqtransform:{
selector:"select,input"
}
},
beforecheck:function(curform){
//在表单提交执行验证之前执行的函数,curform参数是当前表单对象。
//这里明确return false的话将不会继续执行验证操作;
},
beforesubmit:function(curform){
//在验证成功后,表单提交前执行的函数,curform参数是当前表单对象。
//这里明确return false的话表单将不会提交;
},
callback:function(data){
//返回数据data是json格式,{"info":"demo info","status":"y"}
//info: 输出提示信息;
//status: 返回提交数据的状态,是否提交成功。如可以用"y"表示提交成功,"n"表示提交失败,在ajax_post.php文件返回数据里自定字符,主要用在callback函数里根据该值执行相应的回调操作;
//你也可以在ajax_post.php文件返回更多信息在这里获取,进行相应操作;
//ajax遇到服务端错误时也会执行回调,这时的data是{ status:**, statustext:**, readystate:**, responsetext:** };
//这里执行回调操作;
//注意:如果不是ajax方式提交表单,传入callback,这时data参数是当前表单对象,回调函数会在表单验证全部通过后执行,然后判断是否提交表单,如果callback里明确return false,则表单不会提交,如果return true或没有return,则会提交表单。
}
});
validform对象的方法和属性:
tipmsg:自定义提示信息,通过修改validform对象的这个属性值来让同一个页面的不同表单使用不同的提示文字;
datatype:获取内置的一些正则;
eq(n):获取validform对象的第n个元素;
ajaxpost(flag,sync,url):以ajax方式提交表单。flag为true时,跳过验证直接提交,sync为true时将以同步的方式进行ajax提交,传入了url地址时,表单会提交到这个地址;
abort():终止ajax的提交;
submitform(flag,url):以参数里设置的方式提交表单,flag为true时,跳过验证直接提交,传入了url地址时,表单会提交到这个地址;
resetform():重置表单;
resetstatus():重置表单的提交状态。传入了postonce参数的话,表单成功提交后状态会设置为"posted",重置提交状态可以让表单继续可以提交;
getstatus():获取表单的提交状态,normal:未提交,posting:正在提交,posted:已成功提交过;
setstatus(status):设置表单的提交状态,可以设置normal,posting,posted三种状态,不传参则设置状态为posting,这个状态表单可以验证,但不能提交;
ignore(selector):忽略对所选择对象的验证;
unignore(selector):将ignore方法所忽略验证的对象重新获取验证效果;
addrule(rule):可以通过validform对象的这个方法来给表单元素绑定验证规则;
check(bool,selector):对指定对象进行验证(默认验证当前整个表单),通过返回true,否则返回false(绑定实时验证的对象,格式符合要求时返回true,而不会等ajax的返回结果),bool为true时则只验证不显示提示信息;
config(setup):可以通过这个方法来修改初始化参数,指定表单的提交地址,给表单ajax和实时验证的ajax里设置参数;
*/
(function($,win,undef){
var errorobj=null,//指示当前验证失败的表单元素;
msgobj=null,//pop box object
msghidden=true;//msgbox hidden?
var tipmsg={//默认提示文字;
tit:"提示信息",
w:{
"*":"不能为空!",
"*6-16":"请填写6到16位任意字符!",
"n":"请填写数字!",
"n6-16":"请填写6到16位数字!",
"s":"不能输入特殊字符!",
"s6-18":"请填写6到18位字符!",
"p":"请填写邮政编码!",
"v":"请填写四位验证码!",
"m":"请填写手机号码!",
"e":"邮箱地址格式不对!",
"username":"2-16位数字或字母!",
"url":"请填写网址!"
},
def:"请填写正确信息!",
undef:"datatype未定义!",
reck:"两次输入的内容不一致!",
r:"通过信息验证!",
c:"正在检测信息…",
s:"请{填写|选择}{0|信息}!",
v:"所填信息没有经过验证,请稍后…",
p:"正在提交数据…"
}
$.tipmsg=tipmsg;
var validform=function(forms,settings,inited){
var settings=$.extend({},validform.defaults,settings);
settings.datatype && $.extend(validform.util.datatype,settings.datatype);
var brothers=this;
brothers.tipmsg={w:{}};
brothers.forms=forms;
brothers.objects=[];
//创建子对象时不再绑定事件;
if(inited===true){
return false;
}
forms.each(function(){
//已经绑定事件时跳过,避免事件重复绑定;
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
var curform=this;
curform.settings=$.extend({},settings);
var $this=$(curform);
//防止表单按钮双击提交两次;
curform.validform_status="normal"; //normal | posting | posted;
//让每个validform对象都能自定义tipmsg;
$this.data("tipmsg",brothers.tipmsg);
//bind the blur event;
$this.delegate("[datatype]","blur",function(){
//判断是否是在提交表单操作时触发的验证请求;
var subpost=arguments[1];
validform.util.check.call(this,$this,subpost);
});
$this.delegate(":text","keypress",function(event){
if(event.keycode==13 && $this.find(":submit").length==0){
$this.submit();
}
});
//点击表单元素,默认文字消失效果;
//表单元素值比较时的信息提示增强;
//radio、checkbox提示信息增强;
//外调插件初始化;
validform.util.enhance.call($this,curform.settings.tiptype,curform.settings.useplugin,curform.settings.tipsweep);
curform.settings.btnsubmit && $this.find(curform.settings.btnsubmit).bind("click",function(){
$this.trigger("submit");
return false;
});
$this.submit(function(){
var subflag=validform.util.submitform.call($this,curform.settings);
subflag === undef && (subflag=true);
return subflag;
});
$this.find("[type='reset']").add($this.find(curform.settings.btnreset)).bind("click",function(){
validform.util.resetform.call($this);
});
});
//预创建pop box;
if( settings.tiptype==1 || (settings.tiptype==2 || settings.tiptype==3) && settings.ajaxpost ){
creatmsgbox();
}
}
validform.defaults={
tiptype:1,
tipsweep:false,
showallerror:false,
postonce:false,
ajaxpost:false
}
validform.util={
datatype:{
"*":/[\w\w]+/,
"*6-16":/^[\w\w]{6,16}$/,
"n":/^\d+$/,
"n6-16":/^\d{6,16}$/,
"s":/^[\u4e00-\u9fa5\uf900-\ufa2d\w\.\s]+$/,
"s6-18":/^[\u4e00-\u9fa5\uf900-\ufa2d\w\.\s]{6,18}$/,
"p":/^[0-9]{6}$/,
"v":/^[\w\w]{4}$/,
"m":/^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|18[0-9]{9}$/,
"e":/^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
"username":/^[a-za-z0-9]{2,16}$/,
"url":/^http[s]?:\/\/[a-za-z0-9]+\.[a-za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/
},
tostring:object.prototype.tostring,
isempty:function(val){
return val==="" || val===$.trim(this.attr("tip"));
},
getvalue:function(obj){
var inputval,
curform=this;
if(obj.is(":radio")){
inputval=curform.find(":radio[name='"+obj.attr("name")+"']:checked").val();
inputval= inputval===undef ? "" : inputval;
}else if(obj.is(":checkbox")){
inputval="";
curform.find(":checkbox[name='"+obj.attr("name")+"']:checked").each(function(){
inputval +=$(this).val()+',';
})
inputval= inputval===undef ? "" : inputval;
}else{
inputval=obj.val();
}
inputval=$.trim(inputval);
return validform.util.isempty.call(obj,inputval) ? "" : inputval;
},
enhance:function(tiptype,useplugin,tipsweep,addrule){
var curform=this;
//页面上不存在提示信息的标签时,自动创建;
curform.find("[datatype]").each(function(){
if(tiptype==2){
if($(this).parent().next().find(".validform_checktip").length==0){
$(this).parent().next().append("");
$(this).siblings(".validform_checktip").remove();
}
}else if(tiptype==3 || tiptype==4){
if($(this).siblings(".validform_checktip").length==0){
$(this).parent().append("");
$(this).parent().next().find(".validform_checktip").remove();
}
}
})
//表单元素值比较时的信息提示增强;
curform.find("input[recheck]").each(function(){
//已经绑定事件时跳过;
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
var _this=$(this);
var recheckinput=curform.find("input[name='"+$(this).attr("recheck")+"']");
recheckinput.bind("keyup",function(){
if(recheckinput.val()==_this.val() && recheckinput.val() != ""){
if(recheckinput.attr("tip")){
if(recheckinput.attr("tip") == recheckinput.val()){return false;}
}
_this.trigger("blur");
}
}).bind("blur",function(){
if(recheckinput.val()!=_this.val() && _this.val()!=""){
if(_this.attr("tip")){
if(_this.attr("tip") == _this.val()){return false;}
}
_this.trigger("blur");
}
});
});
//hasdefaulttext;
curform.find("[tip]").each(function(){//tip是表单元素的默认提示信息,这是点击清空效果;
//已经绑定事件时跳过;
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
var defaultvalue=$(this).attr("tip");
var altercss=$(this).attr("altercss");
$(this).focus(function(){
if($(this).val()==defaultvalue){
$(this).val('');
if(altercss){$(this).removeclass(altercss);}
}
}).blur(function(){
if($.trim($(this).val())===''){
$(this).val(defaultvalue);
if(altercss){$(this).addclass(altercss);}
}
});
});
//enhance info feedback for checkbox & radio;
curform.find(":checkbox[datatype],:radio[datatype]").each(function(){
//已经绑定事件时跳过;
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
var _this=$(this);
var name=_this.attr("name");
curform.find("[name='"+name+"']").filter(":checkbox,:radio").bind("click",function(){
//避免多个事件绑定时的取值滞后问题;
settimeout(function(){
_this.trigger("blur");
},0);
});
});
//select multiple;
curform.find("select[datatype][multiple]").bind("click",function(){
var _this=$(this);
settimeout(function(){
_this.trigger("blur");
},0);
});
//plugins here to start;
validform.util.useplugin.call(curform,useplugin,tiptype,tipsweep,addrule);
},
useplugin:function(plugin,tiptype,tipsweep,addrule){
/*
plugin:settings.useplugin;
tiptype:settings.tiptype;
tipsweep:settings.tipsweep;
addrule:是否在addrule时触发;
*/
var curform=this,
plugin=plugin || {};
//swfupload;
if(curform.find("input[plugin='swfupload']").length && typeof(swfuploadhandler) != "undefined"){
var custom={
custom_settings:{
form:curform,
showmsg:function(msg,type,obj){
validform.util.showmsg.call(curform,msg,tiptype,{obj:curform.find("input[plugin='swfupload']"),type:type,sweep:tipsweep});
}
}
};
custom=$.extend(true,{},plugin.swfupload,custom);
curform.find("input[plugin='swfupload']").each(function(n){
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
$(this).val("");
swfuploadhandler.init(custom,n);
});
}
//datepicker;
if(curform.find("input[plugin='datepicker']").length && $.fn.datepicker){
plugin.datepicker=plugin.datepicker || {};
if(plugin.datepicker.format){
date.format=plugin.datepicker.format;
delete plugin.datepicker.format;
}
if(plugin.datepicker.firstdayofweek){
date.firstdayofweek=plugin.datepicker.firstdayofweek;
delete plugin.datepicker.firstdayofweek;
}
curform.find("input[plugin='datepicker']").each(function(n){
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
plugin.datepicker.callback && $(this).bind("dateselected",function(){
var d=new date( $.event._dpcache[this._dpid].getselected()[0] ).asstring(date.format);
plugin.datepicker.callback(d,this);
});
$(this).datepicker(plugin.datepicker);
});
}
//passwordstrength;
if(curform.find("input[plugin*='passwordstrength']").length && $.fn.passwordstrength){
plugin.passwordstrength=plugin.passwordstrength || {};
plugin.passwordstrength.showmsg=function(obj,msg,type){
validform.util.showmsg.call(curform,msg,tiptype,{obj:obj,type:type,sweep:tipsweep});
};
curform.find("input[plugin='passwordstrength']").each(function(n){
if(this.validform_inited=="inited"){return true;}
this.validform_inited="inited";
$(this).passwordstrength(plugin.passwordstrength);
});
}
//jqtransform;
if(addrule!="addrule" && plugin.jqtransform && $.fn.jqtransselect){
if(curform[0].jqtransselected=="true"){return;};
curform[0].jqtransselected="true";
var jqtransformhideselect = function(otarget){
var ulvisible = $('.jqtransformselectwrapper ul:visible');
ulvisible.each(function(){
var oselect = $(this).parents(".jqtransformselectwrapper:first").find("select").get(0);
//do not hide if click on the label object associated to the select
if( !(otarget && oselect.olabel && oselect.olabel.get(0) == otarget.get(0)) ){$(this).hide();}
});
};
/* check for an external click */
var jqtransformcheckexternalclick = function(event) {
if ($(event.target).parents('.jqtransformselectwrapper').length === 0) { jqtransformhideselect($(event.target)); }
};
var jqtransformadddocumentlistener = function (){
$(document).mousedown(jqtransformcheckexternalclick);
};
if(plugin.jqtransform.selector){
curform.find(plugin.jqtransform.selector).filter('input:submit, input:reset, input[type="button"]').jqtransinputbutton();
curform.find(plugin.jqtransform.selector).filter('input:text, input:password').jqtransinputtext();
curform.find(plugin.jqtransform.selector).filter('input:checkbox').jqtranscheckbox();
curform.find(plugin.jqtransform.selector).filter('input:radio').jqtransradio();
curform.find(plugin.jqtransform.selector).filter('textarea').jqtranstextarea();
if(curform.find(plugin.jqtransform.selector).filter("select").length > 0 ){
curform.find(plugin.jqtransform.selector).filter("select").jqtransselect();
jqtransformadddocumentlistener();
}
}else{
curform.jqtransform();
}
curform.find(".jqtransformselectwrapper").find("li a").click(function(){
$(this).parents(".jqtransformselectwrapper").find("select").trigger("blur");
});
}
},
getnullmsg:function(curform){
var obj=this;
var reg=/[\u4e00-\u9fa5\uf900-\ufa2da-za-z\s]+/g;
var nullmsg;
var label=curform[0].settings.label || ".validform_label";
label=obj.siblings(label).eq(0).text() || obj.siblings().find(label).eq(0).text() || obj.parent().siblings(label).eq(0).text() || obj.parent().siblings().find(label).eq(0).text();
label=label.replace(/\s(?![a-za-z])/g,"").match(reg);
label=label? label.join("") : [""];
reg=/\{(.+)\|(.+)\}/;
nullmsg=curform.data("tipmsg").s || tipmsg.s;
if(label != ""){
nullmsg=nullmsg.replace(/\{0\|(.+)\}/,label);
if(obj.attr("recheck")){
nullmsg=nullmsg.replace(/\{(.+)\}/,"");
obj.attr("nullmsg",nullmsg);
return nullmsg;
}
}else{
nullmsg=obj.is(":checkbox,:radio,select") ? nullmsg.replace(/\{0\|(.+)\}/,"") : nullmsg.replace(/\{0\|(.+)\}/,"$1");
}
nullmsg=obj.is(":checkbox,:radio,select") ? nullmsg.replace(reg,"$2") : nullmsg.replace(reg,"$1");
obj.attr("nullmsg",nullmsg);
return nullmsg;
},
geterrormsg:function(curform,datatype,recheck){
var regxp=/^(.+?)((\d+)-(\d+))?$/,
regxp2=/^(.+?)(\d+)-(\d+)$/,
regxp3=/(.*?)\d+(.+?)\d+(.*)/,
mac=datatype.match(regxp),
temp,str;
//如果是值不一样而报错;
if(recheck=="recheck"){
str=curform.data("tipmsg").reck || tipmsg.reck;
return str;
}
var tipmsg_w_ex=$.extend({},tipmsg.w,curform.data("tipmsg").w);
//如果原来就有,直接显示该项的提示信息;
if(mac[0] in tipmsg_w_ex){
return curform.data("tipmsg").w[mac[0]] || tipmsg.w[mac[0]];
}
//没有的话在提示对象里查找相似;
for(var name in tipmsg_w_ex){
if(name.indexof(mac[1])!=-1 && regxp2.test(name)){
str=(curform.data("tipmsg").w[name] || tipmsg.w[name]).replace(regxp3,"$1"+mac[3]+"$2"+mac[4]+"$3");
curform.data("tipmsg").w[mac[0]]=str;
return str;
}
}
return curform.data("tipmsg").def || tipmsg.def;
},
_regcheck:function(datatype,gets,obj,curform){
var curform=curform,
info=null,
passed=false,
reg=/\/.+\//g,
regex=/^(.+?)(\d+)-(\d+)$/,
type=3;//default set to wrong type, 2,3,4;
//datatype有三种情况:正则,函数和直接绑定的正则;
//直接是正则;
if(reg.test(datatype)){
var regstr=datatype.match(reg)[0].slice(1,-1);
var param=datatype.replace(reg,"");
var rexp=regexp(regstr,param);
passed=rexp.test(gets);
//function;
}else if(validform.util.tostring.call(validform.util.datatype[datatype])=="[object function]"){
passed=validform.util.datatype[datatype](gets,obj,curform,validform.util.datatype);
if(passed === true || passed===undef){
passed = true;
}else{
info= passed;
passed=false;
}
//自定义正则;
}else{
//自动扩展datatype;
if(!(datatype in validform.util.datatype)){
var mac=datatype.match(regex),
temp;
if(!mac){
passed=false;
info=curform.data("tipmsg").undef||tipmsg.undef;
}else{
for(var name in validform.util.datatype){
temp=name.match(regex);
if(!temp){continue;}
if(mac[1]===temp[1]){
var str=validform.util.datatype[name].tostring(),
param=str.match(/\/[mgi]*/g)[1].replace("\/",""),
regxp=new regexp("\\{"+temp[2]+","+temp[3]+"\\}","g");
str=str.replace(/\/[mgi]*/g,"\/").replace(regxp,"{"+mac[2]+","+mac[3]+"}").replace(/^\//,"").replace(/\/$/,"");
validform.util.datatype[datatype]=new regexp(str,param);
break;
}
}
}
}
if(validform.util.tostring.call(validform.util.datatype[datatype])=="[object regexp]"){
passed=validform.util.datatype[datatype].test(gets);
}
}
if(passed){
type=2;
info=obj.attr("sucmsg") || curform.data("tipmsg").r||tipmsg.r;
//规则验证通过后,还需要对绑定recheck的对象进行值比较;
if(obj.attr("recheck")){
var theother=curform.find("input[name='"+obj.attr("recheck")+"']:first");
if(gets!=theother.val()){
passed=false;
type=3;
info=obj.attr("errormsg") || validform.util.geterrormsg.call(obj,curform,datatype,"recheck");
}
}
}else{
info=info || obj.attr("errormsg") || validform.util.geterrormsg.call(obj,curform,datatype);
//验证不通过且为空时;
if(validform.util.isempty.call(obj,gets)){
info=obj.attr("nullmsg") || validform.util.getnullmsg.call(obj,curform);
}
}
return{
passed:passed,
type:type,
info:info
};
},
regcheck:function(datatype,gets,obj){
/*
datatype:datatype;
gets:inputvalue;
obj:input object;
*/
var curform=this,
info=null,
passed=false,
type=3;//default set to wrong type, 2,3,4;
//ignore;
if(obj.attr("ignore")==="ignore" && validform.util.isempty.call(obj,gets)){
if(obj.data("cked")){
info="";
}
return {
passed:true,
type:4,
info:info
};
}
obj.data("cked","cked");//do nothing if is the first time validation triggered;
var dtype=validform.util.parsedatatype(datatype);
var res;
for(var eithor=0; eithor[["/regexp/"],["phone"],["tel","s","e"],["f","e"]];
*/
var reg=/\/.+?\/[mgi]*(?=(,|$|\||\s))|[\w\*-]+/g,
dtype=datatype.match(reg),
sepor=datatype.replace(reg,"").replace(/\s*/g,"").split(""),
arr=[],
m=0;
arr[0]=[];
arr[0].push(dtype[0]);
for(var n=0;n正在检测 | 2=>通过, sweep:true | false},
triggered:在blur或提交表单触发的验证中,有些情况不需要显示提示文字,如自定义弹出提示框的显示方式,不需要每次blur时就马上弹出提示;
tiptype:1\2\3时都有坑能会弹出自定义提示框
tiptype:1时在triggered bycheck时不弹框
tiptype:2\3时在ajax时弹框
tipsweep为true时在triggered bycheck时不触发showmsg,但ajax出错的情况下要提示
*/
//如果msg为undefined,那么就没必要执行后面的操作,ignore有可能会出现这情况;
if(msg==undef){return;}
//tipsweep为true,且当前不是处于错误状态时,blur事件不触发信息显示;
if(triggered=="bycheck" && o.sweep && (o.obj && !o.obj.is(".validform_error") || typeof type == "function")){return;}
$.extend(o,{curform:this});
if(typeof type == "function"){
type(msg,o,validform.util.cssctl);
return;
}
if(type==1 || triggered=="byajax" && type!=4){
msgobj.find(".validform_info").html(msg);
}
//tiptypt=1时,blur触发showmsg,验证是否通过都不弹框,提交表单触发的话,只要验证出错,就弹框;
if(type==1 && triggered!="bycheck" && o.type!=2 || triggered=="byajax" && type!=4){
msghidden=false;
msgobj.find(".iframe").css("height",msgobj.outerheight());
msgobj.show();
setcenter(msgobj,100);
}
if(type==2 && o.obj){
o.obj.parent().next().find(".validform_checktip").html(msg);
validform.util.cssctl(o.obj.parent().next().find(".validform_checktip"),o.type);
}
if((type==3 || type==4) && o.obj){
o.obj.siblings(".validform_checktip").html(msg);
validform.util.cssctl(o.obj.siblings(".validform_checktip"),o.type);
}
},
cssctl:function(obj,status){
switch(status){
case 1:
obj.removeclass("validform_right validform_wrong").addclass("validform_checktip validform_loading");//checking;
break;
case 2:
obj.removeclass("validform_wrong validform_loading").addclass("validform_checktip validform_right");//passed;
break;
case 4:
obj.removeclass("validform_right validform_wrong validform_loading").addclass("validform_checktip");//for ignore;
break;
default:
obj.removeclass("validform_right validform_loading").addclass("validform_checktip validform_wrong");//wrong;
}
},
check:function(curform,subpost,bool){
/*
检测单个表单元素;
验证通过返回true,否则返回false、实时验证返回值为ajax;
bool,传入true则只检测不显示提示信息;
*/
var settings=curform[0].settings;
var subpost=subpost || "";
var inputval=validform.util.getvalue.call(curform,$(this));
//隐藏或绑定dataignore的表单对象不做验证;
if(settings.ignorehidden && $(this).is(":hidden") || $(this).data("dataignore")==="dataignore"){
return true;
}
//dragonfly=true时,没有绑定ignore,值为空不做验证,但验证不通过;
if(settings.dragonfly && !$(this).data("cked") && validform.util.isempty.call($(this),inputval) && $(this).attr("ignore")!="ignore"){
return false;
}
var flag=validform.util.regcheck.call(curform,$(this).attr("datatype"),inputval,$(this));
//值没变化不做检测,这时要考虑recheck情况;
//不是在提交表单时触发的ajax验证;
if(inputval==this.validform_lastval && !$(this).attr("recheck") && subpost==""){
return flag.passed ? true : false;
}
this.validform_lastval=inputval;//存储当前值;
var _this;
errorobj=_this=$(this);
if(!flag.passed){
//取消正在进行的ajax验证;
validform.util.abort.call(_this[0]);
if(!bool){
//传入"bycheck",指示当前是check方法里调用的,当tiptype=1时,blur事件不让触发错误信息显示;
validform.util.showmsg.call(curform,flag.info,settings.tiptype,{obj:$(this),type:flag.type,sweep:settings.tipsweep},"bycheck");
!settings.tipsweep && _this.addclass("validform_error");
}
return false;
}
//验证通过的话,如果绑定有ajaxurl,要执行ajax检测;
//当ignore="ignore"时,为空值可以通过验证,这时不需要ajax检测;
var ajaxurl=$(this).attr("ajaxurl");
if(ajaxurl && !validform.util.isempty.call($(this),inputval) && !bool){
var inputobj=$(this);
//当提交表单时,表单中的某项已经在执行ajax检测,这时需要让该项ajax结束后继续提交表单;
if(subpost=="postform"){
inputobj[0].validform_subpost="postform";
}else{
inputobj[0].validform_subpost="";
}
if(inputobj[0].validform_valid==="posting" && inputval==inputobj[0].validform_ckvalue){return "ajax";}
inputobj[0].validform_valid="posting";
inputobj[0].validform_ckvalue=inputval;
validform.util.showmsg.call(curform,curform.data("tipmsg").c||tipmsg.c,settings.tiptype,{obj:inputobj,type:1,sweep:settings.tipsweep},"bycheck");
validform.util.abort.call(_this[0]);
var ajaxsetup=$.extend(true,{},settings.ajaxurl || {});
var localconfig={
type: "post",
cache:false,
url: ajaxurl,
data: "param="+encodeuricomponent(inputval)+"&name="+encodeuricomponent($(this).attr("name")),
success: function(data){
if($.trim(data.status)==="y"){
inputobj[0].validform_valid="true";
data.info && inputobj.attr("sucmsg",data.info);
validform.util.showmsg.call(curform,inputobj.attr("sucmsg") || curform.data("tipmsg").r||tipmsg.r,settings.tiptype,{obj:inputobj,type:2,sweep:settings.tipsweep},"bycheck");
_this.removeclass("validform_error");
errorobj=null;
if(inputobj[0].validform_subpost=="postform"){
curform.trigger("submit");
}
}else{
inputobj[0].validform_valid=data.info;
validform.util.showmsg.call(curform,data.info,settings.tiptype,{obj:inputobj,type:3,sweep:settings.tipsweep});
_this.addclass("validform_error");
}
_this[0].validform_ajax=null;
},
error: function(data){
if(data.status=="200"){
if(data.responsetext=="y"){
ajaxsetup.success({"status":"y"});
}else{
ajaxsetup.success({"status":"n","info":data.responsetext});
}
return false;
}
//正在检测时,要检测的数据发生改变,这时要终止当前的ajax。不是这种情况引起的ajax错误,那么显示相关错误信息;
if(data.statustext!=="abort"){
var msg="status: "+data.status+"; statustext: "+data.statustext;
validform.util.showmsg.call(curform,msg,settings.tiptype,{obj:inputobj,type:3,sweep:settings.tipsweep});
_this.addclass("validform_error");
}
inputobj[0].validform_valid=data.statustext;
_this[0].validform_ajax=null;
//localconfig.error返回true表示还需要执行temp_err;
return true;
}
}
if(ajaxsetup.success){
var temp_suc=ajaxsetup.success;
ajaxsetup.success=function(data){
localconfig.success(data);
temp_suc(data,inputobj);
}
}
if(ajaxsetup.error){
var temp_err=ajaxsetup.error;
ajaxsetup.error=function(data){
//localconfig.error返回false表示不需要执行temp_err;
localconfig.error(data) && temp_err(data,inputobj);
}
}
ajaxsetup=$.extend({},localconfig,ajaxsetup,{datatype:"json"});
_this[0].validform_ajax=$.ajax(ajaxsetup);
return "ajax";
}else if(ajaxurl && validform.util.isempty.call($(this),inputval)){
validform.util.abort.call(_this[0]);
_this[0].validform_valid="true";
}
if(!bool){
validform.util.showmsg.call(curform,flag.info,settings.tiptype,{obj:$(this),type:flag.type,sweep:settings.tipsweep},"bycheck");
_this.removeclass("validform_error");
}
errorobj=null;
return true;
},
submitform:function(settings,flg,url,ajaxpost,sync){
/*
flg===true时跳过验证直接提交;
ajaxpost==="ajaxpost"指示当前表单以ajax方式提交;
*/
var curform=this;
//表单正在提交时点击提交按钮不做反应;
if(curform[0].validform_status==="posting"){return false;}
//要求只能提交一次时;
if(settings.postonce && curform[0].validform_status==="posted"){return false;}
var beforecheck=settings.beforecheck && settings.beforecheck(curform);
if(beforecheck===false){return false;}
var flag=true,
inflag;
curform.find("[datatype]").each(function(){
//跳过验证;
if(flg){
return false;
}
//隐藏或绑定dataignore的表单对象不做验证;
if(settings.ignorehidden && $(this).is(":hidden") || $(this).data("dataignore")==="dataignore"){
return true;
}
var inputval=validform.util.getvalue.call(curform,$(this)),
_this;
errorobj=_this=$(this);
inflag=validform.util.regcheck.call(curform,$(this).attr("datatype"),inputval,$(this));
if(!inflag.passed){
validform.util.showmsg.call(curform,inflag.info,settings.tiptype,{obj:$(this),type:inflag.type,sweep:settings.tipsweep});
_this.addclass("validform_error");
if(!settings.showallerror){
_this.focus();
flag=false;
return false;
}
flag && (flag=false);
return true;
}
//当ignore="ignore"时,为空值可以通过验证,这时不需要ajax检测;
if($(this).attr("ajaxurl") && !validform.util.isempty.call($(this),inputval)){
if(this.validform_valid!=="true"){
var thisobj=$(this);
validform.util.showmsg.call(curform,curform.data("tipmsg").v||tipmsg.v,settings.tiptype,{obj:thisobj,type:3,sweep:settings.tipsweep});
_this.addclass("validform_error");
thisobj.trigger("blur",["postform"]);//continue the form post;
if(!settings.showallerror){
flag=false;
return false;
}
flag && (flag=false);
return true;
}
}else if($(this).attr("ajaxurl") && validform.util.isempty.call($(this),inputval)){
validform.util.abort.call(this);
this.validform_valid="true";
}
validform.util.showmsg.call(curform,inflag.info,settings.tiptype,{obj:$(this),type:inflag.type,sweep:settings.tipsweep});
_this.removeclass("validform_error");
errorobj=null;
});
if(settings.showallerror){
curform.find(".validform_error:first").focus();
}
if(flag){
var beforesubmit=settings.beforesubmit && settings.beforesubmit(curform);
if(beforesubmit===false){return false;}
curform[0].validform_status="posting";
if(settings.ajaxpost || ajaxpost==="ajaxpost"){
//获取配置参数;
var ajaxsetup=$.extend(true,{},settings.ajaxpost || {});
//有可能需要动态的改变提交地址,所以把action所指定的url层级设为最低;
ajaxsetup.url=url || ajaxsetup.url || settings.url || curform.attr("action");
//byajax:ajax时,tiptye为1、2或3需要弹出提示框;
validform.util.showmsg.call(curform,curform.data("tipmsg").p||tipmsg.p,settings.tiptype,{obj:curform,type:1,sweep:settings.tipsweep},"byajax");
//方法里的优先级要高;
//有undefined情况;
if(sync){
ajaxsetup.async=false;
}else if(sync===false){
ajaxsetup.async=true;
}
if(ajaxsetup.success){
var temp_suc=ajaxsetup.success;
ajaxsetup.success=function(data){
settings.callback && settings.callback(data);
curform[0].validform_ajax=null;
if($.trim(data.status)==="y"){
curform[0].validform_status="posted";
}else{
curform[0].validform_status="normal";
}
temp_suc(data,curform);
}
}
if(ajaxsetup.error){
var temp_err=ajaxsetup.error;
ajaxsetup.error=function(data){
settings.callback && settings.callback(data);
curform[0].validform_status="normal";
curform[0].validform_ajax=null;
temp_err(data,curform);
}
}
var localconfig={
type: "post",
async:true,
data: curform.serializearray(),
success: function(data){
if($.trim(data.status)==="y"){
//成功提交;
curform[0].validform_status="posted";
validform.util.showmsg.call(curform,data.info,settings.tiptype,{obj:curform,type:2,sweep:settings.tipsweep},"byajax");
}else{
//提交出错;
curform[0].validform_status="normal";
validform.util.showmsg.call(curform,data.info,settings.tiptype,{obj:curform,type:3,sweep:settings.tipsweep},"byajax");
}
settings.callback && settings.callback(data);
curform[0].validform_ajax=null;
},
error: function(data){
var msg="status: "+data.status+"; statustext: "+data.statustext;
validform.util.showmsg.call(curform,msg,settings.tiptype,{obj:curform,type:3,sweep:settings.tipsweep},"byajax");
settings.callback && settings.callback(data);
curform[0].validform_status="normal";
curform[0].validform_ajax=null;
}
}
ajaxsetup=$.extend({},localconfig,ajaxsetup,{datatype:"json"});
curform[0].validform_ajax=$.ajax(ajaxsetup);
}else{
if(!settings.postonce){
curform[0].validform_status="normal";
}
var url=url || settings.url;
if(url){
curform.attr("action",url);
}
return settings.callback && settings.callback(curform);
}
}
return false;
},
resetform:function(){
var brothers=this;
brothers.each(function(){
this.reset && this.reset();
this.validform_status="normal";
});
brothers.find(".validform_right").text("");
brothers.find(".passwordstrength").children().removeclass("bgstrength");
brothers.find(".validform_checktip").removeclass("validform_wrong validform_right validform_loading");
brothers.find(".validform_error").removeclass("validform_error");
brothers.find("[datatype]").removedata("cked").removedata("dataignore").each(function(){
this.validform_lastval=null;
});
brothers.eq(0).find("input:first").focus();
},
abort:function(){
if(this.validform_ajax){
this.validform_ajax.abort();
}
}
}
$.datatype=validform.util.datatype;
validform.prototype={
datatype:validform.util.datatype,
eq:function(n){
var obj=this;
if(n>=obj.forms.length){
return null;
}
if(!(n in obj.objects)){
obj.objects[n]=new validform($(obj.forms[n]).get(),{},true);
}
return obj.objects[n];
},
resetstatus:function(){
var obj=this;
$(obj.forms).each(function(){
this.validform_status="normal";
});
return this;
},
setstatus:function(status){
var obj=this;
$(obj.forms).each(function(){
this.validform_status=status || "posting";
});
return this;
},
getstatus:function(){
var obj=this;
var status=$(obj.forms)[0].validform_status;
return status;
},
ignore:function(selector){
var obj=this;
var selector=selector || "[datatype]"
$(obj.forms).find(selector).each(function(){
$(this).data("dataignore","dataignore").removeclass("validform_error");
});
return this;
},
unignore:function(selector){
var obj=this;
var selector=selector || "[datatype]"
$(obj.forms).find(selector).each(function(){
$(this).removedata("dataignore");
});
return this;
},
addrule:function(rule){
/*
rule => [{
ele:"#id",
datatype:"*",
errormsg:"出错提示文字!",
nullmsg:"为空时的提示文字!",
tip:"默认显示的提示文字",
altercss:"gray",
ignore:"ignore",
ajaxurl:"valid.php",
recheck:"password",
plugin:"passwordstrength"
},{},{},...]
*/
var obj=this;
var rule=rule || [];
for(var index=0; index0?top:0);
obj.css({
left:left
}).animate({
top : top
},{ duration:time , queue:false });
}
function creatmsgbox(){
if($("#validform_msg").length!==0){return false;}
msgobj=$('').appendto("body");//提示信息框;
msgobj.find("a.validform_close").click(function(){
msgobj.hide();
msghidden=true;
if(errorobj){
errorobj.focus().addclass("validform_error");
}
return false;
}).focus(function(){this.blur();});
$(window).bind("scroll resize",function(){
!msghidden && setcenter(msgobj,400);
});
};
//公用方法显示&关闭信息提示框;
$.showmsg=function(msg){
creatmsgbox();
validform.util.showmsg.call(win,msg,1,{});
};
$.hidemsg=function(){
msgobj.hide();
msghidden=true;
};
})(jquery,window);