首页 > 其他分享 >MouseValidate表单验证库扩展与优化

MouseValidate表单验证库扩展与优化

时间:2022-10-12 09:59:05浏览次数:48  
标签:node function false 验证 校验 表单 规则 MouseValidate mouseValidate

前言

写这篇文档主要是为了渣土系统这样的KO(即Knockout)老项目,这里边使用的非常多。mouseValidate这个库确实没怎么听过,以至于我想找一下官方文档都搜不到,只能由我自己简单的定义一下了。mouseValidate是一个基于jquery的表单验证库,目前公司项目中除了KO老项目中普遍使用,其它系统基本没有用到,不过这并不妨碍我们学习它的设计思想,以及根据我们自己的需求对它进行定制修改。

基本使用

  • 第一步引进来,例如:
  define(["jquery", "durandal/app", "durandal/composition", "knockout", "mouseValidate"],
      function ($, app, composition, ko, mouseValidate) {
          function viewModal() {
      }
 			return viewModal;
		});

  • 第二步初始化验证

    实际上就是定义一些规则,非空啊,手机号码啊,身份证号码之类的。这里只摘录核心代码片段,具体实例可以到渣土系统中找,例子非常多。另外,注意这个initValidate方法一般页面加载完毕就先调用一遍,这样被添加规则的表单字段就能做出响应了。

//添加规则 
model.initValidate = function () {
    mouseValidate.clearValidate();
    mouseValidate.initValidate($(_dom).find("#businessLicenseNumber"), {"isEmpty": "请输入工商营业执照编号"});
    mouseValidate.initValidate($(_dom).find("#registerMoney"), {"isEmpty": "请输入注册资金","isNumber":"请输入正确数值"});
    mouseValidate.initValidate($(_dom).find("#legalRepresentative"), {"isEmpty": "请输入企业法人"});
    mouseValidate.initValidate($(_dom).find("#legalRepresentativeContact"), {"isEmpty": "请输入企业法人联系方式","isAllPhone":""});
    mouseValidate.initValidate($(_dom).find("#legalRepresentativeNumber"), {"isEmpty": "请输入企业法人身份证号码"});
};

//提交表单时校验
model.submit = function(){
//注意returnFlag并不是boolean类型,而是"true"或"false"
var returnFlag = MouseValidate.returnValidate();
if (returnFlag === "false") {
commonUtil.showTip(_dom, "error", "完成提示与必填项!", "company-tip");
return false;
}
};

  • 效果展示

    调用MouseValidate.returnValidate(),校验的是整个表单。校验不通过的表单项显示红色边框。

    img

    单击某个表单项让它获得焦点,然后再失去焦点,会单独对这个表单项进行校验。校验不通过,会显示相应提示信息。

img

缺陷

  1. 不支持自定义校验规则,比如:校验车牌号。

  2. disabled或readonly的表单项,不能触发校验,这是因为这两种情况下,没办法走如下流程:获取焦点——手动输入或选择——失去焦点的操作方式,所以不能触发校验。为了便于大家理解,这里截取一个这样的场景。下面3个字段,都是通过点击按钮,在弹框界面选择某项,然后带回来赋值给右边的input框。因为是选择方式,不支持手动输入,故这几个input框全部都是readonly状态。

    img

    下面选取具体的值后,发现Input框仍然是红色边框image-20220320191338606

优化与扩展

  • 本次优化与扩展的目的

    针对上面2个缺陷,本次改造mouseValidate库希望达到2个目的。

    1. 支持自定义校验规则,这一点非常重要。

    2. readonly、disabled 字段值发生变化后,触发校验规则。

  • mouseValidate库源码概览

    其实结构非常简单,原来的代码主要由如下几部分构成:2个容器、初始化规则收集函数、表单提交校验函数、清除规则函数、一堆内置校验规则,本次扩展新增了一个customKeys和customFlag,以及增加了一个供外部注册规则的 registerValidate 方法,它们专门用于处理自定义校验规则。这些内容里比较重要的就是initValidate和returnValidate。

image-20220320192006482

  • initValidate

    image-20220320193718886

initValidate方法中,我并不打算详细解读focus、blur等方法,有兴趣的自己去研读。我主要讲一下自己加的一段处理readonly和disabled的逻辑。因为readonly(或disabled)表单项可以通过选择方式或其它非手动输入方式得到值,所以这里只能监听一下它的change事件,其实说穿了很简单,就是当它的值发生变化时,简单校验一下,如果为空就给它来个红色边框,反之就正常边框。

