Reputation: 2394
i have the following database table for the Compounds table (chemical compounds/elements in the periodic table) there are typos in table data so ignore them
the data is :
the controller :
public class CheckboxController : Controller
{
//
// GET: /Checkbox/
testdbEntities db = new testdbEntities();
[HttpGet]
public ActionResult Index()
{
var comps = db.Compounds.Select(c => new CompoundModel { Id=c.Id, CompoundName=c.Name, IsSelected=c.IsSelected}).ToList();
CheckboxVM cvm = new CheckboxVM { checkboxData=comps};
return View(cvm);
}
[HttpPost]
public string Index(IEnumerable<CheckboxVM> collection)
{
return "";
}
}
Model class CompoundModel is:
public class CompoundModel
{
public int Id { get; set; }
public string Code { get; set; }
public string CompoundName { get; set; }
public bool IsSelected { get; set; }
}
and the ViewModel CheckBoxVM:
public class CheckboxVM
{
public string Id { get; set; }
public string CompoundNmae { get; set; }
public bool IsSelected { get; set; }
public IEnumerable<CompoundModel> checkboxData { get; set; }
}
When the page loads it should display check boxes with names and if db table has checked on them (IsSelected=1)
then they should be checked.In the post back i need to receive the id, of the user checked checkboxes
. At the moment my code does meet the first requirement to check the checked checkboxes
based on IsSelected
on page load. Is there a way to fix this?
If you need a video with debugging please ask i will be happy to post : )
THE VIEW: (UPDATE)
@model recitejs1.Models.CheckboxVM
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
foreach (var item in Model.checkboxData)
{
@Html.CheckBoxFor(x=>x.IsSelected, (item.IsSelected)?new{@checked="check"}:null)@item.CompoundName
@Html.HiddenFor(x=>x.Id, item.Id)
@Html.HiddenFor(x=>x.CompoundNmae, item.CompoundName)
}
<br><br>
<input type="submit" name="name" value="Send" />
}
Upvotes: 0
Views: 194
Reputation:
You cannot use a foreach
loop to generate form controls. It generates duplicate name
attributes (that have no relationship to your model) and duplicate id
attributes (invalid html).
Create a custom `EditorTemplate for your model
In /Views/Shared/EditorTemplates/CompoundModel.cshtml
@model recitejs1.Models.CompoundModel
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.CompoundName)
@Html.CheckBoxFor(m => m.IsSelected)
@Html.LabelFor(m => m.CompoundName)
Then in the main view
@model recitejs1.Models.CheckboxVM
....
@using (Html.BeginForm())
{
@Html.EditorFor(m => m.checkboxData)
<input type="submit" name="name" value="Send" />
}
The EditorFor()
method will generate the correct html for each item in your collection
Note: You should inspect the html before and after you make this change to better understand how model binding works.
Note also that your POST method parameter needs to be
public string Index(CheckboxVM model)
since that's what the view is based on. However the only property of CheckboxVM
that you use in the view is IEnumerable<CompoundModel> checkboxData
in which case your view should be
@model IEnumerable<CompoundModel>
...
@Html.EditorFor(m => m)
and keep the POST method as it is (but change the GET method)
Upvotes: 2