I have a nested data object for a set of items within categories. Each category can contain sub categories and there is no set limit to the depth of sub categories. (A file
Create your own HtmlHelper extension method like so:
namespace System.Web.Mvc
{
public static class HtmlHelperExtensions
{
public static string CategoryTree(this HtmlHelper html, IEnumerable<Category> categories)
{
string htmlOutput = string.Empty;
if (categories.Count() > 0)
{
htmlOutput += "<ul>";
foreach (Category category in Categories)
{
htmlOutput += "<li>";
htmlOutput += category.Name;
htmlOutput += html.CategoryTree(category.Categories);
htmlOutput += "</li>";
}
htmlOutput += "</ul>";
}
return htmlOutput;
}
}
}
Funny you should ask because I actually created one of these just yesterday.
You could easily do it by having each <ul>
list in a PartialView
, and for each new list you need to start you just call Html.RenderPartial("myPartialName");
.
So the Category
PartialView could look like this:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Category>>" %>
<% foreach(Category cat in ViewData.Model) { %>
<li><p><%= cat.name %></p>
<% if (cat.categories.Count > 0) {
Html.RenderPartial("Category", cat.Categories);
} %></li>
<% } %>
In your View, you simply send the "root" collection as the model for the partial view:
<% Html.RenderPartial("Category", ViewData.Model) %>
EDIT:
Html.RenderPartial()
call - of course the category has to be passed as the model.You can use helper methods.
@model Models.CategoryModel
@helper TreeView(List<Models.CategoryModel> categoryTree)
{
foreach (var item in categoryTree)
{
<li>
@if (item.HasChild)
{
<span>@item.CategoryName</span>
<ul>
@TreeView(item.ChildCategories)
</ul>
}
else
{
<span class="leaf @item.CategoryTreeNodeType.ToString()" id="@item._CategoryId">@item.CategoryName</span>
}
</li>
}
}
<ul id="categorytree">
<li>@Model.CategoryName
@TreeView(Model.ChildCategories)
</li>
</ul>
More info can be found on this link: http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx
You can reuse html parts with lambdas
Example
public class Category
{
public int id;
public string name;
public IEnumerable categories;
}
<%
Action<IEnumerable<Category>> categoriesMacros = null;
categoriesMacros = categories => { %>
<ul>
<% foreach(var c in categories) { %>
<li> <%= Html.Encode(c.name)%> </li>
<% if (c.categories != null && c.categories.Count() > 0) categoriesMacros(c.categories); %>
<% } %>
</ul>
<% }; %>
<% var categpries = (IEnumerable<Category>)ViewData["categories"]; %>
<% categoriesMacros(categpries); %>