多次验证器使用不显眼的方式调用动态添加的内容

时间:2012-03-27 08:04:45

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

这是一个经典问题,当您通过javascript向FORM添加内容时,尽管您调用了此内容,但不会验证此内容     $ .validator.unobtrusive.parse( “形式”);

好的,这是一个很好的解决方案:只需在解析之前清理信息:

$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");`

这很好,而且看起来很有效。但! 调用此块时,每个验证器都会被调用多次:

$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

您可以通过创建自定义验证器并在其中设置断点或任何调试输出来轻松检查此案例:

jQuery.validator.addMethod("checksalary",
   function (value, element, param) {
   return (!isNaN(value) && parseInt(value) > 0) || $("#" + param).attr('checked');
});

jQuery.validator.unobtrusive.adapters.add
("checksalary", ["param"], function (options) {
  options.rules["checksalary"] = options.params.param;
  options.messages["checksalary"] = options.message;
});

如果你的验证人几次打电话而不是一次,那看起来真是非专业。

在调用parse()之前是否应该清除其他信息?

让我们假设您已经调用了100次parse()。我认为客户可以清楚地看到这种开销。

更新 好吧,我可以调试大量的脚本,并发现,即使我们清理表单的验证信息,我们仍然没有清除这个绑定,由jquery.validate.js中的第53行引起

    this.submit(function (event) {
        if (validator.settings.debug)
        // prevent form submit to be able to see console output
            event.preventDefault();
...

所以我为这个案例创建了暂时的丑陋修复,现在可以使用,但我相信应该有更好的方法,比如更新验证对象,而不是创建新的:

    var validator = $.data(this[0], 'validator');
    var skipReAttach = false;
    if (validator) {
        //return validator;
        skipReAttach = true;
    }

    validator = new $.validator(options, this[0]);
    $.data(this[0], 'validator', validator);

    if (validator.settings.onsubmit) {

        // allow suppresing validation by adding a cancel class to the submit button
        this.find("input, button").filter(".cancel").click(function () {
            validator.cancelSubmit = true;
        });

        // when a submitHandler is used, capture the submitting button
        if (validator.settings.submitHandler) {
            this.find("input, button").filter(":submit").click(function () {
                validator.submitButton = this;
            });
        }

        // validate the form on submit
        if (skipReAttach)
            return validator;

        this.submit(function (event) {
            if (validator.settings.debug)
            // prevent form submit to be able to see console output
                event.preventDefault();

当然 - 现在只有     $.validator.unobtrusive.parse("form"); 应该被称为。

但解决此问题的好方法是什么?

1 个答案:

答案 0 :(得分:1)

我使用this solution的大量帮助找到了一个不那么优雅的解决方案。到目前为止对我来说效果很好,但尚未经过全面测试。

而不是使用:

$("form").removeData("validator"); 
$("form").removeData("unobtrusiveValidation"); 
$.validator.unobtrusive.parse("form");

使用以下代码:

function resetValidationAttributes(parentContainer) {
    $(parentContainer).find(':input[data-val = true]').each(function() {
        //
        $.validator.unobtrusive.parseElement(this, true);

        var form = $(this).first().closest('form');

        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);
                    }
                });
            }
        });
    });
}

将动态内容加载到容器中,然后搜索该容器中的任何输入。对于每个输入,它调用parseElement,并在函数调用中指定true(查看不显眼的验证文件以获取更多信息)。最后,它遍历表单上的验证器,如果不在那里,则将字段添加到规则中。