我正在使用ASP.Net MVC3,使用客户端验证的更简单方法是启用jquery.validate.unobtrusive。一切正常,对于服务器中的正确内容。
但是,当我尝试使用javascript注入一些新的“输入”时,我知道需要调用$.validator.unobtrusive.parse()以重新绑定验证。但是,所有这些动态注入字段仍无法正常工作。
更糟糕的是,我尝试使用手动绑定jquery.validate,但也不起作用。有什么想法吗?
我正在使用ASP.Net MVC3,使用客户端验证的更简单方法是启用jquery.validate.unobtrusive。一切正常,对于服务器中的正确内容。
但是,当我尝试使用javascript注入一些新的“输入”时,我知道需要调用$.validator.unobtrusive.parse()以重新绑定验证。但是,所有这些动态注入字段仍无法正常工作。
更糟糕的是,我尝试使用手动绑定jquery.validate,但也不起作用。有什么想法吗?
Answers:
我为jquery.validate.unobtrusive库创建了一个扩展,该扩展针对我的情况解决了该问题-可能很有趣。
http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
$.validator.unobtrusive.parse()。另外,它似乎仅添加新规则,而不选择更新现有规则?
                    我尝试了Xhalent的方法,但不幸的是,它对我没有用。罗宾的方法行得通而且行不通。它对于动态添加的元素非常有用,但是,如果您尝试使用JQuery从DOM中删除所有验证属性和范围,则验证库仍将尝试对其进行验证。
但是,如果除“ validationData”之外还删除了表单的“ unobtrusiveValidation”数据,它就像一种用于动态添加和删除要验证或未验证的元素的超级按钮。
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");validator未定义吗?我同时引用了validation和validation.unobtrusive。验证有效,直到我调用这些代码
                    $('#form').validate({ignore: ""})
                    我实际上真的很喜欢@viggity和@Robins解决方案的简单性,因此我将其变成了一个快速的小插件:
(function ($) {
    $.fn.updateValidation = function () {
        var $this = $(this);
        var form = $this.closest("form")
            .removeData("validator")
            .removeData("unobtrusiveValidation");
        $.validator.unobtrusive.parse(form);
        return $this;
    };
})(jQuery);用法示例:
$("#DischargeOutcomeNumberOfVisits")
    .attr("data-val-range-min", this.checked ? "1" : "2")
    .updateValidation();我有同样的问题。我发现不可能以相同的形式两次调用$ .validator.unobtrusive.parse()。最初从服务器加载表单时,表单将由非侵入式库自动解析。当您将输入元素动态添加到表单中并再次调用$ .validator.unobtrusive.parse()时,它将不起作用。parseElement()也是如此。
不显眼的lib调用jquery validate插件的validate方法来设置所有规则和消息。问题是,再次调用该插件时,它不会更新其给定的新规则集。
我找到了一个简单的解决方案:在不打扰的lib上调用parse方法之前,我丢弃了表单验证器:
$('yourForm').removeData("validator");现在,当不打扰的lib调用validate方法时,将重新创建所有规则和消息,包括动态添加的输入。
希望这可以帮助
我正在使用MVC 4和JQuery 1.8,看起来需要以下代码才能使Jquery验证通过Ajax或Jquery向DOM中动态注入的内容。
我做了一个模块化的函数,可以接受新添加元素的Jquery对象。如果tblContacts单击按钮后使用Jquery 克隆了一个ID为ID的新表,请在js文件中包含以下函数
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.
}并这样称呼它:
fnValidateDynamicContent("#tblContacts")从上面标记为答案的Xhalent解决方案中,我对它进行了扩展。
$.validator.unobtrusive.parseDynamicContent = function (selector) {
    var $selector = $(selector),
        $jqValUnob = $.validator.unobtrusive,
        selectorsDataValAttr = $selector.attr('data-val'),
        $validationInputs = $selector.find(':input[data-val=true]');
    if ((selectorsDataValAttr !== 'true') && 
        ($validationInputs.length === 0)) { 
        return; 
    }
    if (selectorsDataValAttr === 'true') {
        $jqValUnob.parseElement(selector, true);
    }
    $validationInputs.each(function () {
        $jqValUnob.parseElement(this, true);
    });
    //get the relevant form
    var $form = $selector.first().closest('form');
    $jqValUnob.syncValdators($form);
};
/* synchronizes the unobtrusive validation with jquery validator */
$.validator.unobtrusive.syncValdators = function ($form) {
    if ($.hasData($form[0])) {
        var unobtrusiveValidation = $form.data('unobtrusiveValidation'),
            validator = $form.validate();
        // add validation rules from unobtrusive to jquery
        $.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);
                    }
                });
            }
        });
        // remove all validation rules from jquery that arn't in unobtrusive
        $.each(validator.settings.rules, function (elname, elrules) {
            if (unobtrusiveValidation.options.rules[elname] === undefined) {
                delete validator.settings.rules[elname];
            } else {
                $.each(elrules, function (rulename, data) {
                    if (rulename !== "messages" && unobtrusiveValidation.options.rules[elname][rulename] === undefined) {
                        delete validator.settings.rules[elname][rulename];
                    }
                });
            }
        });
    }        
};
$.validator.unobtrusive.unparseContent = function (selector) {
    var $selector = $(selector);
    // if its  a text node, then exit
    if ($selector && $selector.length > 0 && $selector[0].nodeType === 3) {
        return;
    }
    var $form = $selector.first().closest('form'), 
        unobtrusiveValidation = $form.data('unobtrusiveValidation');
    $selector.find(":input[data-val=true]").each(function () {
        removeValidation($(this), unobtrusiveValidation);
    });
    if ($selector.attr('data-val') === 'true') {
        removeValidation($selector, unobtrusiveValidation);
    }
    $.validator.unobtrusive.syncValdators($form);
};
function removeValidation($element, unobtrusiveValidation) {
    var elname = $element.attr('name');
    if (elname !== undefined) {
        $element.rules('remove');
        if (unobtrusiveValidation) {
            if (unobtrusiveValidation.options.rules[elname]) {
                delete unobtrusiveValidation.options.rules[elname];
            }
            if (unobtrusiveValidation.options.messages[elname]) {
                delete unobtrusiveValidation.options.messages[elname];
            }
        }
    }
}因此,基本上它仍然与上述Xhalent的解决方案相同,但是我添加了删除从dom中删除元素的规则的功能。因此,当您从Dom中删除元素并希望删除那些验证规则时,还可以调用:
$.validator.unobtrusive.unparseContent('input.something');我在代码中找到@Xhalent的代码脚本,并打算删除它,因为我没有使用它,这导致我遇到这个SO问题。
这段代码非常干净和简单:
jQuery.fn.unobtrusiveValidationForceBind = function () {
    //If you try to parse a form that is already parsed it won't update
    var $form = this
       .removeData("validator") /* added by the raw jquery.validate plugin */
            .removeData("unobtrusiveValidation");  /* added by the jquery     unobtrusive plugin */
    $form.bindUnobtrusiveValidation();
}然后,要调用此jQuery扩展,只需使用选择器即可获取表单:
$('#formStart').unobtrusiveValidationForceBind();中提琴!
我尝试了无懈可击的回答,但起初一切似乎都可行。但是过了一会儿,我注意到随着添加的内容更加动态,验证变得很痛苦。原因是他的解决方案没有解除绑定事件处理程序,而是每次都添加新的处理程序。因此,如果添加5个项目,则验证将执行6次,而不是仅执行一次。要解决此问题,您必须将事件另外绑定到removeData调用。
$("form").removeData("validator")
         .removeData("unobtrusiveValidation")
         .off("submit.validate click.validate focusin.validate focusout.validate keyup.validate invalid-form.validate");
