我同意 - 在多种形式 - 组件

时间:2014-07-25 21:33:40

标签: asp.net-mvc-3 asp.net-mvc-4 razor

我要求在应用程序的许多表单中生成一个同意框。

我使用jQuery构建了一个禁用提交按钮的组件,直到选中了“同意”复选框。如果未选中复选框(即ModelState错误的一部分),产品所有者想要返回错误消息,则不会删除它。

在不必更改与表单关联的所有ViewModel的情况下,最好的方法是什么,并保留可以在任何页面上使用的漂亮的通用部分(唯一改变的是我同意 - 同意文本

2 个答案:

答案 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>

现在会做什么:

  1. 它挂钩到表单提交事件
  2. 检查该表单上的最后一个复选框是否已“检查”
  3. 如果未选中,则会阻止表单提交,您可以在此处执行任何操作
  4. 在您不想编辑代码,更改模型等的情况下,这是理想的选择。最大的好处是可以在可重复使用的代码段中轻松地重构,可以包含在运行中。

    选项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!');
    }
  });
});