views:

67

answers:

1

I'm currently in the process of creating a shared Edit/Create view for my game review project and have hit a snag. Each game can be a title on a variety of platforms. I have this mapped as a many-to-many relationship in my EF4 model. For my view, I'd like to have a series of checkboxes with the names of each platform, and, for the Edit view, have the correct boxes checked.

I can create the checkboxes easily with an HTML helper. My biggest problem is figuring out how to tell the helper to turn on isChecked on the correct platform values. Here's what I have so far:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HandiGamer.ViewModels.AdminGameReviewViewModel>" %>

<p>
    <%: Html.LabelFor(model => model.GameData.GameTitle) %>
    <%: Html.TextBoxFor(model => model.GameData.GameTitle) %>
    <%: Html.ValidationMessageFor(model => model.GameData.GameTitle) %>
</p>
<p>
    <%: Html.LabelFor(model => model.Genres) %>
    <%: Html.DropDownList("Genre", new SelectList(ViewData["Genres"] as IEnumerable, "GenreID", "Name", Model.GameData.GenreID) %>
</p>
<p>
    <%: Html.LabelFor(model => model.Platforms) %>
    <% foreach(var item in Model.Platforms) { %>
        <%: Html.CheckBox(item.Name) %>
    <% } %>
</p>

And, my view model is:

public class AdminGameReviewViewModel
{
    public Game GameData { get; set; }
    public List<Genre> Genres { get; set; }
    public List<Platform> Platforms { get; set; }
}

Populated by:

    public ActionResult EditReview(int id)
    {
        var game = _siteDB.Games.Include("Genre").Include("Platforms").Include("Content").Single(g => g.GameID == id);
        var genres = _siteDB.Genres.ToList();
        var platforms = _siteDB.Platforms.ToList();
        var model = new { GameData = game, Genres = genres, Platforms = platforms }; 

        return View(model);
    }

So, I really just need a nudge in the right direction with the logic to determine which boxes should be checked.

Thanks.

+2  A: 

Try using Html.CheckBoxFor

The predicate is an expression bound to the field (which should be a boolean).

<%: Html.CheckBoxFor(item => item.Name) %>

Also, i noticed in your Controller you are returning an anonymous type - that should be strongly-typed to your AdminGameReviewViewModel view-model, otherwise the model binding will not work.

e.g:

var model = new AdminGameReviewViewModel { GameData = game, Genres = genres, Platforms = platforms }; 

I'm not really sure what model property you want you want for the checkbox. Are you sure an item can/can't have a Name? It sounds like item.Name is a string, which is not valid for a checkbox - you should be binding to a boolean flag.

Maybe you should add another property to your ViewModel?

RPM1984
Part of my problem is that I'm just not familiar with MVC binding and form creation. Platforms share a many-to-many relationship with games, but the only thing linking them is a pivot table, which isn't actually visible in my EF4 model. I have to have a list of all available platforms, which is what Platforms is in my view model, but I just don't know how to map the actual platforms of my GameData to the overall list of Platforms. Even if I add another property to my view model, the problem would remain - not knowing how to set isChecked on the correct platforms in the list.
kevinmajor1
Yes i have a similar setup in my EF4 model (hidden junction tale to cater for many-to-many). When you say 'not knowing how to set isChecked on the correct platforms in the list`, what do you mean? What value are you 'checking'? Remember - a checkbox represents a true/false value. Are you saying you want to be able to remove an association to a particular platform when they uncheck the box?
RPM1984
Yes, or set a new association with a different platform in the list of all available platforms. So, if PS3 is checked, I should be able to remove it and/or check XBox 360.
kevinmajor1
Hmm, yeah that's tricky. There is no 1-1 binding for the checkbox to a model property (which is generally the case with model binding). I think it will need to be manual - when you submit the form, you'll need to compare the checked items to the "enabled" platforms in your ViewModel, then for the ones that are not checked, remove it from the Platform's collection. This doesn't seem great to me though, i don't think you should allow "removing" platforms via checkboxes, it should be more explicit. (ie delete button next to each platform)
RPM1984