我想用来实现可选的客户端验证
- 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
任何想法修复或解决该问题,并让阿贾克斯形式表现为预期的欢迎。
附录
为了有一个客户端验证是绝对必要的。 服务器端验证是不是一种选择。 除了较高的流量(此示例是一种简化 - 真正的形式包含更多的字段)和延迟,有一件事情是服务器端验证不会做:客户端验证突出显示失去焦点错误的领域。 这意味着你只要有一个反馈您标签到下一个区域。
这是微软的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。
最后,我想出了一个解决方案,它本身就是不显眼
// 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
来选择,如果你正在使用的按钮)
如果不需要验证不显眼,禁用它,做你在服务器端的所有检查。
你可以检查值提交服务器端的按钮,并基于该着手:
添加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