欢迎来到小懒的博客~email:568705236@qq.com

layui 2.5.6 form改造,暴露js调用表单验证

2020/9/21 18:45:19站长

    layui form表单验证可以通过点击按钮触发,那可不可以通过js代码来触发表单验证?

    官方回答是目前layui表单只是在监听提交的时候来验证。这样的话,我们想JS来触发的话,就需要修改源代码。从github上下载源码,打开src/lay/modules/form.js。找到验证的代码部分。image.png

    layui作者的注释说明很清晰。初步阅读一下验证代码。涉及到审查的元素是通过触发按钮获取的,所以提取代码需要进行稍微修改。

    我们先把这段验证代码提取一下。

//原本的submit方法
//表单提交校验    
var submit = function(){    
var stop = null //验证不通过状态    
,verify = form.config.verify //验证规则    
,DANGER = 'layui-form-danger' //警示样式    
,field = {}  //字段集合    
,button = $(this) //当前触发的按钮    
,elem = button.parents(ELEM) //当前所在表单域    
,verifyElem = elem.find('*[lay-verify]') //获取需要校验的元素    
,formElem = button.parents('form')[0] //获取当前所在的 form 元素,如果存在的话    
,filter = button.attr('lay-filter'); //获取过滤器    
//开始校验    
layui.each(verifyElem, function(_, item){    
var othis = $(this)    
,vers = othis.attr('lay-verify').split('|')    
,verType = othis.attr('lay-verType') //提示方式    
,value = othis.val();    
othis.removeClass(DANGER); //移除警示样式    
//遍历元素绑定的验证规则    
layui.each(vers, function(_, thisVer){    
var isTrue //是否命中校验    
,errorText = '' //错误提示文本    
,isFn = typeof verify[thisVer] === 'function';    
//匹配验证规则    
if(verify[thisVer]){    
var isTrue = isFn ? errorText = verify[thisVer](value, item) : !verify[thisVer][0].test(value);    
errorText = errorText || verify[thisVer][1];    
if(thisVer === 'required'){    
errorText = othis.attr('lay-reqText') || errorText;    
}    
//如果是必填项或者非空命中校验,则阻止提交,弹出提示    
if(isTrue){    
//提示层风格    
if(verType === 'tips'){    
layer.tips(errorText, function(){    
if(typeof othis.attr('lay-ignore') !== 'string'){    
if(item.tagName.toLowerCase() === 'select' || /^checkbox|radio$/.test(item.type)){    
return othis.next();    
}    
}    
return othis;    
}(), {tips: 1});    
} else if(verType === 'alert') {    
layer.alert(errorText, {title: '提示', shadeClose: true});    
} else {    
layer.msg(errorText, {icon: 5, shift: 6});    
}    
//非移动设备自动定位焦点    
if(!device.android && !device.ios){    
setTimeout(function(){    
item.focus();     
}, 7);    
}    
othis.addClass(DANGER);    
return stop = true;    
}    
}    
});    
if(stop) return stop;    
});    
if(stop) return false;    
//获取当前表单值    
field = form.getValue(null, elem);    
//返回字段    
return layui.event.call(this, MOD_NAME, 'submit('+ filter +')', {    
elem: this    
,form: formElem    
,field: field    
});    
};

    提取验证部分。

//表单提交校验
  var submit = function(){
    var stop = null //验证不通过状态
    ,verify = form.config.verify //验证规则
    ,DANGER = 'layui-form-danger' //警示样式
    ,field = {}  //字段集合
    ,button = $(this) //当前触发的按钮
    ,elem = button.parents(ELEM) //当前所在表单域
    ,verifyElem = elem.find('*[lay-verify]') //获取需要校验的元素
    ,formElem = button.parents('form')[0] //获取当前所在的 form 元素,如果存在的话
    ,filter = button.attr('lay-filter'); //获取过滤器
   
    
    stop = validate(verifyElem);
    
    if(stop) return false;
    
    //获取当前表单值
    field = form.getValue(null, elem);
 
    //返回字段
    return layui.event.call(this, MOD_NAME, 'submit('+ filter +')', {
      elem: this
      ,form: formElem
      ,field: field
    });
  };

  /**
   * 
   * @param {*} verifyElem 需要验证的元素
   */
  var validate=function(verifyElem){
    var stop = null //验证不通过状态
    ,verify = form.config.verify //验证规则
    ,DANGER = 'layui-form-danger' //警示样式    
    ; //获取需要校验的元素
    //开始校验
    layui.each(verifyElem, function(_, item){
      var othis = $(this)
      ,vers = othis.attr('lay-verify').split('|')
      ,verType = othis.attr('lay-verType') //提示方式
      ,value = othis.val();
      
      othis.removeClass(DANGER); //移除警示样式
      
      //遍历元素绑定的验证规则
      layui.each(vers, function(_, thisVer){
        var isTrue //是否命中校验
        ,errorText = '' //错误提示文本
        ,isFn = typeof verify[thisVer] === 'function';
        
        //匹配验证规则
        if(verify[thisVer]){
          var isTrue = isFn ? errorText = verify[thisVer](value, item) : !verify[thisVer][0].test(value);
          errorText = errorText || verify[thisVer][1];
          
          if(thisVer === 'required'){
            errorText = othis.attr('lay-reqText') || errorText;
          }
          
          //如果是必填项或者非空命中校验,则阻止提交,弹出提示
          if(isTrue){
            //提示层风格
            if(verType === 'tips'){
              layer.tips(errorText, function(){
                if(typeof othis.attr('lay-ignore') !== 'string'){
                  if(item.tagName.toLowerCase() === 'select' || /^checkbox|radio$/.test(item.type)){
                    return othis.next();
                  }
                }
                return othis;
              }(), {tips: 1});
            } else if(verType === 'alert') {
              layer.alert(errorText, {title: '提示', shadeClose: true});
            } else {
              layer.msg(errorText, {icon: 5, shift: 6});
            }
            
            //非移动设备自动定位焦点
            if(!device.android && !device.ios){
              setTimeout(function(){
                item.focus(); 
              }, 7);
            }
            
            othis.addClass(DANGER);
            return stop = true;
          }
        }
      });
      if(stop) return stop;
    });
    return stop;
  }

    在暴露对象前,绑定方法给对象,当然暴露的方法需要新建一个,用于获取需要验证的元素,传入真正验证的方法。这里注意,返回true是表示有验证错误

/**
 * 触发验证,返回true/false,true是存在不符合
 * @param {*} formFilter 表单筛选
 */
  var beforeValidate = function(formFilter){
    //如果有传值则找到需要验证的表单,否则全部验证
    var elemForm = $(ELEM + function(){
      return filter ? ('[lay-filter="' + formFilter +'"]') : '';
    }()),
    verifyElem = elemForm.find('*[lay-verify]');
    return validate(verifyElem);
  }

    在暴露的对象创建后,绑定方法。

//绑定验证方法
  form.validate = beforeValidate;

    然后进行测试,清空缓存,测试原来的功能。

image.png

    再在控制台调用方法,模拟JS触发全局验证。

image.png


image.png

    正常触发,再测试触发单个表单验证。

image.png

    输入框执行聚集失败了。这应该是控制台把焦点抢了。

image.png

    执行代码后马上将焦点放回页面。2秒后。

image.png

    显示正常了。至此,改造form.js完成。


赞赏