jQuery的不显眼的验证忽略了“取消”上提交按钮类,如果在阿贾克斯的形式使用(jQuery uno

2019-06-26 09:53发布

我想用来实现可选的客户端验证

  • ASP.NET MVC 4,
  • 不显眼的jQuery验证,
  • 不显眼的AJAX

这工作正常

下面的图片说明我的意思与可选的客户端验证:我的表格上只有一个字段,预计包含电子邮件,所以连接到它的电子邮件验证。

现在我们点击保存。 因为我们的文字“姓名@ 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>
}

这些都工作正常。

问题

第二个提交按钮- “保存反正”停止,如果我切换到Ajax的形式,预期工作。 它只是行为就像正常的一个,并防止提交,直到验证成功。

这里是“Ajax化”观点的代码片段:

@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>
}

我已经调试jQuery.validation.js找出有什么不同,但失败了。

Qustion

任何想法修复或解决该问题,并让阿贾克斯形式表现为预期的欢迎。


附录

为了有一个客户端验证是绝对必要的。 服务器端验证是不是一种选择。 除了较高的流量(此示例是一种简化 - 真正的形式包含更多的字段)和延迟,有一件事情是服务器端验证不会做:客户端验证突出显示失去焦点错误的领域。 这意味着你只要有一个反馈您标签到下一个区域。

Answer 1:

这是微软的AJAX不显眼脚本的一个已知的限制。 你可以修改它来修复该错误。 所以里面jquery.unobtrusive-ajax.js脚本替换线144以下几点:

$(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);

有:

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

另外我们传递的类名的处理程序,以便它可以决定它是否应该触发客户端验证或没有。 目前,它总是触发验证无论哪个按钮被点击。 而现在上线154我们修改了以下测试:

if (!validate(this)) {

有:

if (clickInfo[0].className != 'cancel' && !validate(this)) {

因此,如果使用类名称提交按钮取消用来提交表单,这个客户端验证不再触发。 另一种可能性是刮jquery.unobtrusive-ajax.js脚本并更换Ajax.BeginForm与标准Html.BeginForm ,你可以悄悄地AJAXify使用老式的jQuery。



Answer 2:

最后,我想出了一个解决方案,它本身就是不显眼

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

注意:如果在第一次尝试看来,这是行不通的 - 确保你没有双向传递到服务器,并有错误刷新页面。 你必须通过其他方式绕过了服务器端验证-这只是允许,而不必浪费时间加入到提交表单.ignore属性在表单中的一切。

(您可能需要添加button来选择,如果你正在使用的按钮)



Answer 3:

如果不需要验证不显眼,禁用它,做你在服务器端的所有检查。

你可以检查值提交服务器端的按钮,并基于该着手:

添加name属性,您的两个输入提交:

<input type="submit" value="Save" name="btnSubmit" />
<input type="submit" value="Save anyway" class="cancel" name="btnSubmit" />

更新您的行为采取string btnSubmit 。 您可以把它放在你的模型,如果你有一个。

[HttpPost]
public ActionResult Edit(string emailfield, string btnSubmit)
{
    switch (btnSubmit)
    {
        case "Save":
            if(ModelState.IsValid)
            {
                // Save email
            }
            break;
        case "Save anyway":
            // Save email
            return RedirectToAction("Success");
            break;
    }
    // ModelState is not valid
    // whatever logic to re display the view
    return View(model);
}

UPDATE

据我所知,客户端验证,简化了工作,但如果你不能弄清楚什么是错的Ajax(我不熟悉它的行为,当类=“中止”耳光输入),你可以写一个脚本,将验证上未集中在服务器侧的输入:

$('input[type=text]').blur(function(){
    $.ajax({
        url: '/ControllerName/ValidateInput',
        data: { inputName: $(this).val() },
        success: function(data) {
            //if there is a validation error, display it
        },
        error: function(){
            alert('Error');
        }
    });
});

现在,你需要创建一个动作,会做一个输入的验证:

public ActionResult ValidateInput(string inputName)
{
    bool isValid = true;
    string errorMessage = "";
    switch (inputName)
    {
        case "password"
            // do password validation
            if(!inputIsValid)
            {
                isValid = false;
                errorMessage = "password is invalid";
            }
            break;
        case "email"
            // do email validation
            if(!inputIsValid)
            {
                isValid = false;
                errorMessage = "email is invalid";
            }
            break;
    }
    return Json(new { inputIsValid = isValid, message = errorMessage });
}

这是一个有点麻烦,但正如我所说,如果你不弄清楚客户端验证可以工作。


UPDATE

不知道为什么我没有想到这首...而不是依赖于class="cancel" ,你可以这样做:

给你“反正”提交输入编号:

<input type="submit" value="Save anyway" class="cancel" name="btnSubmit" id="submitAyway" />

然后有这样的脚本:

$('#submitAyway').click(function(evt) {
    evt.preventDefault();
    $('form').submit();
});

我没有测试过这一点,但在理论上,这应该提交表单而不验证它。 你可能仍然需要服务器端验证正如我在我的第一个例子说明。



文章来源: jQuery unobtrusive validation ignores “cancel” class on submit button if used in Ajax form