xSea xSea - 1 month ago 11
C# Question

How to create a dynamic checkboxlist group in C# MVC?

How do I create a dynamic checkboxlist groups in C# MVC Razor View as shown in the picture below.

Let say the group category is CO2 and there are sub-items below it which example shown test and test2.

looks ok with my current code but how do i do the sub-items in it?

enter image description here

This is my Current Code for Model

public class Sites
{
public int SiteId { get; set; }

public string SiteName { get; set; }

public bool IsCheck { get; set; }
}

public class SiteList
{
public List<Sites> sites { get; set; }
}


Controller

public ActionResult sitechecklist()
{
List<Sites> site = new List<Sites>();
site.Add(new Sites() { SiteId = 1, SiteName = "CO2", IsCheck = false });
site.Add(new Sites() { SiteId = 2, SiteName = "CO3", IsCheck = false });
site.Add(new Sites() { SiteId = 3, SiteName = "IO", IsCheck = false });
site.Add(new Sites() { SiteId = 4, SiteName = "NCC01", IsCheck = false });
SiteList sList = new SiteList();
sList.sites = site;
return View(sList);
}


my View

<ul>
@for (int i = 0; i < Model.sites.Count; i++)
{
<li>
@Html.CheckBoxFor(m=>Model.sites[i].IsCheck)
@Model.sites[i].SiteName
@Html.HiddenFor(m=>Model.sites[i].SiteId)
@Html.HiddenFor(m=>Model.sites[i].SiteName)
</li>
}
</ul>

Answer

Firstly, you model requires an additional collection property for the sub-items. It could be public List<Sites> Rooms { get; set; } or you might have another class (say) Rooms with similar properties

public class Room
{
    public int RoomId { get; set; }
    public string RoomName { get; set; }
    public bool IsCheck { get; set; }
}

and the Sites model will be

public class Site // should be singular, not plural - its describes one object
{
    public int SiteId { get; set; }
    public string SiteName { get; set; }
    public bool IsCheck { get; set; }
    public List<Room> Rooms { get; set; }
}

which would then be populated in the GET method using, for example

site.Add(new Site()
{
    SiteId = 1,
    SiteName = "CO2",
    Rooms = new List<Room>()
    {
        new Room() { RoomId = 1, RoomName = "Test" },
        new Room() { RoomId = 2, RoomName = "Test 2"},
    }
});

Then in the view, you need to use nested for loops

@for (int i = 0; i < Model.sites.Count; i++)
{
    // Generate the sites
    @Html.CheckBoxFor(m => m.sites[i].IsCheck)
    // @Model.sites[i].SiteName
    @Html.LabelFor(m => m.sites[i].IsCheck, Model.sites[i].SiteName)
    @Html.HiddenFor(m => m.sites[i].SiteId)
    @Html.HiddenFor(m => m.sites[i].SiteName)
    // Generate the rooms for each site
    @for(int j = 0; j < Model.sites[i].Rooms.Count; j++)
    {
        @Html.CheckBoxFor(m => m.sites[i].Rooms[j].IsCheck)
        @Html.LabelFor(m => m.sites[i].Rooms[j].IsCheck, Model.sites[i].Rooms[j].RoomName)
        @Html.HiddenFor(m => m.sites[i].Rooms[j].RoomId)
        @Html.HiddenFor(m => m.sites[i].Rooms[j].RoomName)
    }
}

Side note: I suspect you will also want some javascript to handle the outer checkboxes (if a Site is checked, then all its associated Room's should also be checked and vice versa).