//readonly和disabled的元素增加一个change事件,同时还需在代码中还需要手动触发一下change事件,
// 这是因为readonly和disabled会导致默认的change失效,$(_dom).find("#fenceNames").trigger("change");
if ($(node).attr("readonly") === "readonly" || $(node).attr("disabled") === "disabled") {
   $(node).change(function (evt) {
      var value = $(node).val();
      if (value || value === 0) {
         $(node).css("border", "1px solid #B7C7CD");
      } else {
         $(node).css("border", "1px solid red");
      }
   });
}

但是,这里有一个非常重要的细节,readonly或disabled后,change事件需要手动显示触发**$(_dom).find("xxx").trigger("change")**。这个地方我一直没有想到更好的办法,只能在当前表单项拿到值后,手动触发一下了。就像下面这样:

function initEvents() {
    app.off('app:construction:choose:fences');
    app.on('app:construction:choose:fences').then(function (data) {
        self._selectedFences = data;
        if (self._selectedFences && self._selectedFences.length) {
            var fenceNames = commonUtil.getMappingFields(self._selectedFences, "fenceName", ",");
            self.fenceNames(fenceNames);
        //触发一下change事件配合mouseValidate库
        $(_dom).find("#fenceNames").trigger("change");
    }
});

}

  • returnValidate

    returnValidate方法用于提交表单时,统一校验所有添加了规则的表单项。使用方法类似于:

    //提交表单时校验
    model.submit = function(){
      //注意returnFlag并不是boolean类型,而是"true"或"false"
       var returnFlag = MouseValidate.returnValidate();
       if (returnFlag === "false") {
           commonUtil.showTip(_dom, "error", "完成提示与必填项!", "company-tip");
           return false;
        }
    };
    

    那么它里边具体是怎么做的呢?

    1. 校验isEmpty规则,将所以不通过的表单节点,放入到flag容器中;
    2. 校验自定义规则,将所有不通过的表单节点,放入到flag容器中(这个是我新加的逻辑);
    3. 统一处理flag容器中的节点,依次添加红色边框,以表示哪些没有通过校验。

    image-20220320200007749

下面主要讲一下我自己添加的逻辑。这里要结合前面的inValidate方法来看。故这里重新再贴一遍截图。我们首先要搞清楚customFlag里到底存储的是什么。customFlag.set(node, key) 中的node很好理解,key实际上就是 isVehicleNum、isTaskNum 这样的规则函数!所以customFlag里实际上是类似这样的结构:[ {node: isVehicleNum}, {node: isTaskNum} ] 这样的键值对。

image-20220320201100060

了解了上面这些,然后如果对eval变态函数有些了解,下面这段逻辑就基本能看明白了。eval的神奇在这里表现得淋漓尽致了,能够将字符串拼接成的函数调用执行起来,并且拿到调用后的结果!当然前提是你这个method首先必须得存在,所以下面接着必须讲一下 registerValidate方法的作用了。

//处理自定义的校验
customFlag.forEach(function (method, node) {
   var value = $(node).val();
   var res = eval(method+"('"+value+"')");
   if (res.success) {
      if (flag.get(node) === "false") {
         flag.set(node, "true");
      }
   } else {
      flag.set(node, "false");
   }
});
  • registerValidate

    这个方法比较简单,这里就不多说了,主要目的就是向customKeys数组中添加元素(自定义规则函数名称)。同时,添加进去的规则,务必要有对应的校验函数。后面会举一个添加车牌号校验规则的实例,这个例子也是实际开发中遇到的需求,比较有代表性。

    image-20220320202515832

使用自定义校验

  1. 注册自定义规则,并给表单项添加该规则

    model.initValidate = function () {
        //注册自定义规则isVehicleNum
        mouseValidate.registerValidate("isVehicleNum");
        mouseValidate.clearValidate();
        //给表单项添加规则,这里包含2个规则,isEmpty、isVehicleNum,多个规则是可以一起使用的
        mouseValidate.initValidate($(model._constrain).find("#vehicleNum"), {"isEmpty": "请输入车牌号", "isVehicleNum": "请输入正确的车牌号码"});
    }
    
  2. 在mouseValidate文件中定义规则函数

    注意规则校验函数的返回值结构,务必保持一致!

    /*
     * 车牌号验证(这里只简单校验一下前缀和长度)
     * @param {string}
     */
    function isVehicleNum(val) {
       //校验前缀
       var prefix = eUrban.global.LICENSE_PLATE_NUMBER || "";
       if (prefix && val.indexOf(prefix) !== 0) {
          return {success: false, message: '车牌号前缀不正确!'};
       }
       //校验长度,车牌号码长度目前是7、8位数
       if (val.length < 7 || val.length > 8) {
          return {success: false, message: '车牌号长度不正确!'};
       }
       return {success: true};
    }
    
  3. 校验效果

    img

