Treeview not displaying intended hierarchy from self referencing data source

8 posts, 1 answers
  1. Matt
    Matt avatar
    3 posts
    Member since:
    Nov 2012

    Posted 20 Dec 2013 Link to this post

    I am trying to bind my kendo treeview to a sql self referencing table that stores the data needed to represent a multi-level hierarchy of treeview items. I am attaching a picture of my sql table as well as a screen shot of how my treeview is currently displaying this data, and certain items are being duplicated, and I can't determine why. Below is the code for my controller and view.  Pretty sure my table structure is correct, but I'm thinking the query is adding the children nodes a 2nd time but as parent items, so maybe the controller needs to filter out the items that don't have null as the parent ID as it's binding the parent nodes... If anyone can help I'd be very grateful!!!

    Controller
        public class NavigationMenuItemController : Controller
        {
            private symphonyappEntities db = new symphonyappEntities();

            // GET: /NavigationMenuItem/
            public ActionResult Index()
            {
                var navigationmenuitems = db.NavigationMenuItems.Include(n => n.NavigationMenuItem1).Include(n => n.NavigationMenu);
                return PartialView("~/Views/Shared/_NavigationBarPartial.cshtml", navigationmenuitems);
            }

            [ChildActionOnly]
            public ActionResult NavBarPartial()
            {
                var navigationmenuitems =
                    db.NavigationMenuItems.Include(n => n.NavigationMenuItem1).Include(n => n.NavigationMenu);
                return PartialView("~/Views/Shared/_NavigationBarPartial.cshtml", navigationmenuitems);
            }
    }

    View
            @(Html.Kendo().TreeView()
                      .Name("treeview")
                      .HtmlAttributes(new { style = "width:200px;" })
                      .Events(events => events
                    .Select("onSelect"))
                .BindTo(Model, mappings =>
                      {
                    mappings.For<NavigationMenuItem>(binding => binding
                        .ItemDataBound((item, menuItem) =>
                              {
                            item.Text = menuItem.MenuItemText;
                            item.Id = menuItem.MenuItemURL;
                        })

                        .Children(menuItem => menuItem.NavigationMenuItems1));

                mappings.For<NavigationMenuItem>(binding => binding
                        .ItemDataBound((item, submenuitem) =>
                                      {
                            item.Text = submenuitem.MenuItemText;
                            item.Id = submenuitem.MenuItemURL;
                        }));

                      })
            
            )


  2. Answer
    Matt
    Matt avatar
    3 posts
    Member since:
    Nov 2012

    Posted 23 Dec 2013 Link to this post

    Hello Matt,

    Actually what you shared is something that we already demonstrated in the following demo:

    http://demos.kendoui.com/web/treeview/remote-data.html

    However in your case you are using initial binding via the BindTo method.

    Basically the only thing that I doubt is that you have declared same mapping two times:

    mappings.For<NavigationMenuItem>(binding => binding
                        .ItemDataBound((item, menuItem) =>
                              {
                            item.Text = menuItem.MenuItemText;
                            item.Id = menuItem.MenuItemURL;
                        })
     
                        .Children(menuItem => menuItem.NavigationMenuItems1));
     
                mappings.For<NavigationMenuItem>(binding => binding
                        .ItemDataBound((item, submenuitem) =>
                                      {
                            item.Text = submenuitem.MenuItemText;
                            item.Id = submenuitem.MenuItemURL;
                        }));

    Since the hierarchy is self-referencing you do not need to second declaration, the first one will be used.

    Please if still struggling demonstrate your case with a small demo so we can troubleshoot the case.

    Kind Regards,
    Petur Subev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
  4. Matt
    Matt avatar
    3 posts
    Member since:
    Nov 2012

    Posted 23 Dec 2013 Link to this post

    Thank you for the quick reply. I removed that section and this is what my treeview is displaying now. It is understanding the hierarchy,  but it is repeating children and grandchildren nodes on the root of the tree.... here is what is being displayed now. What am I doing wrong?
  5. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 24 Dec 2013 Link to this post

    Hello Matt,

    This is weird, we will need a project that demonstrates what you experience. Thank you for the cooperation and the understanding.

    Kind Regards,
    Petur Subev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Matt
    Matt avatar
    3 posts
    Member since:
    Nov 2012

    Posted 24 Dec 2013 Link to this post

    Aha your solution worked perfectly! 

    The reason it appeared not to work was my model was not returning the data the way I needed it.  I think the entity model was doing the wrong join so it was duplicating some records but the duplicate would have a null for the parent menu id while the original record displayed the parent menu id I saved for that record. That's what put into the correct grandchild node while it also incorrectly stuck it into the root. I corrected the sql join and removed the section of the view you told me to and presto it works!

    Thanks!


  7. Doug Hills
    Doug Hills avatar
    3 posts
    Member since:
    Aug 2004

    Posted 03 Feb 2015 in reply to Matt Link to this post

    There is an important point missed by Matt's response: It is possible to have a flat self-referencing dataset. The advantage of this is that a complete hierarchical dataset can be returned in a single call. An example of such dataset is:
    var nodes = [
    {"node_key": "priority_id", "parent_node_key": "", "node_text": "Priority", "has_children": "1", "nodeId": "1"},
    {"node_key": "priority_id:1", "parent_node_key": "priority_id", "node_text": "A", "has_children": "0", "nodeId": "2"},
    {"node_key": "priority_id:2", "parent_node_key": "priority_id", "node_text": "B", "has_children": "0", "nodeId": "3"},
    {"node_key": "priority_id:3", "parent_node_key": "priority_id", "node_text": "C", "has_children": "0", "nodeId": "4"},
    {"node_key": "status_id", "parent_node_key": "", "node_text": "Status", "has_children": "1", "nodeId": "5"},
    {"node_key": "status_id:1", "parent_node_key": "status_id", "node_text": "Open", "has_children": "0", "nodeId": "6"},
    {"node_key": "status_id:2", "parent_node_key": "status_id", "node_text": "Pending", "has_children": "0", "nodeId": "7"},
    {"node_key": "status_id:7", "parent_node_key": "status_id", "node_text": "Finished", "has_children": "0", "nodeId": "8"},
    {"node_key": "status_id:8", "parent_node_key": "status_id", "node_text": "Closed", "has_children": "0", "nodeId": "9"},
    {"node_key": "status_id:9", "parent_node_key": "status_id", "node_text": "Defective", "has_children": "0", "nodeId": "10"},
    {"node_key": "status_id:10", "parent_node_key": "status_id", "node_text": "Not Visited", "has_children": "0", "nodeId": "11"},
    {"node_key": "status_id:11", "parent_node_key": "status_id", "node_text": "NDF", "has_children": "0", "nodeId": "12"},
    {"node_key": "status_id:12", "parent_node_key": "status_id", "node_text": "Info", "has_children": "0", "nodeId": "13"},
    {"node_key": "status_id:13", "parent_node_key": "status_id", "node_text": "Disagree", "has_children": "0", "nodeId": "14"}
    ];

    It would be fabulous to be able to tell a treeview that his dataset is 'nodes', his ID field is 'node_key', his parent field is 'parent_node_key'. The control should be able to consume such a rowset and render appopriately. It currently does not.


    An excellent alternative would be to allow a hierarchical dataset to be defined with such a flat row-set. The hierarchical dataset already has provisions for reckoning parent-child relationships. It just doesn't seem to want to honor those in a self-referencing flat set.
  8. Joey
    Joey avatar
    4 posts
    Member since:
    Aug 2016

    Posted 07 Sep in reply to Doug Hills Link to this post

    Indeed it would. Was this solution ever provided?
  9. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    356 posts

    Posted 10 Sep Link to this post

    Hi Joey,

    The Kendo UI TreeView does not support the desired functionality, and there are no planned efforts in this direction.

    Please check out the following documentation article that illustrates how flat data can be converted to hierarchical one, so that the TreeView can be bound to it:

    http://docs.telerik.com/kendo-ui/controls/navigation/treeview/binding-to-flat-data

    Alternatively you can consider using the Kendo UI TreeList that supports similar to the desired behavior:

    http://docs.telerik.com/kendo-ui/controls/data-management/treelist/overview

    http://demos.telerik.com/kendo-ui/treelist/index

    http://docs.telerik.com/kendo-ui/api/javascript/ui/treelist

    I hope this helps.

    Regards,
    Dimiter Topalov
    Telerik by Progress
    Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
Back to Top
Kendo UI is VS 2017 Ready