如果在Ajax表单中使用,jQuery不显眼validation会忽略提交按钮上的“取消”类
我正在尝试使用实现可选的客户端validation
- ASP.NET MVC 4,
- 不引人注目的jQueryvalidation,
- 不引人注目的ajax
这很好用
下面的图片显示了我对可选的客户端validation的意思:我的表单上唯一一个字段应该包含电子邮件,因此附加了一个电子邮件validation器。
现在我们点击保存。 由于我们的文本“name @ doamin”不是有效的电子邮件,因此会显示validation摘要。 与validation摘要一起,我们取消隐藏“无论如何”保存按钮。
第二个按钮是一个普通的提交按钮,只有class="cancel"
。 这指示jQuery.validate.js
脚本在使用此按钮提交时跳过validation。
以下是视图的代码段:
@using (Html.BeginForm()) { * @Html.ValidationSummary(false, "Still errors:") }
一切正常。
问题
如果我切换到Ajax表单,第二个提交按钮 – “仍然保存”按预期停止工作。 它的行为与正常行为相同,并且在validation成功之前阻止提交。
以下是“ajaxified”视图的代码段:
@using (Ajax.BeginForm("Edit", new { id = "0" }, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "ajaxSection", })) { * @Html.ValidationSummary(false, "Still errors:") }
我调试了jQuery.validation.js
以找出有什么不同,但失败了。
Qustion
任何修复或解决问题并让ajax表单按预期运行的想法都是受欢迎的。
附录
要进行客户端validation是绝对必要的。 服务器端validation不是一个选项。 除了更高的流量(此示例是简化 – 真实表单包含更多字段)和延迟之外,服务器端validation还有一件事情不会做:客户端validation器突出显示丢失焦点上的错误字段。 这意味着只要您切换到下一个字段,您就会收到反馈。
这是微软不显眼的ajax脚本的一个已知限制。 你可以修改它来修复bug。 所以在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 }] : []);
此外,我们将类名传递给处理程序,以便它可以决定是否应该触发客户端validation。 目前,无论点击哪个按钮,它始终会触发validation。 现在在第154行,我们修改了以下测试:
if (!validate(this)) {
有:
if (clickInfo[0].className != 'cancel' && !validate(this)) {
这样,如果使用带有类名取消的提交按钮来提交表单,则不再触发客户端validation。 另一种可能性是刮掉jquery.unobtrusive-ajax.js
脚本并用标准的Html.BeginForm
替换你的Ajax.BeginForm
,你可以使用普通的旧jQuery不引人注意地使用AJAXify。
最后,我找到了一个解决方案,它本身并不引人注目
// 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; });
注意:如果首先尝试它似乎不起作用 – 请确保您没有往返服务器并刷新页面时出错。 您将不得不通过其他方式绕过服务器端的validation – 这只是允许提交表单而不必将.ignore
属性添加到表单中的所有内容。
(如果使用按钮,可能需要向选择器添加按钮)
如果不需要Unobtrusivevalidation,请将其禁用并在服务器端执行所有检查。
您可以检查服务器端的“提交”按钮的值,然后根据该值继续:
为两个提交输入添加name
属性:
更新您的操作以获取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
我知道客户端validation简化了工作,但是如果你无法弄清楚Ajax有什么问题(我不熟悉它在输入时打字=“取消”时的行为),你可以写一个会validation的脚本服务器端未聚焦的输入:
$('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'); } }); });
现在,您需要创建一个将对输入进行validation的操作:
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 }); }
这有点麻烦,但正如我所说,如果你不弄清楚客户端validation,它可以工作。
UPDATE
不知道为什么我没有想到这个…而不是依靠class="cancel"
你可以这样做:
给你的“反正”提交输入ID:
然后有一个这样的脚本:
$('#submitAyway').click(function(evt) { evt.preventDefault(); $('form').submit(); });
我没有对此进行测试,但从理论上讲,这应该在不validation的情况下提交表单。 你可能仍然需要服务器端validation,就像我在第一个例子中所示。
- jQuery Mobile绑定事件
- 如何从表单提交将产品和数量传递给ASP.NET MVC4 Web API
- 在ASP.NET MVC 4中将jQuery 1.8.3更新为jQuery 1.9.0
- 如何在我的JQUERY提交中添加其他数据?
- 使用Javascript将CSV数据转换为JSON格式
- 如何将在texbox中输入的值传递给PartialViewResult?
- JTable:’在更新或删除记录时与服务器通信时发生错误’
- 如何插入jQuery代码? 未捕获的ReferenceError:$未在视图razor代码中定义
- window.location或window.location.href没有更改所有浏览器MVC应用程序中的值