如果在Ajax表单中使用,jQuery不显眼的验证会忽略提交按钮上的"取消"类

Geo*_*dze 6 jquery jquery-validate unobtrusive-validation asp.net-mvc-4 unobtrusive-ajax

我正在尝试使用可选的客户端验证

  • ASP.NET MVC 4,
  • 不引人注目的jQuery验证,
  • 不引人注目的ajax

这很好用

下面的图片显示了我对可选的客户端验证的意思:我的表单上唯一一个字段应该包含电子邮件,因此附加了一个电子邮件验证器.

在此输入图像描述

现在我们点击保存.由于我们的文本"name @ doamin"不是有效的电子邮件,因此会显示验证摘要.与验证摘要一起,我们取消隐藏"无论如何"保存按钮.

在此输入图像描述

第二个按钮是一个正常的提交按钮class="cancel".这指示jQuery.validate.js脚本在使用此按钮提交时跳过验证.

以下是视图的代码段:

@using (Html.BeginForm())
{
    <div>
        <input data-val="true" data-val-email="Uups!" name="emailfield" />
        <span class="field-validation-valid" data-valmsg-for="emailfield" data-valmsg-replace="false">*</span>
    </div>

    <input type="submit" value="Save" />
    @Html.ValidationSummary(false, "Still errors:")
    <div class="validation-summary-valid" data-valmsg-summary="true">
        <input type="submit" value="Save anyway" class="cancel" />
    </div>
}
Run Code Online (Sandbox Code Playgroud)

一切正常.

问题

如果我切换到Ajax表单,第二个提交按钮 - "仍然保存"按预期停止工作.它的行为与正常行为相同,并且在验证成功之前阻止提交.

以下是"ajaxified"视图的代码段:

@using (Ajax.BeginForm("Edit", new { id = "0" },
        new AjaxOptions
            {
                HttpMethod = "POST",
                InsertionMode = InsertionMode.Replace,
                UpdateTargetId = "ajaxSection",
            }))
{
    <div>
        <input data-val="true" data-val-email="Uups!" name="emailfield" />
        <span class="field-validation-valid" data-valmsg-for="emailfield" data-valmsg-replace="false">*</span>
    </div>

    <input type="submit" value="Save" />
    @Html.ValidationSummary(false, "Still errors:")
    <div class="validation-summary-valid" data-valmsg-summary="true">
        <input type="submit" value="Save anyway" class="cancel" name="saveAnyway" />
    </div>
}
Run Code Online (Sandbox Code Playgroud)

我已调试jQuery.validation.js找出有什么区别,但失败了.

Qustion

任何修复或解决问题并让ajax表单按预期运行的想法都是受欢迎的.


附录

要进行客户端验证是绝对必要的.服务器端验证不是一个选项.除了更高的流量(此示例是简化 - 真实表单包含更多字段)和延迟之外,服务器端验证还有一件事情不会做:客户端验证器突出显示丢失焦点上的错误字段.这意味着只要您切换到下一个字段,您就会收到反馈.

Dar*_*rov 11

这是微软不显眼的ajax脚本的一个已知限制.你可以修改它来修复bug.因此在jquery.unobtrusive-ajax.js脚本内部替换第144行的以下内容:

$(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);
Run Code Online (Sandbox Code Playgroud)

有:

$(form).data(data_click, name ? [{ name: name, value: evt.target.value, className: evt.target.className }] : []);
Run Code Online (Sandbox Code Playgroud)

此外,我们将类名传递给处理程序,以便它可以决定是否应该触发客户端验证.目前,无论点击哪个按钮,它始终会触发验证.现在在第154行,我们修改了以下测试:

if (!validate(this)) {
Run Code Online (Sandbox Code Playgroud)

有:

if (clickInfo[0].className != 'cancel' && !validate(this)) {
Run Code Online (Sandbox Code Playgroud)

因此,如果使用带有类名取消的提交按钮来提交表单,则不再触发客户端验证.另一种可能性是刮掉jquery.unobtrusive-ajax.js脚本并Ajax.BeginForm用一个标准替换你Html.BeginForm,你可以使用普通的旧jQuery不引人注意地使用AJAXify.

  • 这解决了我的问题,有两个修改.首先检查className是否包含cancel而不是仅取消以支持按钮上的多个类名.其次是在处理之前检查clickInfo长度,以避免特殊情况下的脚本错误,如@ achitaka-san报道的那样.这将第154行更改为"if(clickInfo.length> 0 && clickInfo [0] .className.indexOf('cancel')<0 &&!validate(this)){".谢谢,是的,MS真的应该解决这个问题. (2认同)

Sim*_*ver 6

最后,我找到了一个解决方案,它本身并不引人注目

    // restore behavior of .cancel from jquery validate to allow submit button 
    // to automatically bypass all jquery validation
    $(document).on('click', 'input[type=image].cancel,input[type=submit].cancel', function (evt)
    {
        // find parent form, cancel validation and submit it
        // cancelSubmit just prevents jQuery validation from kicking in
        $(this).closest('form').validate().cancelSubmit = true;
        $(this).closest('form').submit();
        return false;
    });
Run Code Online (Sandbox Code Playgroud)

注意:如果首先尝试它似乎不起作用 - 请确保您没有往返服务器并刷新页面时出错.您必须通过其他方式绕过服务器端的验证 - 这只是允许提交表单而不必为.ignore表单中的所有内容添加属性.

(button如果使用按钮,可能需要添加到选择器)