MVC Controllers get value of 'Checkboxlist'

8.3k views Asked by At

I'm probably a idiot here but I'm having problems getting the value of whether or not a checkbox is checked/selected or not. Here's what I've got so far:

In my Model:

public IEnumerable<SelectListItem> Insurers
{
  get
    { 
      var list = new List<SelectListItem>();
      string zInsurersList = "Age UK,Be Wiser,Call Connection,Churchill,Sainsbury's,Direct Line,Hastings Direct,LV=,Nationwide,RIAS,Swinton";
      string[] zInsurers = zInsurersList.Split(',');
      foreach (string aInsurer in zInsurers)
      {
        list.Add(new SelectListItem() { Text = aInsurer, Value = aInsurer, Selected=false});
      }
      return list;
    }
  }
}

And my view:

@foreach (var insurer in @Model.Insurers)
{
  var zInsurer = insurer.Text;
  var zValue = insurer.Value;
  <tr>
    <td style="width: 120px; height: 35px;"><span id="@zInsurer">@zInsurer</span></td>
    <td style="width: 40px; height: 35px;"><input id="@zInsurer" type="checkbox" name="@zInsurer"></td>
  </tr>
}

So in my controller I'm trying to loop the list and get the value of whether or not the user has selected the option:

foreach (var item in model.Insurers)
{
  //if (item.GetType() == typeof(CheckBox))
  //string controlVal = ((SelectListItem)item).Selected.ToString();
  zInsurers = zInsurers + item.Text + " " + ((SelectListItem)item).Selected.ToString() + "<br/>";
}

But the value always returns false.

Could someone spare a few mins to highlight my stupidity please?

Thanks,

Craig

5

There are 5 answers

1
Win On BEST ANSWER

There are a lot of ways to do it. I normally add String Array in model to collect selected values.

public string[] SelectedInsurers { get; set; }

<input type="checkbox" name="SelectedInsurers" value="@insurer.Value" />

Here is the sample code -

MyModel

public class MyModel
{
    public string[] SelectedInsurers { get; set; }

    public IEnumerable<SelectListItem> Insurers
    {
        get
        {
            var list = new List<SelectListItem>();
            string zInsurersList = "Age UK,Be Wiser,Call Connection,Churchill,Sainsbury's,Direct Line,Hastings Direct,LV=,Nationwide,RIAS,Swinton";
            string[] zInsurers = zInsurersList.Split(',');
            foreach (string aInsurer in zInsurers)
            {
                list.Add(new SelectListItem { Text = aInsurer, Value = aInsurer, Selected = false });
            }

            return list;
        }
    }
}

Action Methods

public ActionResult Index()
{
    return View(new MyModel());
}

[HttpPost]
public ActionResult Index(MyModel model)
{
    return View();
}

View

@using (Html.BeginForm())
{
    foreach (var insurer in @Model.Insurers)
    {
        <input type="checkbox" name="SelectedInsurers" value="@insurer.Value" /> @insurer.Text<br/>
    }
    <input type="submit" value="Post Back" />
}

Result

enter image description here

1
AudioBubble On

