I've been reading the various posts on view models and check boxes, but my brain is starting to lock up and I need a little push in the right direction.
Here's my simplified view model. I have checkboxes that need to populate the lists with their values. I don't think this can happen automagically. I'm not sure how to bridge the gap between an array of string values and a List correctly. Suggestions?
public int AlertId { get; set; }
public List<int> UserChannelIds { get; set; }
public List<int> SharedChannelIds { get; set; }
public List<int> SelectedDays { get; set; }
Have your View Model like this to represent the CheckBox item
public class ChannelViewModel
{
public string Name { set;get;}
public int Id { set;get;}
public bool IsSelected { set;get;}
}
Now your main ViewModel will be like this
public class AlertViewModel
{
public int AlertId { get; set; }
public List<ChannelViewModel> UserChannelIds { get; set; }
//Other Properties also her
public AlertViewModel()
{
UserChannelIds=new List<ChannelViewModel>();
}
}
Now in your GET
Action, you will fill the values of the ViewModel and sent it to the view.
public ActionResult AddAlert()
{
var vm = new ChannelViewModel();
//The below code is hardcoded for demo. you mat replace with DB data.
vm.UserChannelIds.Add(new ChannelViewModel{ Name = "Test1" , Id=1});
vm.UserChannelIds.Add(new ChannelViewModel{ Name = "Test2", Id=2 });
return View(vm);
}
Now Let's create an EditorTemplate. Go to Views/YourControllerName
and Crete a Folder called "EditorTemplates" and Create a new View there with the same name as of the Property Name(ChannelViewModel.cshtml
)
Add this code ro your new editor template.
@model ChannelViewModel
<p>
<b>@Model.Name</b> :
@Html.CheckBoxFor(x => x.IsSelected) <br />
@Html.HiddenFor(x=>x.Id)
</p>
Now in your Main View, Call your Editor template using the EditorFor
Html Helper method.
@model AlertViewModel
<h2>AddTag</h2>
@using (Html.BeginForm())
{
<div>
@Html.LabelFor(m => m.AlertId)
@Html.TextBoxFor(m => m.AlertId)
</div>
<div>
@Html.EditorFor(m=>m.UserChannelIds)
</div>
<input type="submit" value="Submit" />
}
Now when You Post the Form, Your Model will have the UserChannelIds
Collection where the Selected Checkboxes will be having a True
value for the IsSelected
Property.
[HttpPost]
public ActionResult AddAlert(AlertViewModel model)
{
if(ModelState.IsValid)
{
//Check for model.UserChannelIds collection and Each items
// IsSelected property value.
//Save and Redirect(PRG pattern)
}
return View(model);
}
Part of My View Model:
public List<int> UserChannelIds { get; set; }
public List<int> SharedChannelIds { get; set; }
public List<int> Weekdays { get; set; }
public MyViewModel()
{
UserChannelIds = new List<int>();
SharedChannelIds = new List<int>();
Weekdays = new List<int>();
}
I used partial views to display my reusable checkboxes (I didn't know about editor templates at this point):
@using AlertsProcessor
@using WngAlertingPortal.Code
@model List<int>
@{
var sChannels = new List<uv_SharedChannels>();
Utility.LoadSharedChannels(sChannels);
}
<p><strong>Shared Channels:</strong></p>
<ul class="channel-list">
@{
foreach (var c in sChannels)
{
string chk = (Model.Contains(c.SharedChannelId)) ? "checked=\"checked\"" : "";
<li><input type="checkbox" name="SharedChannelIds" value="@c.SharedChannelId" @chk /> @c.Description (@c.Channel)</li>
}
}
All three checkbox partial views are similar to each other. The values of the checkboxes are integers, so by lining up my view model List names with the checkbox names, the binding works.
Because I am working in int values, I don't feel like I need the extra class to represent the checkboxes. Only checked checkboxes get sent, so I don't need to verify they are checked; I just want the sent values. By initializing the List in the constructor, I should be avoiding null exceptions.
Is this better, worse or just as good as the other solution? Is the other solution (involving an extra class) best practice?
The following articles were helpful to me:
http://forums.asp.net/t/1779915.aspx/1?Checkbox+in+MVC3
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Binding list with view model
This site handles it very nicely
https://www.exceptionnotfound.net/simple-checkboxlist-in-asp-net-mvc/
public class AddMovieVM
{
[DisplayName("Title: ")]
public string Title { get; set; }
public List<CheckBoxListItem> Genres { get; set; }
public AddMovieVM()
{
Genres = new List<CheckBoxListItem>();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With