How to form multi level menus dynamically using kendo menu

12 posts, 1 answers
  1. Bspreethi
    Bspreethi avatar
    7 posts
    Member since:
    Mar 2012

    Posted 16 Jan 2013 Link to this post

    Hi,
    I'm having datasource as follows
    MenuID MenuName ParentMenuID
    1           Self             null
    2           Functional   null
    3           Leave          1
    4           Leave Application 3
    5           Delete Application 4

    I have formed kendo menu like,
    @model IEnumerable<ESSUserInterface.Models.Menus>
    <div>
        @(Html.Kendo().Menu()
                  .Name("menu")
            .Items(items =>
                {
                    foreach (var item in Model)
                    {
                        if (item.ParentMenuID == null)
                        {
                            items.Add()
                                .Text(item.MenuName)
                                .Items(children =>
                                {
                                    foreach (var subitem in Model)
                                    {
                                        if (subitem.ParentMenuID == item.MenuID)
                                        {
                                            children.Add().Text(subitem.MenuName)
                                                .Items(innerchildren =>
                                                {
                                                    foreach (var grandChilditem in Model)
                                                    {
                                                        if (grandChilditem.ParentMenuID == subitem.MenuID)
                                                        {
                                                            innerchildren.Add().Text(grandChilditem.MenuName);
                                                        }
                                                    }
                                                });
                                        }
                                    }
                                });
                        }
                    }
                })
                .Direction(MenuDirection.Right)
          )
    </div>

    But the above will work only with 3 levels, and menu ID 5 is not visible.
    How can i solve this? I have tried few for loops, and nthng worked still.
  2. Answer
    Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 18 Jan 2013 Link to this post

    Hi,

    The Menu supports binding to hierarchical data but the children should be included in the model. If the ParentMenuID is the only relation I can suggest to use recursion. Here is a sample that uses a recursive function defined in the view:

    @using Kendo.Mvc.UI.Fluent
    @functions{
        public void addChildren(MenuItemBuilder builder, Menus item, IEnumerable<Menus> items){
            var children = items.Where(m => m.ParentMenuID == item.MenuID);
            if (children != null)
            {
                builder.Items(menuItems =>
                    {
                        foreach (var child in children)
                        {
                            var menuItem = menuItems.Add().Text(child.MenuName);
                            addChildren(menuItem, child, items);
                        }
                    });
     
            }
        }
    }
     
    @(Html.Kendo().Menu()
        .Name("menu")
        .Items(menu => {
            foreach (var item in Model.Where(m=> m.ParentMenuID == null))
            {
                var builder = menu.Add().Text(item.MenuName);
                addChildren(builder, item, Model);
            }
        }))
    Regards,
    Daniel
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Bspreethi
    Bspreethi avatar
    7 posts
    Member since:
    Mar 2012

    Posted 23 Jan 2013 Link to this post

    Thanks Daniel. Saved my time.
  5. Kiran
    Kiran avatar
    13 posts
    Member since:
    Jul 2014

    Posted 30 Apr 2015 in reply to Daniel Link to this post

    how to bind custom route parameter runtime with Action propertiy. 

    Example:  RouteParameter  = " Status= False";

    Any example on this.

  6. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 04 May 2015 Link to this post

    Hello,

    I am not sure if I understand what you mean by "Action property". Could you clarify? If you are using the Action method then you can pass the route values after the action and controller names:
    menu.Add().Text(item.MenuName).Action("action", "controller", new { Status = false })


    Regards,
    Daniel
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  7. Kiran
    Kiran avatar
    13 posts
    Member since:
    Jul 2014

    Posted 04 May 2015 in reply to Daniel Link to this post

    Hi Daniel,

     

    Actually I have to bind those route parameters at runtime not at design time. 

    my code is :

    My parameters are like this:  child .RouteParameters ="status=false&stage=user&menuData=123";

    can you explain me how to achieve this.

     public void addChildren(MenuItemBuilder builder, IEnumerable<Model> children)
            {
                //var children = items; //.Where(m => m.MainMenuId == mainMenuId);
                if (children != null)
                {
                    builder.Items(menuItems =>
                        {
                            foreach (var child in children)
                            {
                                var menuItem = menuItems.Add().Text(child.SubMenu);
                                if (child.RouteComponentCode > 0 )
                                {
                                     
                                      
                                        menuItem.Action(child.RouteAction, child.RouteController, new { area = child.RouteArea, @status = child .RouteParameters});
                                }
                                addChildren(menuItem, Model.SubMenuModelEnumerable.Where(m => m.ParentId == child.SubMenuId));
                            }
                        });

                }
            }
        }

  8. Hemant
    Hemant avatar
    3 posts
    Member since:
    Apr 2015

    Posted 06 May 2015 in reply to Daniel Link to this post

    Daniel,

    Could you please post a sample of how to do this in the non-MVC-wrapper case? I am trying to build a simple Kendo Menu by reading data from the server via a rest url. I understand I can do this using the kendo.data.HierarchicalDataSource but cannot find a complete example anywhere.

    My json data coming from server would look something like this
    [{
    "text":"Web Sites","url":"",
    "children":
    [{"text":"Google","url":"www.google.com","children":null},{"text":"Yahoo","url":"www.yahoo.com","children":null}]
    }]

        

  9. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 07 May 2015 Link to this post

    Hi,

    @Kiran

    If you have the route values as string then you could parse it and set the resulting dictionary to the Action method:
    foreach (var child in children)
    {
        var menuItem = menuItems.Add().Text(child.SubMenu);
        if (child.RouteComponentCode > 0 )
        {        
            var queryString = HttpUtility.ParseQueryString(child.RouteParameters);
            var routeValues = new RouteValueDictionary();
            foreach (string key in queryString)
            {
                routeValues[key] = queryString[key];
            }
            routeValues["area"] = child.RouteArea;
            menuItem.Action(child.RouteAction, child.RouteController, routeValues);
        }
    }


    @Hemant

    The menu supports initialization from data when using the JavaScript initialization however the name of the children field should be items:
    <ul id="menu"></ul>
    <script>
      $("#menu").kendoMenu({
        dataSource: [{
          "text":"Web Sites","url":"",
          "items": [{
            "text":"Google",
            "url":"www.google.com",
            "items":null
          }, {
            "text":"Yahoo",
            "url":"www.yahoo.com",
            "items":null
          }]
        }]
      });
    </script>



    Regards,
    Daniel
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  10. Kiran
    Kiran avatar
    13 posts
    Member since:
    Jul 2014

    Posted 07 May 2015 in reply to Daniel Link to this post

    Hi Daniel,

    Thank you for the sample, but I am looking how can use the encrypted route action parameters when I click on menu link?

    any sample on this: use encryption parameter route values and redirect them to proper view in secure way?

    Thanks,

    Kiran

  11. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 11 May 2015 Link to this post

    Hello Kiran,

    The menu does not provide any utilities for encrypting the parameters. This should be done the same way as in any other case.

    Regards,
    Daniel
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  12. Kiran
    Kiran avatar
    13 posts
    Member since:
    Jul 2014

    Posted 30 May 2015 in reply to Daniel Link to this post

    This way working fine to load dynamic menu, but it is a performance hit on every time when we load master layouts, is there any other things need to care to control the performance?

    Thanks,

    Kiran

  13. Georgi Krustev
    Admin
    Georgi Krustev avatar
    3706 posts

    Posted 03 Jun 2015 Link to this post

    Hello Kiran,

    Probably, you are observing the non-cached security trimming functionality in action. Could you try to run the site in release mode and see whether performance issue is still observable? More details can be found here:
    Regards,
    Georgi Krustev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready