我正在尝试使用
实现可选的客户端验证以下图片展示了我对可选客户端验证的意思: 我的表单上唯一一个字段应该包含电子邮件,因此附加了一个电子邮件验证程序。
现在我们点击保存。由于我们的文本“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>
}
这些都很好。
如果切换到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>
}
我已调试jQuery.validation.js
以找出有什么不同,但失败了。
欢迎修改或解决问题并让ajax表单符合预期的任何想法。
要有客户端验证是绝对必须的。服务器端验证不是一个选项。除了更高的流量(此示例是简化 - 真实表单包含更多字段)和延迟之外,服务器端验证还有一件事情不会做:客户端验证器突出显示丢失焦点上的错误字段。这意味着只要您切换到下一个字段,就会收到反馈。
答案 0 :(得分:11)
这是微软不引人注目的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 }] : []);
此外,我们将类名传递给处理程序,以便它可以决定是否应该触发客户端验证。目前,无论点击哪个按钮,它始终会触发验证。现在在第154行,我们修改了以下测试:
if (!validate(this)) {
使用:
if (clickInfo[0].className != 'cancel' && !validate(this)) {
如果使用带有类名取消的提交按钮来提交表单,则不再触发客户端验证。另一种可能性是抓取jquery.unobtrusive-ajax.js
脚本并用标准Ajax.BeginForm
替换Html.BeginForm
,使用普通的旧jQuery可以不引人注意地使用AJAXify。
答案 1 :(得分: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;
});
注意:如果首先尝试它似乎不起作用 - 请确保您没有往返服务器并刷新页面时出错。您必须通过其他方式绕过服务器端的验证 - 这只是允许提交表单,而不必将.ignore
属性添加到表单中的所有内容。
(如果您正在使用按钮,则可能需要将button
添加到选择器)
答案 2 :(得分:-1)
如果不需要不显眼的验证,请将其禁用并在服务器端执行所有检查。
您可以检查服务器端的“提交”按钮的值,然后根据该值继续:
为您的两个提交输入添加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);
}
<强>更新强>
我理解客户端验证简化了工作,但是如果你无法弄清楚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 });
}
这有点麻烦,但正如我所说,如果你不弄清楚客户验证,它可以工作。
<强>更新强>
不知道为什么我没有想到这个......而不是依靠class="cancel"
你可以做这样的事情:
给你的“反正”提交输入ID:
<input type="submit" value="Save anyway" class="cancel" name="btnSubmit" id="submitAyway" />
然后有一个这样的脚本:
$('#submitAyway').click(function(evt) {
evt.preventDefault();
$('form').submit();
});
我没有对此进行测试,但从理论上讲,这应该在不验证的情况下提交表单。 您可能仍需要服务器端验证,正如我在第一个示例中所示。