Asp.Net Mvc Checkbox list
Create a custom 'services check box item' class (reusable), and make a list or enumerable of them as a property in your AdditionalServicesModel. Also, its probably a better idea to create a constructor of the model so you don't have to assign the model properties inside the controller.
public class ServicesItem
{
public bool Selected { get; set; }
public string Value { get; set; }
public string Text { get; set; }
}
public class AdditionalServicesModel
{
public AdditionalServicesModel(IList<ServicesItem> items){
this.AdditionalServices = items;
}
public IList<ServicesItem> AdditionalServices { get; set; }
}
Create a custom editor template for Additional Services, to easily reference in your view (you don't have to add a hidden for the text, as only the value and selected properties will be default binded back to the model:
@Html.CheckBoxFor(m => Selected)
@Html.LabelFor(m => Text)
@Html.HiddenFor(m => Value)
Then pop the editor template into your view (let MVC.net do its magic - have a look at the markup to see what it does):
@Html.EditorFor(m => m.AdditionalServices)
Then inspect the automatically bound values in your controller:
public class HomeController : Controller
{
public ActionResult Index()
{
List<SelectListItem> services = new List<SelectListItem>();
services.Add(new SelectListItem { Text = "service-1", Value = "1", Selected=false });
services.Add(new SelectListItem { Text = "service-2", Value = "2", Selected=false });
services.Add(new SelectListItem { Text = "service-3", Value = "3", Selected=false });
return View(new AdditionalServicesModel(services));
}
[HttpPost]
public ActionResult Index(AdditionalServicesModel result)
{
var selectedServicesList = result.AdditionalServices.Where(s => s.Selected);
return RedirectToAction("Thanks", "Home");
}
}
Alex
Updated on July 03, 2022Comments
-
Alex almost 2 years
I'm implementing check box list in MVC, although I succeed to get the desired result, I have a doubt in my approach:
public class AdditionalServicesModel { public IList<SelectListItem> AdditionalServices { get; set; } }
=========================================================================
public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { AdditionalServicesModel objAdditionalServicesModel = new AdditionalServicesModel(); List<SelectListItem> services = new List<SelectListItem>(); services.Add(new SelectListItem { Text = "service-1", Value = "1", Selected=false }); services.Add(new SelectListItem { Text = "service-2", Value = "2", Selected=false }); services.Add(new SelectListItem { Text = "service-3", Value = "3", Selected=false }); objAdditionalServicesModel.AdditionalServices = services; return View(objAdditionalServicesModel); } [HttpPost] public ActionResult Index(AdditionalServicesModel result) { return RedirectToAction("Thanks", "Home"); } public ActionResult Thanks() { return View(); } }
=========================================================================
@model checkboxes.Models.AdditionalServicesModel @{ ViewBag.Title = "Index"; Layout = null; } @using (Html.BeginForm("Index", "Home", FormMethod.Post)) { for (int i = 0; i < Model.AdditionalServices.Count; i++) { <ul> <li> @Html.CheckBoxFor(m=>Model.AdditionalServices[i].Selected, new { id = "Chk-" + i}) @Html.Label(Model.AdditionalServices[i].Text, new { @for = "Chk-" + i }) @Html.HiddenFor(m => Model.AdditionalServices[i].Text) @Html.HiddenFor(m=> Model.AdditionalServices[i].Value) </li> </ul> } <input type="submit" value="POST to Controller" /> }
1) For one checkbox I should create 2 additional hidden fields. Is there a better approach? I feel like it just wrong to make all this long way just to send checkboxes values + names, It would be much easier to collect its values with javascript and send it via Json, but then I will not have an unobtrusive validation...
2) I send all check boxes while I need to send only selected boxes. Is there a way to do it with forms post?