zoukankan      html  css  js  c++  java
  • validate[.unobtrusive]和Bootstrap实现tooltip错误提示

    validate[.unobtrusive]和Bootstrap实现tooltip错误提示

    类似的文章园子里已有,请看这里,个人感觉稍显复杂,日前也打算写一个简单的给项目用,一些关键点记录于此。最终效果如下:

    后端使用Asp.net mvc5,前端框架有:jquery.validate、jquery.validate.unobtrusive、requirejs、Bootstrap,都是当前最/较新版本。jquery.validate就不用说了,目前比较流行的前端校验组件;jquery.validate.unobtrusive基于jquery.validate,是为了配合Asp.net mvc,微软自己写的,NuGet下可查找Microsoft.jQuery.Unobtrusive.Validation安装,具体怎么用请继续往下看。

    首先在后台我们定义实体类:

     实体定义

    实体各属性上面有Attribute形式的校验规则,当用户提交一个Model到后端Action时,MVC框架会据此自动帮我们完成校验工作,于是后端开发就很开心。然而在数据提交之前,前端也有必要进行第一轮的校验,如果使用jquery.validate,那么需要在js或标签里再写一遍类似的规则,能不能复用后端已有的代码呢?我们以属性EnterpriseNo为例,在cshtml中写:

    @Html.TextBoxFor(m => m.BasicInfo.EnterpriseNo, new { placeholder = "必填项", @class = "form-control" })

    最终生成的html如下:

    <input class="form-control" data-val="true" data-val-maxlength="字段 EnterpriseNo 必须是最大长度为“30”的字符串或数组类型。" data-val-maxlength-max="30" data-val-required="信用代码/注册号不能为空" id="BasicInfo_EnterpriseNo" name="BasicInfo.EnterpriseNo" placeholder="必填项" value="" data-original-title="" title="" type="text">

    标签里面自动加上了很多data-开头的属性,data-val表示该控件需要校验,其它data-开头的就是一系列校验规则和失败时的错误信息,错误信息可以自定义,否则框架会给你生成类如“字段 EnterpriseNo 必须是最大长度为30的字符串或数组类型。”这种机器翻译语言。当然这些属性jquery.validate是不认的,要让jquery.validate认识,就需要jquery.validate.unobtrusive出马了。

    现在我们来说这些js如何配合使用。

    新版本的jquery.validate已经支持AMD模式,所以可以直接使用requirejs加载,jquery.validate.unobtrusive则不行,需要shim配置,代码:

    复制代码
    require.config({
                baseUrl: '/scripts',
                paths: {
                    "jquery": 'jquery-2.2.3.min',
                    "knockout":'knockout-3.4.0',
                    "bootstrap":'../components/bootstrap/3.3.6/js/bootstrap.min','validate':'jquery.validate',
                    'validateunobtrusive':'jquery.validate.unobtrusive.min'
                },
                shim : {
                    'bootstrap' : {
                        deps : [ 'jquery' ],
                        exports : 'bootstrap'
                    },
                    'validateunobtrusive':{
                        deps:['validate'],
                        exports: 'validateunobtrusive'
                    }
                }
            });
    复制代码

    配置好后,在页面中require,此时点击submit按钮提交表单,各js就开始作用了。但是除了焦点会落到第一个校验失败的控件上,似乎并没有其它效果,连jquery.validate默认的在控件后面展示错误信息(errorPlacement函数)都没有了,are you kidding me?其实这是因为jquery.validate.unobtrusive覆盖了errorPlacement配置项(看源码中的attachValidation函数),对我们来说反而省了一道工序。由于tooltip的html标记是由bootstrap动态生成的,所以errorPlacement并不适合我们,参考本文开头的链接,选择覆写showErrors函数,核心代码如下(tooltipvalidator.js):

    复制代码
     1 define(['validateunobtrusive'], function () {
     2 
     3     function TooltipValidator() {}
     4 
     5     TooltipValidator.prototype = {
     6         init: function (validatorOptions, tooltipOptions) {
     7             tooltipOptions = tooltipOptions || {};
     8             validatorOptions = validatorOptions || {};
     9 
    10             this._tooltipOptions = $.extend({}, {
    11                 placement: 'top'
    12             }, tooltipOptions, { animation: false });
    13 
    14             this._validatorOptions = $.extend({}, {
    15 
    16                 //errorPlacement: function (error, element) {
    17                 //    // do nothing
    18                 //},
    19 
    20                 showErrors: function (errorMap, errorList) {
    21                     for (var i = 0; i < this.successList.length; i++) {
    22                         var success = this.successList[i];
    23                         $(this.successList[i]).tooltip('destroy');
    24                         $(this.successList[i]).parents('div.form-group').removeClass('has-error');
    25                     }
    26                     for (var i = 0; i < errorList.length; i++) {
    27                         var errorElement = $(errorList[i].element);
    28                         errorElement.parents('div.form-group').addClass('has-error');
    29                         errorElement.attr('data-original-title', errorList[i].message).tooltip('show');
    30                     }
    31                 },
    32 
    33                 submitHandler: function (form) {
    34                     return false;
    35                 }
    36 
    37             }, validatorOptions)
    38 
    39             this._configTooltip();
    40             this._configValidator();
    41         },
    42 
    43         _configTooltip: function () {
    44             $('[data-val="true"]').tooltip(this._tooltipOptions);
    45         },
    46 
    47         _configValidator: function () {
    48             $.validator.setDefaults(this._validatorOptions);
    49             $.validator.unobtrusive.parse(document);
    50         }
    51     }
    52 
    53     return new TooltipValidator();
    54 });
    复制代码

    这样我们就可以在require回调函数中执行tooltipvalidator.init,不需要另外再写逻辑,于是前端同学也开心的笑了。这里还有一处需要注意,大家看到第49行代码,这是初始化jquery.validate.unobtrusive的步骤。原本jquery.validate.unobtrusive在其代码中已经有$(function () { $jQval.unobtrusive.parse(document); });但是由于$.ready会在Dom元素加载完成后(题外话:不是渲染完成)就执行,因此它会在tooltipvalidator有机会_configValidator之前完成,导致咱们的配置项无效(如果是在单页无刷新应用中,会发现之后再次加载局部页时,配置项有效了,因为$.ready只在初次加载的时候执行,而require回调会每次加载都执行)。有两种解决方法:1、让jquery.validate.unobtrusive依赖tooltipvalidator;2、移除jquery.validate.unobtrusive中的$jQval.unobtrusive.parse(document);这里选择第2种。

  • 相关阅读:
    Encrypted Handshake Message
    RSAParameters Struct
    What if JWT is stolen?
    What's the difference between JWTs and Bearer Token?
    RSA Algorithm Example
    第18届Jolt大奖结果公布
    Ruby on rails开发从头来(windows)(三十六) 调试技巧
    Ruby on rails开发从头来(四十二) ActiveRecord基础(主键和ID)
    YouTube开放基础技术架构 让用户建自家YouTube
    Ruby on rails开发从头来(四十) ActiveRecord基础(Boolean属性)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/6014035.html
Copyright © 2011-2022 走看看