CheckboxList in MVC3 View and get the checked items passed to the controller
Asked Answered
T

3

25

I have a class for MoreInfo:

public class MoreInfo
{
        public string Name { get; set; }
        public string selectedCheckboxItems {get; set;}
}

I want to know how to create a checkbox list on the view and pass the checked off items to my controller on submit.

How would I go about creating the checkbox list and how to pass all the checked items and process them?

Tadio answered 12/3, 2011 at 18:6 Comment(1)
I made something similar you could use it as a replacement for checkboxlist, it's called Lookup with multiselect mrgsp.md:8080/awesome/lookupdemo hthNasion
R
45

Let's modify your model a little:

public class ItemViewModel
{
    public string Id { get; set; }
    public string Name { get; set; }
    public bool Checked { get; set; }
}

then you could have a controller:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        // This action is used to render the form => 
        // we should populate our model with some values
        // which could obviously come from some data source
        var model = new[]
        {
            new ItemViewModel { Id = "1", Checked = true, Name = "item 1" },
            new ItemViewModel { Id = "2", Checked = false, Name = "item 2" },
            new ItemViewModel { Id = "3", Checked = true, Name = "item 3" },
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(IEnumerable<ItemViewModel> items)
    {
        // This action will be invoked when the form is submitted
        // and here the view model will be properly bound and
        // you will get a collection of all items with their
        // corresponding id, name and whether they were checked or not
        ...
    }
}

then you would have a corresponding view (~/Views/Home/Index.cshtml) which would contain the form allowing the user to check/uncheck values:

@model IEnumerable<AppName.Models.ItemViewModel>
@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <input type="submit" value="OK" />
}

and finally the editor template (~/Views/Home/EditorTemplates/ItemViewModel.cshtml):

@model AppName.Models.ItemViewModel
// Those two hidden fields are just to persist the id and name
@Html.HiddenFor(x => x.Id)
@Html.HiddenFor(x => x.Name)
<div>
    @Html.CheckBoxFor(x => x.Checked)
    @Html.LabelFor(x => x.Checked, Model.Name)
</div>
Radman answered 12/3, 2011 at 19:50 Comment(6)
Is this answer still valid for MVC4?Biisk
Yes, this solution is still valid for MVC 4.Radman
Ok. I think I will create a separate question, because my scenario is a little bit different.Biisk
Here the Checked value is passed as true and false. How to get the checkbox value dynamically ?Acclaim
@kk1076, what do you mean by dynamically? I don't understand your question.Radman
To get Only when the user selects the checkbox and pass the list of selected items of checkboxlist. But here the value of checkbox is passed.Acclaim
I
21
public class MoreInfo
{
        public Int64 Id {get; set;}
        public string Name { get; set; }
        public bool Checkbox {get; set;}
}

Controller Action:

public ActionResult Index(){
  var list = new List<MoreInfo>{
      new MoreInfo{Id = 1, Name = "Name1", Checkbox = false},
      new MoreInfo{Id = 2, Name = "Name2", Checkbox = false},
      new MoreInfo{Id = 3, Name = "Name3", Checkbox = true},
  };
  return View(list);
}

[HttpPost]
public ActionResult Index(List<MoreInfo> lists){

  return View(lists);
}

Razor View:

@model List<MoreInfo>

<form action="" method="POST">
@for (var i = 0; i < Model.Count();i++ )
{
    @Html.HiddenFor(it => it[i].Id)
    @Html.TextBoxFor(it => it[i].Name)
    @Html.CheckBoxFor(it => it[i].Checkbox)
}
<input type="submit" />
</form>

More information here

Intact answered 17/6, 2011 at 4:55 Comment(1)
First solution totally did not work for me and this one worked nicely!Embayment
D
1

its that easy:
1. create the checkbox class with string id and bool value.
2. put list of checkbox in the controller method with some name.
3. create 2 fields dynamically in your view but make sure you conform to the razor engine naming system.