$.validator.unobtrusive.parse("form");如果是动态内容,则需要如下更新“非侵入式验证”,并Form在提交时检查其是否有效。
function UpdateUnobtrusiveValidations(idForm) {
    $(idForm).removeData("validator").removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse($(idForm));
};
$('#idDivPage').on('click', '#idSave', function (e) {
    e.preventDefault();
    if (!$('#idForm').valid()) {
        // Form is invalid … so return
        return false;
    }
    else {
        // post data to server using ajax call
        // update Unobtrusive Validations again
        UpdateUnobtrusiveValidations('#idForm');
    }
});我已经摆弄了一段时间,放弃了解决方案并稍后再试(当我有空闲时间时,信不信由你)。
自从此线程最后创建或注释以来,我不确定这种行为是否会在较新版本的jquery(我们正在使用1.7.2)中更改,但是我发现.parseElement(inputElement)当我尝试向表单中添加动态创建的元素时,这种方法工作正常已经加载了验证器。@jamesfm(2011年2月15日)已经在上面的评论之一中建议过这一点,但是我在从事此工作的头几次就忽略了它。因此,我将其添加为一个单独的答案以使其更明显,因为我认为这是一个很好的解决方案,并且不需要太多开销。它可能与后续答案中提出的所有问题都不相关,但我认为这将是对原始问题的解决方案。这是我的工作方式:
//row & textarea created dynamically by an async ajax call further up in the code
var row = ...; //row reference from somewhere
var textarea = row.find("textarea");
textarea.val("[someValue]");
//add max length rule to the text area
textarea.rules('add', {
    maxlength: 2000
});
//parse the element to enable the validation on the dynamically added element
$.validator.unobtrusive.parseElement(textarea);如果您需要添加和删除某些东西(可能已经显示了一些错误),这就是我自带的。它主要基于此问题页面上的不同想法。我使用内置方法,destroy()而不仅仅是删除JQuery验证的data属性。
function resetValidator($form: JQuery) {
    $form.validate().destroy();
    //reset unobtrusive validation summary, if it exists
    $form.find("[data-valmsg-summary=true]")
        .removeClass("validation-summary-errors")
        .addClass("validation-summary-valid")
        .find("ul").empty();
    //reset unobtrusive field level, if it exists
    $form.find("[data-valmsg-replace]")
        .removeClass("field-validation-error")
        .addClass("field-validation-valid")
        .empty();
    $form.removeData("unobtrusiveValidation");
}在动态修改表单中的输入之前,请先调用它。然后,您可以在之后重新初始化验证。
resetValidator($form);
//add or remove inputs here ...
$.validator.unobtrusive.parse($form);注意:如果某些或所有输入已通过验证并且有错误,这些错误将被重置...但是它们将在下一次验证时正确返回。