在表单中使用CheckBoxFor

时间:2014-11-26 15:22:47

标签: c# html asp.net-mvc forms checkbox

我在视图中有以下表格:

@using (Html.BeginForm("Subscriptions", "Group", new { id = Model.Id, slug = Model.Slug,  Groups = Model.Groups,  Names = Model.SelectedNames, SelectedMemberEmail = Model.SelectedMember.EmailAddress, WhichView = "Subscriptions", }, FormMethod.Post))
   {
     <div id="communitygroupsedit" class="list-unstyled">
       @for (var x = 0; x < Model.Groups.Count; x++)
          {
             if (Model.Groups[x].Name == "All members")
               {
                  Model.Groups[x].AdminOnly = true;
               }
            string adminTest = (Model.Groups[x].AdminOnly && !Model.IsUserAdministrator) ? "disabled=\"disabled\"" : string.Empty;
            string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty;

             <p>
               @Html.CheckBoxFor(m => m.Groups[x].IsMember, new { @adminTest @checktest})
               @Html.Raw(Model.Groups[x].Name + " - " + Model.Groups[x].Description)
               @if (adminTest == "disabled=\"disabled\"" && !Model.IsUserAdministrator && checktest == "checked=\"checked\"")
                {
                    Model.SelectedNames.Add(Model.Groups[x].Name);
                }                         
             </p>
      }
       </div>
     if (Model.Groups.Count > 0)
     {
         @Html.SubmitButton("Update groups", false, new { @class = "btn btn-primary" });
      }

问题是在控制器中,&#39;群组&#39; list对象为空,在视图中,满足条件时不会禁用复选框。此选择的名称属性也没有填充&#39;名称&#39;列出我需要的。我在这种形式上做错了什么?

2 个答案:

答案 0 :(得分:1)

这种形式我做错了什么? 一切!

至于为什么你没有得到SelectedNames,你没有为它提供任何控制,所以如何回复

如果您查看action标记的<form>属性,则应该很明显。它会有类似

的东西
<form action="/Group/Subscriptions.....?Names=System.Collections.Generic.List%601%5BYourAssembly.YourModelName%5D" ....>

因此,当您发布表单时,属性SelectedNames是一个字符串"System.Collections.Generic.List...",它不能绑定到集合。

现在检查html的复选框,您会看到类似的内容(取决于adminTestchecktest

的值
<input type="checkbox" ... adminTest="" checktest="checked="checked"">

当然不会设置复选框的disabledchecked属性。即使你做得正确并且复选框已被禁用并选中(true),它也会回发false的值(禁用复选框不会回发,因此ModelBinder会绑定到false因为相关的隐藏输入而且你得到的数据不正确。

当您使用@Html.CheckBoxFor(m => m.Groups[x].IsMember)时,复选框状态是根据IsMember的值设置的,因此代码string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty;不仅错误,而且完全没有意义。

if (Model.Groups.Count > 0)有什么意义?您编辑的唯一内容是Groups,如果没有,为什么会显示一个无法提交的空白表单!

删除所有这些并创建视图模型以显示/编辑您想要的内容

查看模型

public class GroupVM
{
  public int ID { get; set; }
  public string DisplayName { get; set; }
  public bool IsMember { get; set; }
}

public class MyModelVM
{
  public int ID {get; set; }
  // any other properties of the model you want to display
  public List<GroupVM> Groups { get; set; }
}

控制器

public ActionResult Group(int ID)
{
  // Get your data model
  ....
  MyModelVM model = new MyModelVM();
  model.Groups = new List<GroupVM>();
  // Populate the collection based on your data model
  foreach(var item in yourDataModel.Groups)
  {
    GroupVM group = new GroupVM();
    // apply you logic here
    if(item.AdminOnly && !item.IsUserAdministrator)
    {
      continue; // no point displaying these
    }
    group.ID = item.ID;
    group.DisplayName = string.Format("{0} - {1}", item.Name, item.Description)
    group.IsMember = item.IsMember;
    model.Groups.Add(group);
  }
  if (model.Groups.Count == 0)
  {
    // ?? is there any point displaying a form?
  }
  return View(model);
}

查看

@model MyModelVM
@using (Html.BeginForm())
{
  for(int i = 0; i < Model.Groups.Count; i++)
  {
    @Html.HiddenFor(m => m.Groups[i].ID)
    @Html.CheckBoxFor(m => m.Groups[i].IsMember)
    @Html.LabelFor(m => m.Groups[i].DisplayName)
  }
  <input type="submit" value="Update groups" />
}

POST方法

public ActionResult Group(MyModel model)
{
  // The model contains the ID so get the data model from the database
  // and loop model.Groups to update the data model and save
}

答案 1 :(得分:-1)

我很高兴地说我终于开始工作了。斯蒂芬你的帖子说明我不知道一个表格应该如何工作,因为我认为你可以将任何旧的值从那里传递给控制器​​。不幸的是,你的解决方案对我来说不起作用,因为我仍然希望在只读状态下显示复选框,如果它是“管理员”的话。复选框和您的代码根本不会显示它。

我解决了复选框的问题,如果只是按照我想要的方式渲染复选框,然后使用hiddenfor来恢复框的状态,则会返回false。
你问的另一件事是if(groups.count&gt; 0)..show提交按钮是什么意思。这是因为如果没有群组,我不希望呈现提交按钮。

我觉得我从这个问题中学到了很多东西,所以非常感谢斯蒂芬的所有帮助。

这就是我提出的:

 @using (Html.BeginForm("Subscriptions", "Group", FormMethod.Post))
     {
       <div id="communitygroupsedit" class="list-unstyled">
          <p> @if (Model.Groups[x].AdminOnly)
                {
                  string adminTest = (Model.Groups[x].AdminOnly && !Model.IsUserAdministrator) ? "disabled=\"disabled\"" : string.Empty;
                  string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty;
                  <input type="checkbox" @adminTest @checktest />

                  @Html.HiddenFor(m => m.Groups[x].IsMember)
                  @Html.HiddenFor(m => m.Groups[x].Name)
                  @Html.HiddenFor(m => m.Groups[x].AdminOnly)
               }
              else
                 {
                   @Html.CheckBoxFor(m => m.Groups[x].IsMember)
                @Html.HiddenFor(m => m.Groups[x].Name)
                 @Html.HiddenFor(m => m.Groups[x].AdminOnly)
              }
              @Html.Raw(Model.Groups[x].Name + " - " + Model.Groups[x].Description)
                                             </p>
               }
             </div>
             if (Model.Groups.Count > 0)
           {
           @Html.SubmitButton("Update groups", false, new { @class = "btn btn-primary" });
           }
        }

在控制器中:

 List<string> Names = new List<string>();
 foreach (var group in input.Groups)
   {
     if (group.IsMember)
     Names.Add(group.Name);
   }

...写入数据库