10

I have searched a lot and spend 3 days only for searching and trying different technique (on stackoverflow etc) but I find no solution for implementing checkboxlist in asp.net mvc. And at last I am posting my problem to stackoverflow;
So, my model looks like this;

Many to Many relationship of my model(1 category may contain many project and a project may belongs to many categories) rel

Many to Many relationship of my model(1 category may contain many projects and a project may belongs to many categories)
My controller;

 [HttpGet]
    [Authorize(Roles = "Admin")]
    public ActionResult ProjectAdd()
    {
        return View();
    }

My view;

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Add New Project</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjectHeading)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjectHeading)
            @Html.ValidationMessageFor(model => model.ProjectHeading)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjecctUrl)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjecctUrl)
            @Html.ValidationMessageFor(model => model.ProjecctUrl)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjectLongDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjectLongDescription)
            @Html.ValidationMessageFor(model => model.ProjectLongDescription)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PromoFront)
        </div>
        @Html.EditorFor(model => model.PromoFront)
        @Html.ValidationMessageFor(model => model.PromoFront)

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjectThubmnail)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjectThubmnail)
            @Html.ValidationMessageFor(model => model.ProjectThubmnail)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjectImage)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjectImage)
            @Html.ValidationMessageFor(model => model.ProjectImage)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CategoryId)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CategoryId)
            @Html.ValidationMessageFor(model => model.CategoryId)
        </div>

        <p>
            <input type="submit" value="Create" class="submit" />
        </p>

So, my question is How do I display checkboxlist for categories in my view?
How do I get selected values from that checkboxlist?

Idrees Khan
  • 7,702
  • 18
  • 63
  • 111

2 Answers2

17

You need to have an object that will have a list of all categories, for example, you could do this:

[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd()
{
    // Get all categories and pass it into the View
    ViewBag.Categories = db.ListAllCategories();

    return View();
}

in the top of your View

@model Database.Project
@{
   // retrieve the list of Categories
   List<Database.Category> categories = ViewBag.Categories;
}

and then replace this

    <div class="editor-label">
        @Html.LabelFor(model => model.CategoryId)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.CategoryId)
        @Html.ValidationMessageFor(model => model.CategoryId)
    </div>

for this

    <div class="editor-label">
        <label for="categories">Categories</label>
    </div>
    <div class="editor-field">
        @foreach(var c in categories) {

        <label class="checkbox">
            <input type="checkbox" name="categories" value="@c.CategoryId"> @c.CategoryName
        </label>

        }
    </div>

back in your Controller

[HttpPost]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd(Database.Project model, int[] categories)
{
    if(ModelState.IsValid) {

        // fill up categories
        db.InsertAndSaveProject(model, categories);

    }

    ...

    return redirectToView("ProjectAdd");
}
balexandre
  • 73,608
  • 45
  • 233
  • 342
  • can u tell me one more thing, which is how do I loop through each categories – Idrees Khan Sep 29 '12 at 06:47
  • @DotNetDreamer with a `foreach(int cat in categories) db.InsertCategory(model.ProductId, cat);` and you need a table to hold both values, a `ProductCategories` table that only contain `ProductId` and `CategoryId`. Remember that for EDITING, you need to delete all categories for that product in the new table `ProductCategories` and add them again. – balexandre Sep 29 '12 at 07:21
  • yes, I have done that already I-e ProjectCategories but I need to insert this in the third table? – Idrees Khan Sep 29 '12 at 07:22
  • for a N-to-N you need 3 tables: `TBL_Products`, `TBL_Categories` and `TBL_ProductCategories` – balexandre Sep 29 '12 at 09:53
  • Is there anyway to do this using the ICollection and ICollection rather than creating the third model? I thought the whole point of Entity Framework was to get around the idea of building all the table legwork? – bbodenmiller Mar 06 '13 at 00:49
  • @bbodenmiller EF is not a wizard, it will never know what goes where... for a **n-to-n** you always need an extra table, not the case for **1-to-n** of course... – balexandre Mar 06 '13 at 09:20
  • @balexandre in the example shown here all you have to do is create the two models as shown and then the EF will create that third table correct? Then you just change what is and isn't in the third table when you make changes right? – bbodenmiller Mar 06 '13 at 21:22
  • I am used but Categories give me still null – Vishal Kiri Jan 22 '16 at 09:47
  • What will be used in form – Vishal Kiri Jan 22 '16 at 09:48
4

Answer suggested by @balexandre above works great. However, I used following HTML Extension for CheckBoxList.

1. CheckboxList in ASP.net MVC4
2. Source Code:HTML Extension Helper method (Github)

The Major advantage of using this helper method is clean code and better readability. E.g.

@Html.CheckBoxListFor(model => model.SelectedItems, Model.AllItems)
Rohit
  • 6,365
  • 14
  • 59
  • 90