【问题标题】:client side validation with dynamically added field具有动态添加字段的客户端验证
【发布时间】:2011-08-23 08:31:45
【问题描述】:

我在 ASP.NET MVC 中使用 jQuery 的不显眼的验证插件。在服务器上呈现的任何字段都经过正确验证。

但是,如果我使用 JavaScript 在表单中动态添加一个字段,即使它具有适当的 HTML5 data-* 属性,也不会对其进行验证。

谁能指导我如何实现这一目标?

【问题讨论】:

    标签: jquery asp.net-mvc asp.net-mvc-3 unobtrusive-validation


    【解决方案1】:

    更简单的答案:

    我正在使用 MVC 4 和 JQuery 1.8。我已经把它变成了一个模块化函数,它接受新添加元素的jQuery对象:

    function fnValidateDynamicContent($element) {
        var $currForm = $element.closest("form");
        $currForm.removeData("validator");
        $currForm.removeData("unobtrusiveValidation");
        $.validator.unobtrusive.parse($currForm);
        $currForm.validate(); // This line is important and added for client side validation to trigger, without this it didn't fire client side errors.
    }
    

    例如,如果您添加了一个 ID 为 tblContacts 的新表,那么您可以这样调用:

    fnValidateDynamicContent($("#tblContacts"))
    

    【讨论】:

    • 很棒的发现!在我有限的测试中,这似乎有效。注意最后一行代码中的“currform”应该是currForm(大写F)。
    • 我假设您的意思是 fnValidateDynamicContent($("#tblContacts")) ?
    【解决方案2】:

    这里有一个blog post,您可能会觉得很有用,这应该会让您走上正轨。从那里采取的扩展方法:

    /// <reference path="jquery-1.4.4.js" />
    /// <reference path="jquery.validate.js" />
    /// <reference path="jquery.validate.unobtrusive.js" />
    
    (function ($) {
      $.validator.unobtrusive.parseDynamicContent = function (selector) {
        //use the normal unobstrusive.parse method
        $.validator.unobtrusive.parse(selector);
    
        //get the relevant form
        var form = $(selector).first().closest('form');
    
        //get the collections of unobstrusive validators, and jquery validators
        //and compare the two
        var unobtrusiveValidation = form.data('unobtrusiveValidation');
        var validator = form.validate();
    
        $.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
          if (validator.settings.rules[elname] == undefined) {
            var args = {};
            $.extend(args, elrules);
            args.messages = unobtrusiveValidation.options.messages[elname];
            $('[name="' + elname + '"]').rules("add", args);
          } else {
            $.each(elrules, function (rulename, data) {
              if (validator.settings.rules[elname][rulename] == undefined) {
                var args = {};
                args[rulename] = data;
                args.messages = unobtrusiveValidation.options.messages[elname][rulename];
                $('[name="' + elname + '"]').rules("add", args);
              }
            });
          }
        });
      }
    })($);
    

    然后:

    var html = "<input data-val='true' "+
               "data-val-required='This field is required' " +
               "name='inputFieldName' id='inputFieldId' type='text'/>;
    $("form").append(html);
    
    $.validator.unobtrusive.parseDynamicContent('form input:last');
    

    更新添加了博文cmets中引用的修复,否则会出现js错误。

    【讨论】:

    • 当我稍微调试它时,它设法跳过条件的 if 和 else 部分
    • 进一步调试显示 var unobtrusiveValidation = form.data('unobtrusiveValidation');是错误的来源,没有获得新添加字段的规则。
    • 工作就像一个魅力。谢谢!
    【解决方案3】:

    为了让达林的回答起作用,我更改了以下行:

    $.validator.unobtrusive.parse(selector); 
    

    到这里:

     $(selector).find('*[data-val = true]').each(function(){
        $.validator.unobtrusive.parseElement(this,false);
     });
    

    这是完整的示例:

    (function ($) {
      $.validator.unobtrusive.parseDynamicContent = function (selector) {
        // don't use the normal unobstrusive.parse method
        // $.validator.unobtrusive.parse(selector); 
    
         // use this instead:
         $(selector).find('*[data-val = true]').each(function(){
            $.validator.unobtrusive.parseElement(this,false);
         });
        
        //get the relevant form
        var form = $(selector).first().closest('form');
    
        //get the collections of unobstrusive validators, and jquery validators
        //and compare the two
        var unobtrusiveValidation = form.data('unobtrusiveValidation');
        var validator = form.validate();
    
        $.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
          if (validator.settings.rules[elname] == undefined) {
            var args = {};
            $.extend(args, elrules);
            args.messages = unobtrusiveValidation.options.messages[elname];
            $('[name="' + elname + '"]').rules("add", args);
          } else {
            $.each(elrules, function (rulename, data) {
              if (validator.settings.rules[elname][rulename] == undefined) {
                var args = {};
                args[rulename] = data;
                args.messages = unobtrusiveValidation.options.messages[elname][rulename];
                $('[name="' + elname + '"]').rules("add", args);
              }
            });
          }
        });
      }
    })($);
    

    $.validator.unobtrusive.parse 内部调用 parseElement 方法,但每次将 isSkip 参数发送为 true,因此使用此值

    if (!skipAttach) {
        valInfo.attachValidation();
    }
    

    jquery.unobtrusive.js 中的这段代码没有将验证附加到元素,我们只找到最初出现在页面上的输入的验证数据。

    注意 Darin 上面的回答是正确的,你可以在他提到的博客上找到很多人已经使用 xhalent 的代码解决了问题(由 darin 发布)。为什么它不起作用超出了我的理解。此外,你可以找到很多posts 告诉你,只是打电话

    $.validator.unobtrusive.parse(selector) 
    

    足以验证动态加载的内容

    【讨论】:

    • 对于其他使用它的人,我建议您再更改一件事,特别是如果您在 MVC 中的动态集合上使用它:$('[name=' + escapeAttributeValue(elname) + ']') 其中 escapeAttributeValue 确实使名称 jquery 选择器安全: return value.replace(/([!"#\$%&'()*\+,\.\/:;\?@[ \\]\^`\{\|\}~])/g, '\\$1');
    • $.validator.unobtrusive.parse(selector) 仅适用于新添加的表单。如果您已经有一个现有的表单并向该表单插入新的输入字段,它将不起作用。
    猜你喜欢
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 2014-12-19
    相关资源
    最近更新 更多