jQuery 的验证摘要不显示不显眼的验证

Validation Summary for jQuery Unobtrusive Validation does not display

我正在处理以下内容:

我的 Knockout 视图模型模板如下所示:

<tbody data-bind="foreach:recipientEmailAddressList">
    <tr>
        <td class="no-padding" style="width:330px">
            <input class="suppress-ms-clear input-parameter full-width" data-bind="value:EmailAddress, hasfocus:EmailAddress.focused" name="EmailAddresses" data-val="true" data-val-email="Please enter a valid email address.">
        </td>
        <td class="no-padding align-right">
            <div class="delete" data-bind="visible: $root.recipientEmailAddressList().length > 1">
                <a href="" data-bind="click:$root.removeRecipientEmailAddress"><span class="no-wrap">X</span></a>
            </div>
        </td>
    </tr>
</tbody>

我在 MVC 视图中也有以下内容:

@Html.ValidationSummary(false)

当我添加验证失败的电子邮件时,无效元素样式被正确应用到输入元素,但是验证摘要未显示并显示验证错误。同样,即使明显存在验证错误,也允许用户提交页面。

我没有任何绑定到表单提交元素的代码。

似乎不​​显眼的验证通过应用错误样式知道存在问题,但为什么不显示验证摘要?为什么我可以提交表格?如果我更正电子邮件地址使其有效,输入中的错误样式就会消失。

TLDR:"jQuery Validate" 和 "Microsoft jQuery Unobtrusive Validation" 不能很好地协同工作 (Reference)。删除 Microsoft 不显眼的验证脚本并使用 jQuery Validate 对 html 属性验证的本机支持。它 好很多

详细说明:

我自己最近一直在努力解决这个问题,经过数小时的研究,我得出的结论是 "jQuery Validate" 和 "Microsofts Unobtrusive Validation" 不能很好地协同工作 (Reference)。

从这篇文章中我了解到,Microsoft 的不显眼的验证通过覆盖某些选项扼杀了很多 jQuery 验证功能。例如,一旦加载了不显眼的脚本,任何自定义设置都会被忽略。这使得在您的 JavaScript 中指定自定义验证 rules/behavior 变得非常困难(在我的情况下需要)。

对于我的情况,我还使用 KnockoutJS. The first thing I do is serialize my C# model into a JSON model and then load it into KnockoutJS using the ko.mappings utility(可通过 NuGet 获得)。

然后我将数据绑定应用于我的标记,并让 HTML 由 KnockoutJS 生成。为了让验证对我有用,我从 HTML 辅助函数之一复制了生成的标记,例如 TextBoxFor,并将生成的验证规则应用到我的 HTML.

例如:

<data-val-required="This fields is required" .... >

虽然此解决方案部分有效,但正如您所提到的,我无法让脚本正确突出显示无效输入并显示验证摘要。

起初我以为这就是我需要做的所有事情才能让不显眼的验证工作。但是我随后发现,首先,要验证的每个元素都需要一个唯一的名称(duh),其次,不引人注目的验证脚本不适用于动态生成的内容。

为了解决不引人注目的验证脚本不适用于动态生成的内容的问题,我遵循了 this, this and this 文章中的建议。

使用下面的代码我能够重新解析数据:

var form = $(".formSelector")
form.removeData('validator');
form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse(form);

重新解析表单并动态添加任何内容后,我能够让新生成的字段正确验证。我还发现 this 这可能会有帮助,但我从未最终使用它。

然后我遇到了另一个问题:我无法在不覆盖某些 jQuery 验证设置的情况下验证 disabled/read-only 输入(我知道这是非常规的,但我需要它)。正如我之前提到的,如果不修改不引人注目的验证脚本,这是不可能的。 (呸!)

最终我偶然发现了这个网站:jQuery Validate Unobtrusive Native which is also on GitHub。正是在这一点上,我发现:

Since jQuery Validate 1.11.x they started including native support for unobtrusive validation which works with Dynamic content

然后我放弃了 Microsoft 的不引人注目的验证脚本。请务必注意,Microsoft 非侵入式脚本的验证属性与 jQuery Validate Unobtrusive Native 脚本所使用的不同。因此需要 this 项目提供的自定义 HTML 助手。

一旦我删除了 Microsoft 的不显眼的验证脚本并将所有生成的属性替换为 jQuery Validate 使用的正确属性,我的表单就开始正确验证了! :)

使用this我确定了如何转换属性,但我确定还有很多其他references/examples。

另请注意,在删除了 Microsoft 的不显眼的验证脚本后,我需要使用以下代码在表单上手动设置验证:

$(".formSelector").validate({
...options...
});

这里是 example 的 KnockoutJS 与 jQuery 的原生无干扰验证一起使用。

您可能需要编写一些 CSS 来处理元素的突出显示,因为 AFAICT,jQuery 验证使用与 Microsoft 非侵入性脚本不同的错误 类。

现在,关于验证摘要:我仍然没有得到这个工作,但据我所知,您需要覆盖默认实现以显示错误。在下面的代码中,我说明了如何使用自定义工具提示来显示错误消息 (Reference)。我假设一旦在表单上检测到错误,您将不得不执行类似的操作以将错误消息应用到 ValidationSummary。也就是说,运行 遍历错误列表并将它们附加到 @Html.ValidationSummary() 生成的验证摘要元素。

我也在努力实现这个目标,所以一旦我弄清楚如何去做,我就会 post 我的解决方案。

//Note this requires the bootstrap tooltip plugin...

$("form").validate({
    showErrors: function (errorMap, errorList) {

        // Clean up any tooltips for valid elements
        $.each(this.validElements(), function (index, element) {
            var $element = $(element);

            $element.data("title", "") // Clear the title - there is no error associated anymore
                .removeClass("error")
                .tooltip("destroy");
        });

        // Create new tooltips for invalid elements
        $.each(errorList, function (index, error) {
            var $element = $(error.element);

            $element.tooltip("destroy") // Destroy any pre-existing tooltip so we can repopulate with new tooltip content
                .data("title", error.message)
                .addClass("error")
                .tooltip(); // Create a new tooltip based on the error messsage we just set in the title
        });
    },

    rules: { /*.... Rules here ....*/ },

    submitHandler: function (form) {
        alert("This is a valid form!");
    }
});

编辑:对于任何感兴趣的人来说,我提到的 SO article 是为了获得 readonly/disabled 输入进行验证。

希望这最终会对某人有所帮助 - 我希望我在一开始就找到了这个信息。