Blazor Page - Recursive menu

Viewed 262

I'm building a Blazor page (as a learning project) and want to create a dynamic menu based on user permissions.

My table layout is

MenuItemID | ItemName | ParentID

I would like to load the information from this table and dynamically create the menu. I'm using MudBlazor for the menu layout.

In the standard Winforms i'm comfortable how to recursively call a function, but i'm not sure how to do this within Blazor to dynamically generate the HTML.

I have a function written for finding the items

private List<MenuItem> GetChildItems(int ParentID)
{
    var foundItems = from m in menuItems
                     where m.ParentID == ParentID
                     select m;

    return foundItems.ToList();
}

My thoughts are my code within my page would start with something like:

@if (menuItems == null)
{
    <div class="spinner"></div>

}
else
{
    foreach (MenuItem p in GetChildItems(0))
    {
        List<MenuItem>
            children = GetChildItems(p.MenuItemID);
        if (children.Count > 0)
        {
            <MudNavGroup Title="@p.ItemName" Icon="@Icons.Material.Outlined.AssignmentInd" HideExpandIcon="true">
                @foreach (MenuItem c in children)
                {
                    <MudNavLink Href="pages/authentication/login" Icon="@Icons.Material.Outlined.InsertDriveFile">@c.ItemName</MudNavLink>
                }
            </MudNavGroup>
        }
        else
        {
            <MudNavLink Href="/FetchData" Match="NavLinkMatch.All" Icon="@Icons.Material.Outlined.Dashboard">@p.ItemName</MudNavLink>
        }
    }
}

What i'm not 100% sure on is how I can convert this to a recursive search?

Thanks Stephen

1 Answers
public class MenuItems 
{
  public int Id {get; set;} 
  public int? ParentId {get; set;}
  public string Title {get; set;}
  public bool IsOpened {get; se;}
}
//Your data will look like this, but you can extend the class up to have Icon property and StyleCss.
var itemList= new List<MenuItems> 
     {
        new MenuItems = (Id=1, Title="fruits", ParentId= null},
        new MenuItems = (Id=2, Title="apple", ParentId= 1},
        new MenuItems = (Id=3, Title="banana", ParentId= 1}
        new MenuItems = (Id=4, Title="mango", ParentId= 1}
        new MenuItems = (Id=5, Title="vegetables", ParentId= null}
        new MenuItems = (Id=6, Title="pepper", ParentId= 6}
        new MenuItems = (Id=7, Title="carrot", ParentId= 6}
    };

In blazor page, the Recursive should be like:

@foreach(var item in itemList.Where(i => i.ParentId == ParentId))
{
  <li style="cursor:pointer" @onclick="() => item.IsOpened = !item.IsOpened">
      @item.Name
      @if (item.IsOpened && itemList.Where(c => c.ParentId == item.Id).Any())
        {
          <ul>
           <RecursiveUI ParentId="item.Id" />
        </ul>
        }
  </li>

The question has been answered Here

Related