Creating submenu in MVC

Mananu Gunawardana asked on October 2, 2018 03:36

Hi, Any suggestion on how to create submenu items in Kentico 11? We're using the MVC development approach and has created the main menu items as in here. We would like to have menu items below each main menu item.

Correct Answer

Andriy B answered on October 5, 2018 11:25

You can make a few changes:

  1. Add attitional attibute into MenuItemViewModel to store Children:

    // children
    public IEnumerable<MenuItemViewModel> Children { get; set; }
    
  2. Add a new method GetMenuChildren() to generate a tree of MenuItemViewModel items instead of list.

    private IEnumerable<MenuItemViewModel> GetMenuChildren(IEnumerable<MenuItem> menuItems, int itemParentId, MultiDocumentQuery pages, int menuDepth = 0, int menuLevel = 0)
    {
        var items = menuItems
            .Where(x => x.NodeParentID == itemParentId)
            .Select(item => new MenuItemViewModel()
            {
                Children = GetMenuChildren(menuItems, item.NodeID, pages, menuDepth, menuLevel + 1),
                MenuItemText = item.MenuItemText,
                // Gets the URL for the page whose GUID matches the given menu item's selected page
                MenuItemRelativeUrl = pages.FirstOrDefault(page => page.NodeGUID == item.MenuItemPage).RelativeURL
            });
    
        return items;
    }
    
  3. Call GetMenuChildren() method from GetMenu() method to get a menu model:

    public virtual ActionResult GetMenu()
    {
        // Loads all menu items using the page type's generated provider
        // Uses the menu item order from the content tree in the Kentico 'Pages' application
        var menuItems = MenuItemProvider.GetMenuItems()
            .Columns("NodeID", "NodeParentID", "MenuItemText", "MenuItemPage")
            .OrderBy("NodeOrder")
            .ToList();
    
        // Loads the pages selected within the menu items
        // The data only contains values of the NodeGUID identifier column
        var pages = DocumentHelper.GetDocuments()
            .WhereIn("NodeGUID", menuItems.Select(item => item.MenuItemPage).ToList())
            .Columns("NodeGUID");
    
        // Get Navigation Menu Root Item - should be the one
        var menuItemsRoot = MenuItemsProvider.GetMenuItems().First();
    
        // Creates a collection of view models based on the menu item and page data
        var model = GetMenuChildren(menuItems, menuItemsRoot.NodeID, pages, 0);
    
        return PartialView(MVCConsts.Menu.Views.ViewNames._SiteMenu, model);
    }
    

Note: MenuItemsProvider (additional MenuItems Page Type added) is required to get the root item id.

0 votesVote for this answer Unmark Correct answer

Recent Answers


Andriy B answered on October 5, 2018 11:22 (last edited on October 5, 2018 13:04)

.

0 votesVote for this answer Mark as a Correct answer

Andriy B answered on October 5, 2018 11:24 (last edited on October 5, 2018 13:04)

.

0 votesVote for this answer Mark as a Correct answer

Petline developer answered on May 16, 2019 17:16 (last edited on June 14, 2019 22:09)

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.