4

So my problem goes like this,

I have two lists

LIST A contains.

  1. Item 1
  2. Item 2
  3. Item 3
  4. Item 4
  5. Item 5

And List B Contains

  1. Item 1
  2. Item 2
  3. Item 3
  4. Item 4
  5. .....
  6. ....
  7. Item 10

All i want to do is Generate Checkboxes dynamically in MVC Razor View for all the items in B, and of those checkboxes, check(select) all the checkboxes for all the items in A. As A will always be a subset of B.

And then a user can check-uncheck any boxes, and those values can be passed to controller for Saving purposes. The List A will be updated with new values, that user selects.

Any Help ?

UPDATE 1: I am able to get all the items in Model.CheckboxSelections in view. I don't want to use a partial view. I am trying something like following, but something is still missing.

         @for (int i = 0; i < Model.CheckboxSelections.Count; i++)
        {
@Html.CheckBox(Model.CheckboxSelections[i].Sku.ToString(), Model.CheckboxSelections[i].IsChecked.ToString())
     }
Nanu
  • 3,010
  • 10
  • 38
  • 52
  • [MVC Add Checkbox Dynamically](http://stackoverflow.com/questions/5433079/asp-net-mvc-add-checkbox-dynamically) and [How to create controls dynamically in MVC 3](http://stackoverflow.com/questions/6329461/how-to-create-controls-dynamically-in-mvc-3-based-on-an-xml-file) – Joshua Drake May 09 '12 at 13:44

1 Answers1

12

With a certain risk of repeating myself I would start my answer with the following sentence:

As always in ASP.NET MVC application you should use a view model.

So:

public class MyViewModel
{
    public string Name { get; set; }
    public bool IsChecked { get; set; }
}

then a controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // Those are your domain models
        // they could come from a database or something
        var listA = new[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
        var listB = new[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10" };

        // Now let's map our domain model to our view model
        var model = listB.Select(x => new MyViewModel
        {
            Name = x,
            IsChecked = listA.Contains(x)
        });

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(IEnumerable<MyViewModel> model)
    {
        var selectedItems = model.Where(x => x.IsChecked);
        var format = string.Join(",", selectedItems.Select(x => x.Name));
        return Content("Thank you for selecting " + format);
    }
}

then a corresponding view (~/Views/Home/Index.cshtml):

@model IEnumerable<MyViewModel>

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <button type="submit">OK</button>
}

and finally the corresponding editor template which will be automatically rendered for each element of the model collection (~/Views/Home/EditorTemplates/MyViewModel.cshtml):

@model MyViewModel

<div>
    @Html.HiddenFor(x => x.Name)
    @Html.LabelFor(x => x.IsChecked, Model.Name)
    @Html.CheckBoxFor(x => x.IsChecked)
</div>

and the rendered result (as seen by my Chrome browser) looks like this:

enter image description here

See how easy it is when you use view models?

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks as you advised, i created a class for the item and then generated a list of these items and now i am passing it in a mail model. All my items are now inside (Model.CheckboxSelections), and i am trying to do something like this, but not working. – Nanu May 09 '12 at 20:06
  • @for (int i = 0; i < Model.CheckboxSelections.Count; i++) { @Html.CheckBox(Model.CheckboxSelections[i].Sku.ToString(), Model.CheckboxSelections[i].IsChecked.ToString()) } – Nanu May 09 '12 at 20:09
  • That's not what I advised. In my answer I recommended using editor templates instead of writing loops in the view. – Darin Dimitrov May 09 '12 at 21:27
  • Aren't for loops faster, than rendering a partial view ? – Nanu May 10 '12 at 14:52
  • 2
    You shouldn't be concerned with that. In Release mode views are cached. – Darin Dimitrov May 10 '12 at 15:30