Firstly, your property Insurers should not be IEnumerable<SelectListItem> (tha'ts for binding a collection to a dropdownlist), and in any case, that kind of logic does not belong in a getter (and whats the point of creating a comma delimited string and then splitting it? - just create an array of strings in the first place!). Its not really clear exactly what you trying to do, but you should be creating a view model and doing it the MVC way and making use of its model binding features

View model

public class InsurerVM
{
  public string Name { get; set; }
  public bool IsSelected { get; set; }
}

Controller

public ActionResult Edit()
{
  // This should be loaded from some data source
  string[] insurers = new string[] { "Age UK", "Be Wiser", "Call Connection" };
  List<InsurerVM> model = insurers.Select(i => new InsurerVM() { Name = i }).ToList();
  return View(model);
}

View

@model List<InsurerVM>
@using(Html.BeginForm())
{
  for (int i = 0; i < Model.Count; i++)
  {
    @Html.HiddenFor(m => m[i].Name)
    @Html.CheckBoxFor(m => m[i].IsSelected)
    @Html.LabelFor(m => m.[i].IsSelected, Model[i].Name)
  }
  <input type="submit" value="Save" />
}

Post method

[HttpPost]
public ActionResult Edit(IEnumerable<InsurerVM> model)
{
  // loop each item to get the insurer name and the value indicating if it has been selected
  foreach(InsurerVM insurer in model)
  {
    ....
  }
}

In reality, Insurers would be an object with an ID and other properties so it can be identified and have a relationship with other entities.

As to why you code is not working. Your property does not have a setter so nothing that posted back could be bound anyway. All the method is doing is initializing your model then calling the getter which creates a new IEnumerable<SelectListItem> (identical to the one you sent to the view in the first place). Not that it would have mattered anyway, your checkboxes have name attributes name="Age_UK", name=Be_Wiser" etc which have absolutely no relationship to your model so cant be bound

0
Jamie On

That is because the modelbinding can't process your values.

You should look into model binding.

Try something like this:

  @for (var countInsurer = 0; Model.Insurers.Count > countInsurer++)
                    {
                        var zInsurer = insurer.Text;
                        var zValue = insurer.Value;
                        <tr>
                            <td style="width: 120px; height: 35px;"><span id="@zInsurer">@zInsurer</span></td>
                            <td style="width: 40px; height: 35px;">@Html.CheckBoxFor(m=> Model.Insurers[countInsurer], new {name = zInsurer})</td>
                        </tr>
                    }
0
Loveneet Singh On
 @for(int i = 0; i < Model.List.Count; i++)
                            {
                                @Html.CheckBoxFor(m => Model.List[i].IsChecked, htmlAttributes: new { @class = "control-label col-md-2" })
                                @Model.List[i].Name
                                @Html.HiddenFor(m => Model.List[i].ID)
                                @Html.HiddenFor(m => Model.List[i].Name)
                            <br />
                            }  

in controller

StringBuilder sb = new StringBuilder();
                    foreach (var item in objDetail.List)
                    {
                        if (item.IsChecked)
                        {  
                            sb.Append(item.Value + ",");
                        }
                    }    
                    ViewBag.Loc = "Your preferred work locations are " + sb.ToString();
0
Purushottam Saini On

I Get Module And Right from Module and Rights Table How to Send All Data To RoleRight Table All Checkbox value

public class RoleRightModel
{        
    public ModuleModel _ModuleModel { get; set; }
    public RightsModel _RightsModel { get; set; }
    public RolesModel _RolesModel { get; set; }
    public List<ModuleModel> _ModuleModelList { get; set; }
    public List<RightsModel> _RightsModelList { get; set; }
    public List<RolesModel> _RolesModelList { get; set; }
    public List<RoleRightModel> _RoleRightModelList { get; set; }
    public int RoleRightID { get; set; }
    public int RoleID { get; set; }
    public int ModuleID { get; set; }
    public int FormMode { get; set; }
    public int RightCode { get; set; }
    public bool? RowInternal { get; set; }
    public byte? IsAuthorised { get; set; }
    public int? CreationID { get; set; }
    public DateTime? CreationDate { get; set; }
    public int? LastModificationID { get; set; }
    public DateTime? LastModificationDate { get; set; }
    public byte? RowStatus { get; set; }

    public string RoleName { get; set; }
}

Razor

@foreach(var item in Model._ModuleModelList.Where(x => x.Level == 1))
{
    <ul style="display: block;">
        <li><i class="fa fa-plus"></i>
            <label>
                @if (item.Level == 1)
                {
                    <input id="node-0-1" data-id="custom-1" type="checkbox" name="Module" value="@item.ModuleID"@(Model._ModuleModel.ModuleID)? "checked":"">
                    @item.ModuleName

                }
            </label>
            @foreach (var lavel1 in Model._ModuleModelList.Where(x => x.ParentModuleID == item.ModuleID))
            {
                <ul>
                    <li><i class="fa fa-plus"></i>
                        <label>
                            <input id="node-0-1-1" data-id="custom-1-1" type="checkbox" name="Module" value="@lavel1.ModuleID"@(Model._ModuleModel.ModuleID)? "checked":"">
                            @lavel1.ModuleName
                        </label>
                        @foreach (var lavel2 in Model._ModuleModelList.Where(x => x.ParentModuleID == lavel1.ModuleID))
                        {
                            <ul>
                                <li><i class="fa fa-plus"></i>
                                    <label>
                                        <input id="node-0-1-1-1" data-id="custom-1-1-1" type="checkbox" name="Module" value="@lavel2.ModuleID"@(Model._ModuleModel.ModuleID)? "checked":"">
                                        @lavel2.ModuleName
                                    </label>
                                    @foreach (var lavel3 in Model._RightsModelList.Where(x => x.ModuleId == lavel2.ModuleID))
                                    {
                                        <ul>
                                            <li>
                                                <label>

                                                    <input id="node-0-1-1-1-1" data-id="custom-1-1-1-1" type="checkbox" name="Right" value="@lavel3.RightID"@(Model._RightsModel.RightID)? "checked":"">
                                                    @lavel3.RightName
                                                </label>
                                            </li>
                                        </ul>
                                    }
                                </li>
                            </ul>
                        }
                    </li>
                </ul>
            }
        </li>
    </ul>
}