Search code examples
sortingasp.net-corenavigationaspnetboilerplate

MenuItemDefinition Order


I'm getting started with ASP.NET Boilerplate where I am using the free start-up template of ASP.NET Core Multi Page Web Application.

My question is regarding the left hand navigation bar. I have the NavigationProvider in my project where the abstract class is implemented. I have been testing out some of the properties available in the MenuItemDefinition, specifically the order and isVisible. My expectation was that I could set both the order and isVisible properties and that this would show in the application when running. I don't however see any of these properties actually being used to either set the order of the menu items or control their visibility.

For the order property I updated the Default.cshtml of the SideBarNav component to implement an OrderBy so I can get the correct order. This works but I'm not sure if this is the recommended approach.

Is it correct that setting the order when adding a MenuItemDefinition doesn't actually have any consequence to the running application and that this property is here with the expectation that I implement the behavior as I've done in the Default.cshtml?

My reason for wanting to control the order this way rather than by just the order the items are added is related to creating different modules that each have their own NavigationProviders.


Solution

  • Is it correct that setting the order when adding a MenuItemDefinition doesn't actually have any consequence to the running application and that this property is here with the expectation that I implement the behavior as I've done in the Default.cshtml?

    Yes, the templates (as of v5.2.0) do not use nor implement ordering of user menu items.

    I suggest implementing an extension method to easily change the ordering across the project.

    public static IOrderedEnumerable<UserMenuItem> OrderByCustom(this IEnumerable<UserMenuItem> menuItems)
    {
        return menuItems
            .OrderBy(menuItem => menuItem.Order)
            .ThenBy(menuItem => menuItem.DisplayName);
    }
    

    Regarding versions: You are using v5.1.x and below. As of v5.2.0, the template has been migrated to use AdminLTE 3 instead of AdminBSB for the MVC UI, so the following changes are incompatible.

    v5.2+

    I have submitted a PR to implement the ordering: aspnetboilerplate/module-zero-core-template#510

    var orderedMenuItems = Model.MainMenu.Items.Where(x => x.IsVisible).OrderByCustom().ToList();
    
    var subMenus = Model.Items.Where(x => x.IsVisible).OrderByCustom().ToList();
    

    Files changed:

    • Web.Mvc/Views/Shared/Components/SideBarMenu/Default.cshtml
    • Web.Mvc/Views/Shared/Components/SideBarMenu/_MenuItem.cshtml

    v5.1.x and below

    Note that you should change in 3 places (corresponding to 3 nesting levels) in Default.cshtml.

    @foreach (var menuItem in Model.MainMenu.Items.OrderByCustom().ToList())
    
    @foreach (var subMenuItem in menuItem.Items.OrderByCustom().ToList())
    
    @foreach (var subSubMenuItem in subMenuItem.Items.OrderByCustom().ToList())
    

    File changed:

    • Web.Mvc/Views/Shared/Components/SideBarNav/Default.cshtml