to create a dynamic checkbox list you need to understand the way the razor engine works, say you have this code
in the head of the view you include a model like so:

@model MyProject.Site.Models.MyWebModel  

that model has a setting class that has a bool inside like so:

public class MyWebModel  
{  
    public HighchartsSettingModel Settings { get; set; }  
}  
public class HighchartsSettingModel  
{  
    public bool JoinSameType{ get; set; }  
}

and in the view you have:

@Html.CheckBoxFor(x => x.Settings.JoinSameType)

in short this creates the following html code:

<input data-val="true" data-val-required="The JoinSameType field is required." id="Settings_JoinSameType" name="Settings.JoinSameType" type="checkbox" value="true" />
<input name="Settings.JoinSameType" type="hidden" value="false" />

so far so good for the CheckBoxFor, that is a part of the framwork, how do we work with arrays?


so now all we need to do is to understand how to work with list in a controller method, say you have this class:

public class Checkbox{
   public string Id { get; set; }
   public bool Value { get; set; }
}

and in the controller you have this:

public ActionResult SensorSearch(List<Checkbox> selectedSensors, string search, string subSearch, string page, string back)

and the view will look like so:

@{  
        int counter = 0;  
        string id_name, id_id, value_id, value_name;  
    }  
    @foreach (var item in Model.SensorList)  
    {  
        id_id = "selectedSensors_" + counter + "__Value";  
        id_name = "selectedSensors[" + counter + "].Value";  
        value_id = "selectedSensors_" + counter + "__Id";  
        value_name = "selectedSensors[" + counter + "].Id";  
        counter++; 


    <li><a href="#" style="padding-top: 0px;padding-bottom: 0px;padding-right: 42px;padding-left: 0px;">
        <label style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;" data-corners="false">
            <fieldset data-role="controlgroup" >
                <input id="@id_id" name="@id_name" type="checkbox" value="true" />
                <input id="@value_id" name="@value_name" type="hidden" value="@item.Key" />                                
                <label for="@id_id" style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;">
                    <label  style="padding:10px 0px 0px 10px;">
                        <h3>@item.Key</h3>
                        <p>User Name: @item.Value</p>
                    </label>
                </label>
            </fieldset>
        </label>
        </a><a href="#" rel="external"></a>
    </li>
}
</ul>   

lets not forget the form in the view:

@using (Html.BeginForm("SensorSearch", "Home", Model.PageNav.StayRouteValues, FormMethod.Post, new Dictionary<string, object>() { { "data-ajax", "false" }, { "id", "sensor_search_form" } }))

now the rendered page will look like so in the checkbox aspect:

<li><a href="#" style="padding-top: 0px;padding-bottom: 0px;padding-right: 42px;padding-left: 0px;">
<label style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;" data-corners="false">
    <fieldset data-role="controlgroup" >
        <input id="selectedSensors_16__Value" name="selectedSensors[16].Value" type="checkbox" value="true" />
        <input id="selectedSensors_16__Id" name="selectedSensors[16].Id" type="hidden" value="10141" />                                
        <label for="selectedSensors_16__Value" style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;">
            <label  style="padding:10px 0px 0px 10px;">
                <h3>10141</h3>
                <p>User Name: 10141_TEN-2MP</p>
            </label>
        </label>
    </fieldset>
</label>
</a><a href="#" rel="external"></a>
</li>

what you need to notice is the names given to the input-checkbox and the input-hidden we used it similar to the way razor engine creates name and so after submit the engine will render this as an array and so you can create any dynamic checkbox list where ever you want same as you would in any other language (say php and so...) .

its that easy: its that easy:
1. create the checkbox class with string id and bool value.
2. put list of checkbox in the controller method with some name.
3. create 2 fields dynamically in your view but make sure you conform to the razor engine naming system.

i hoped it helped.

Decimal answered 31/12, 2012 at 18:28 Comment(1)
That doesnt look very easy :( flipping heck its quite complicatedHeadman

© 2022 - 2024 — McMap. All rights reserved.