后续

增加文本长度校验规则

核心代码片段

/**
	 * 校验文本长度
	 * @param val
	 * @returns {{success: boolean, message: string}|{success: boolean}}
	 */
	function checkLen(val) {
		if (!window._checkNode) {
			return {success: true};
		}
		var min = $(window._checkNode).attr("minlen");
		var max = $(window._checkNode).attr("maxLen");
		min = min && !isNaN(min) ? Number(min) : 0;
		max = max && !isNaN(max) ? Number(max) : 0;
		var len = val.length;
		if (len < min) {
			return {success: false, message: '文本长度不得小于' + min};
		}
		if (len > max) {
			return {success: false, message: '文本长度不得大于' + max};
		}
		return {success: true};
	}

//returnValidate、blur等代码中增加window._checkNode赋值。
customFlag.forEach(function (method, node) {
window._checkNode = node; //增加它,用于在校验函数中获取边界
var value = $(node).val();
var res = eval(method+"('"+value+"')");
if (res.success) {
if (flag.get(node) === "false") {
flag.set(node, "true");
}
} else {
flag.set(node, "false");
}
});

使用方法

image-20220331185015321

image-20220331185109074

image-20220331185130070

image-20220331185144487

标签:node,function,false,验证,校验,表单,规则,MouseValidate,mouseValidate
From: https://www.cnblogs.com/yuanchaowhut/p/mousevalidate-biao-dan-yan-zheng-ku-kuo-zhan-yu-yo.

相关文章

  • Java 手动显示调用validate的实体属性验证
    importorg.springframework.util.CollectionUtils;importjavax.validation.ConstraintViolation;importjavax.validation.Valid;importjavax.validation.Validati......
  • rsync用法教程(已验证)
    一、简介rsync是一个常用的Linux应用程序,用于文件同步。它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也......
  • iview框架form表单内的select标签存在的校验问题
    近期做项目发现,iview框架的select框,选中值之后,没能通过表单的必填校验...仔细看了下,目前我们项目是请求的数据list的id作为key值来进行渲染,这个id是个number类型的0.0OK,......
  • 38. JS表单验证(附带示例)
    1.前言表单是Web应用(网站)的重要组成部分,通过表单可以收集用户提交的信息,例如姓名、邮箱、电话等。由于用户在填写这些信息时,有可能出现一些错误,例如输入手机号时漏掉了......
  • uniapp禁止表单重复提交
    1.在根目录下新建common文件并创建common.js文件,代码直接复制粘贴即可。//防止处理多次点击functionnoMultipleClicks(methods,info){//methods是需要点击后......
  • 直播平台怎么搭建,SpringMVC-登录验证判断
    直播平台怎么搭建,SpringMVC-登录验证判断1.拦截器 packagecom.kuang.config;importorg.springframework.web.servlet.HandlerInterceptor;importjavax.servlet.http......
  • kubernetes(k8s)常用deploy模板 并验证
    kubernetes常用deploy模板,并验证编写deploy配置文件root@hello:~#catdeploy.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:hostname-test-cbylabels......
  • 解决Google无法验证此账号归你所有
    本来正常使用的谷歌,突然有一天登录的时候,被提示“Google无法验证此账号归你所有”,当看到这个提示,不要着急,现在就教大家怎么解决这个问题,1、首先,我们先切换科学上网地址,再......
  • 验证Verificationvs确认Validation
    说法1:“验证”和“确认”都是认定。可是,“验证”表明的是满足规定要求,而“确认”表明的是满足预期用途或应用要求,说简单点,“确认”就是检查最终产品是否达到顾客使用要求......
  • 来看界面控件DevExtreme如何实现数据表单的高效动态更新
    DevExtreme拥有高性能的HTML5/JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NETCore,jQuery,Knockout等)构建交互式的Web应用程序,该套件附带功能......