This is a migrated thread and some comments may be shown as answers.

Treeview not displaying intended hierarchy from self referencing data source

7 Answers 748 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Matt
Top achievements
Rank 1
Matt asked on 20 Dec 2013, 06:28 PM
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;
                    }));

                  })
        
        )


7 Answers, 1 is accepted

Sort by
0
Accepted
Petur Subev
Telerik team
answered on 23 Dec 2013, 07:50 AM
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!
0
Matt
Top achievements
Rank 1
answered on 23 Dec 2013, 06:16 PM
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?
0
Petur Subev
Telerik team
answered on 24 Dec 2013, 08:53 AM
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!
0
Matt
Top achievements
Rank 1
answered on 24 Dec 2013, 05:20 PM
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!


0
Doug Hills
Top achievements
Rank 1
answered on 03 Feb 2015, 08:46 PM
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.
0
Joey
Top achievements
Rank 1
answered on 07 Sep 2016, 08:38 PM
Indeed it would. Was this solution ever provided?
0
Dimiter Topalov
Telerik team
answered on 10 Sep 2016, 07:54 AM
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.
Tags
TreeView
Asked by
Matt
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
Matt
Top achievements
Rank 1
Doug Hills
Top achievements
Rank 1
Joey
Top achievements
Rank 1
Dimiter Topalov
Telerik team
Share this question
or