Load Menu & Sub Menu From Database in Blazor



1. Create a new Blazor Server Project : 

2. NavMenu.razor :

@using BlazorDynamicMenu.Data
@inject MenuService MenuService

<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Dynamic Menu & Sub Menu</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    @if (menuList == null)
    {
        <p><em>Loading....</em></p>
    }
    else
    {
        <ul class="nav flex-column">
            @foreach (var mn in menuList)
            {
                @if (mn.ParentMenuId == 0)
                {
                    <li class="nav-item px-3">
                        <NavLink class="nav-link" href="@mn.PageName" @onclick="()=>GetIsClicked(mn)">
                            <span class="@mn.IconName" aria-hidden="true"></span>@mn.MenuName
                        </NavLink>
                        <ul class="nav flex-column">
                            @foreach (var mn1 in menuList)
                            {
                                @if (mn.MenuId == mn1.ParentMenuId)
                                {
                                    @if (expandSubNav && mn.MenuId == clickedMenu)
                                    {
                                        <li class="nav-item px-3">
                                            <NavLink class="nav-link" href="@mn1.PageName" @onclick="()=>GetIsClicked(mn1)">
                                                <span class="@mn1.IconName" aria-hidden="true"></span>@mn1.MenuName
                                            </NavLink>
                                        </li>
                                    }
                                }
                            }
                        </ul>
                    </li>
                }
            }
        </ul>
    }
</div>

@code {
    private bool collapseNavMenu = true;
    private bool expandSubNav;
    private int clickedMenu = 0;
    private bool hasPageName = true;
    private int prevClickedMenu = 0;

    public IEnumerable<MenuInfo> menuList;

    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        if (hasPageName)
        {
            collapseNavMenu = !collapseNavMenu;
        }

    }

    public void GetIsClicked(MenuInfo mn)
    {
        clickedMenu = mn.MenuId;
        if (prevClickedMenu != clickedMenu)
        {
            expandSubNav = false;
            if (mn.PageName != "" || mn.MenuName == "Home")
            {
                hasPageName = true;
            }
            else
            {
                expandSubNav = !expandSubNav;
                hasPageName = false;
            }
        }
        else
        {
            expandSubNav = !expandSubNav;
        }

        prevClickedMenu = clickedMenu;
    }


    protected override async Task OnInitializedAsync()
    {
        menuList = await MenuService.GetMenuData();
    }
}



MenuService: (using Dapper)
        public async Task<IEnumerable<MenuInfo>> GetMenuData()
        {
            IEnumerable<MenuInfo> menuInfos;

            using (var conn= new SqlConnection(_configuration.Value))
            {
                const string query = @"Select * From MenuInfo";

                if (conn.State == ConnectionState.Closed)
                    conn.Open();
                try
                {
                    menuInfos = await conn.QueryAsync<MenuInfo>(query);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (conn.State == ConnectionState.Open)
                        conn.Close();
                }
            }
            return menuInfos;
        }


Data: Insert this data into MenuInfo Table:
menuList = new List<MenuInfo>()
        {
            new MenuInfo(){MenuId=1,ParentMenuId=0,PageName="",MenuName="Home",IconName="oi oi-home"},
            new MenuInfo(){MenuId=2,ParentMenuId=0,PageName="counter",MenuName="Counter",IconName="oi oi-plus"},
            new MenuInfo(){MenuId=3,ParentMenuId=0,PageName="fetchdata",MenuName="Fetch data",IconName="oi oi-list-rich"},
            new MenuInfo(){MenuId=4,ParentMenuId=2,PageName="child",MenuName="Sub Menu-1",IconName="oi oi-cart"},
            new MenuInfo(){MenuId=5,ParentMenuId=2,PageName="child/2",MenuName="Sub Menu-2",IconName="oi oi-cart"},
            new MenuInfo(){MenuId=6,ParentMenuId=3,PageName="child/3",MenuName="Sub Menu-1",IconName="oi oi-cart"}
        };
For Details please follow this video:
(Please Subscribe my Channel-AshProgHelp)
Load Menu & Sub Menu From Database in Blazor :
https://www.youtube.com/watch?v=aGn3oYAmj4w
How to use Sub Menu in Blazor:
https://www.youtube.com/watch?v=prz5kATC1Dg
Dapper CRUD in Blazor:

https://www.youtube.com/watch?v=nsZNCr7q4gE

Post a Comment

7 Comments

  1. there are a lot of issues with this code.

    ReplyDelete
  2. Tiene un defecto. Cuando se da clic a un nodo con sub-menús, esta va a Home, y luego expende. Para solucionarlo, cambias NavLink por a, y agregas onclick:preventDefault="(i.MenuId!=1)" en la primera, asumiendo que Home es el índice 1. (@__harveyt__)

    ReplyDelete
  3. how do i make sum-sub-menu in sub-menu in a menu in a sidebar????

    ReplyDelete
  4. Então utilizei a dica do ANONYMOUS e estou com uma tag a com evento onclick:preventDefault="(@item.pageName!='')" e funcionou!!!.

    ReplyDelete