内容不做任何修改再离开提示错误的bug解决方法

query
formValidator插件非常好用,但是有一个严重的Bug,在使用ajax验证的时候,如果输入框的内容已经存在,把鼠标放到输入框,不做任何修改再离开,则会提示错误,
这是这个插件犯的一个很愚蠢的错误

jQuery formValidator表单验证插件

复制代码 代码如下:

图片 1图片 2

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;

Code
//====================================================================================================
// [插件名称] jQuery formValidator
//—————————————————————————————————-
// [描    述] jQuery formValidator表单验证插件,它是基于jQuery类库,实现了js脚本于页面的分离。对一个表
//            单对象,你只需要写一行代码就可以轻松实现20种以上的脚本控制。现支持一个表单元素累加很多种
//            校验方式,采用配置信息的思想,而不是把信息写在表单元素上,能比较完美的实现ajax请求。
//—————————————————————————————————-

settings[i].isvalid = true;
}
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;
},

var jQuery_formValidator_initConfig;
(function($) {

您可能感兴趣的文章:

  • jquery
    ajax请求方式与提示用户正在处理请稍等
  • php+ajax做仿百度搜索下拉自动提示框(有实例)
  • ajax 自动完成下拉框
    自动提示位置问题
  • asp+ajax仿google搜索提示效果代码
  • jquery+ajax+text文本框实现智能提示完整实例
  • jquery实现ajax加载超时提示的方法
  • 使用jQuery全局事件ajaxStart为特定请求实现提示效果的代码
  • Ajax实现智能提示搜索功能
  • Ajax带提示的验证表单实例
  • ajax实现输入提示效果

$.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<jQuery_formValidator_initConfig.length;i++)
      {
          if(validatorgroup==jQuery_formValidator_initConfig[i].validatorgroup)
    {
     return jQuery_formValidator_initConfig[i];
    }
      }
  }
  return null;
 },

 //触发每个控件上的各种校验
 triggerValidate : function(returnObj)
 {
  switch(returnObj.setting.validatetype)
  {
   case “InputValidator”:
    $.formValidator.inputValid(returnObj);
    break;
   case “CompareValidator”:
    $.formValidator.compareValid(returnObj);
    break;
   case “AjaxValidator”:
    $.formValidator.ajaxValid(returnObj);
    break;
   case “RegexValidator”:
    $.formValidator.regexValid(returnObj);
    break;
   case “FunctionValidator”:
    $.formValidator.functionValid(returnObj);
    break;
  }
 },
 
 //设置显示信息
 setTipState : function(elem,showclass,showmsg)
 {
  var setting0 = elem.settings[0];
  var initConfig = $.formValidator.getInitConfig(setting0.validatorgroup);
     var tip = $(“#”+setting0.tipid);
  if(showmsg==null || showmsg==””)
  {
   tip.hide();
  }
  else
  {
   if(initConfig.tidymode)
   {
    //显示和保存提示信息
    $(“#fv_content”).html(showmsg);
    elem.Tooltip = showmsg;
    if(showclass!=”onError”){tip.hide();}
   }
   tip.removeClass();
   tip.addClass( showclass );
   tip.html( showmsg );
  }
 },
  
 resetTipState : function(validatorgroup)
 {
  var initConfig = $.formValidator.getInitConfig(validatorgroup);
  $(initConfig.validobjectids).each(function(){
   $.formValidator.setTipState(this,”onShow”,this.settings[0].onshow); 
  });
 },
 
 //设置错误的显示信息
 setFailState : function(tipid,showmsg)
 {
     var tip = $(“#”+tipid);
     tip.removeClass();
     tip.addClass(“onError”);
     tip.html(showmsg);
 },

 //根据单个对象,正确:正确提示,错误:错误提示
 showMessage : function(returnObj)
 {
     var id = returnObj.id;
  var elem = $(“#”+id).get(0);
  var isvalid = returnObj.isvalid;
  var setting = returnObj.setting;//正确:setting[0],错误:对应的setting[i]
  var showmsg = “”,showclass = “”;
  var settings = $(“#”+id).get(0).settings;
  var intiConfig = $.formValidator.getInitConfig(settings[0].validatorgroup);
  if (!isvalid)
  {  
   showclass = “onError”;
   if(setting.validatetype==”AjaxValidator”)
   {
    if(setting.lastValid==””)
    {
        showclass = “onLoad”;
        showmsg = setting.onwait;
    }
    else
    {
        showmsg = setting.onerror;
    }
   }
   else
   {
    showmsg = (returnObj.errormsg==””? setting.onerror : returnObj.errormsg);
    
   }
   if(intiConfig.alertmessage)  
   {
    var elem = $(“#”+id).get(0);
    if(elem.validoldvalue!=$(elem).val()){alert(showmsg);}   
   }
   else
   {
    $.formValidator.setTipState(elem,showclass,showmsg);
   }
  }
  else
  {  
   //验证成功后,如果没有设置成功提示信息,则给出默认提示,否则给出自定义提示;允许为空,值为空的提示
   showmsg = $.formValidator.isEmpty(id) ? setting.onempty : setting.oncorrect;
   $.formValidator.setTipState(elem,”onCorrect”,showmsg);
  }
  return showmsg;
 },

 showAjaxMessage : function(returnObj)
 {
  var setting = returnObj.setting;
  var elem = $(“#”+returnObj.id).get(0);
  if(elem.validoldvalue!=$(elem).val())
  {
   $.formValidator.ajaxValid(returnObj);
  }
  else
  {
   if(setting.isvalid!=undefined && !setting.isvalid){
    elem.lastshowclass = “onError”; 
    elem.lastshowmsg = setting.onerror;
   }
   $.formValidator.setTipState(elem,elem.lastshowclass,elem.lastshowmsg);
  }
 },

 //获取指定字符串的长度
    getLength : function(id)
    {
        var srcjo = $(“#”+id);
  var elem = srcjo.get(0);
        sType = elem.type;
        var len = 0;
        switch(sType)
  {
   case “text”:
   case “hidden”:
   case “password”:
   case “textarea”:
   case “file”:
          var val = srcjo.val();
    var initConfig = $.formValidator.getInitConfig(elem.settings[0].validatorgroup);
    if (initConfig.wideword)
    {
     for (var i = 0; i < val.length; i++) 
     {
      if (val.charCodeAt(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;
    $(“<div class=’formValidateTip’></div>”).appendTo($(“body”)).css({left: x+”px”, top: y+”px”}).prepend($(‘<div id=”‘+tip+'”></div>’).css(setting_temp.tipcss));
   }
   if(initConfig.tidymode){jqobj.showTooltips()};
  }
  
  //每个控件都要保存这个配置信息
  setting.tipid = tip;
  $.formValidator.appendValid(this.id,setting);