我要求在应用程序的许多表单中生成一个同意框。
我使用jQuery构建了一个禁用提交按钮的组件,直到选中了“同意”复选框。如果未选中复选框(即ModelState错误的一部分),产品所有者想要返回错误消息,则不会删除它。
在不必更改与表单关联的所有ViewModel的情况下,最好的方法是什么,并保留可以在任何页面上使用的漂亮的通用部分(唯一改变的是我同意 - 同意文本
答案 0 :(得分:6)
我可以从您的描述以及其他人的评论中读到,您希望尽可能少地工作,并且需要多次应用所请求的行为。而且您不想编辑模型。
特别是考虑到后者,最常用的逻辑选择是客户端解决方案,我在下面提供了一个可能的解决方案。但是,我还提供了第二个选项,需要更多的工作,但会在代码的ModelState方面为您提供更大的灵活性。
注意:以下两个选项都不是100%可重复使用的样本。根据表单的设置方式,它仍然需要您的一些工作。
选项1:客户端脚本
第一个选项是简单地连接到表单发布事件并在那里做你的魔术。类似的东西:
<script>
// Hook into the form submit event
// In this case, fetch the first form we encounter
$("form:first-of-type").submit(function (e) {
// fetch the *last* checkbox in the appropriate form
// assuming the last checkbox is always the 'agree' checkbox
var agreedCheckBox = $("input[type='checkbox']:last-of-type");
if (!agreedCheckBox.is(':checked')) {
// nope, it's not checked so do your magic here
// TODO: Show alert... do something
// Also, don't forget to cancel the form post
e.preventDefault();
}
});
</script>
现在会做什么:
在您不想编辑代码,更改模型等的情况下,这是理想的选择。最大的好处是可以在可重复使用的代码段中轻松地重构,可以包含在运行中。
选项2:自定义ModelBinder
第二个选项也是一个quickwin,但重点是你的服务器端代码:你可以创建一个自定义模型绑定器,它将检查要检查的相应复选框(最后?)。如果没有,您可以在那里轻松添加ModelStateError。像这样:
public class RequireConsentModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
// TODO: Iterate through the 'request.Form' values, find the last checkbox
// and see if it's checked
if (!checked)
bindingContext.ModelState.AddModelError("", "You forgot to agree to our terms, silly you...");
return bindingContext.Model;
}
}
这个选项在你的代码中比选项1中的简单Javascript解决方案更突出,考虑到你需要手动告诉MVC这个绑定器应该做什么动作:
[HttpPost]
public ActionResult SomePost([ModelBinder(typeof(RequireConsentModelBinder))]FormCollection form)
{
if (!ModelState.IsValid)
{
// here is where you'll know if it worked...
}
return View();
}
使用这种方法,您还可以不必编辑任何模型;它只需要更改ActionResult参数的签名,以使其符合要求。最后的奖励是你可以随意注入ModelState。
希望这有助于......
答案 1 :(得分:1)
我只是评估当您单击按钮时是否标记了复选框,还是通过对用户的警报来标记。 如果需要http://plnkr.co/edit/Z0Hts5qzUl3eBa8LaDpD?p=preview
,这里也是一个例子
$(document).ready(function() {
$("#submit").click(function() {
if ($('#agreeCheck').is(':checked')) {
alert('Checkbox is checked!')
/*Code here for if box is checked*/
} else {
alert('Must agree to terms and conditions!');
}
});
});