Bind Kendo TreeView to Model of Groups & Users

6 posts, 0 answers
  1. Jorge
    Jorge avatar
    12 posts
    Member since:
    Jun 2013

    Posted 08 Nov 2014 Link to this post

    Hi, I'm trying to bind a Kendo treeview to a model of Users & Groups. A group contains a list of users and CAN contain a list of groups (and each group in turn can contain more users and more groups). I'd also like to be able to assign a node an icon depending on whether it's a user node or a group node. 

    The models:

    public class Group
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public int? ParentID { get; set; }
            public List<Group> Groups { get; set; }
            public List<User> Users { get; set; }
        }

        public class User
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public int GroupID { get; set; }
        }

    And here's  a method to get the data I want to bind to the treeview:
    private IEnumerable<Group> GetUserGroups()
            {
                List<Group> model = new List<Group>
                    {
                        new Group()
                        {
                            ID = 1,
                            Name = "Admin",
                            ParentID = 1,
                            Users = new List<User>()
                            {
                                new User()
                                {
                                    ID = 1,
                                    Name = "John Doe",
                                    GroupID = 1
                                },
                                new User()
                                {
                                    ID = 2,
                                    Name = "Jane Smith",
                                    GroupID = 1
                                },
                            },
                            Groups = new List<Group>
                            {
                                new Group()
                                {
                                    ID = 2,
                                    Name = "Support",
                                    ParentID = 1,
                                    Users = new List<User>()
                                    {
                                        new User()
                                        {
                                            ID = 1,
                                            Name = "Johnny Support",
                                            GroupID = 2
                                        }
                                    }
                                },
                                new Group()
                                {
                                    ID = 3,
                                    Name = "Production",
                                    ParentID = 1,
                                    Users = new List<User>()
                                    {
                                        new User()
                                        {
                                            ID = 1,
                                            Name = "Johnny Production",
                                            GroupID = 3
                                        }
                                    }
                                }
                            }
                        }
                    };
     
                return model;
            }

    When I try to do the below: 

    @(
            Html.Kendo().TreeView()
                .Name("treeview")
                .BindTo((IEnumerable<TreeViewItemModel>)ViewBag.inlineDefault)
        )

    I get a casting error  ... Unable to cast object of type 'System.Collections.Generic.List`1[MyApp.Models.Admin.Group]' to type 'System.Collections.Generic.IEnumerable`1[Kendo.Mvc.UI.TreeViewItemModel]'.

    Any help would be appreciated, thanks.

  2. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2500 posts

    Posted 10 Nov 2014 Link to this post

    Hello Jorge,

    See the local data binding TreeView example source -- it shows how to bind the TreeView to heterogeneous collections.

    Regards,
    Alex Gyoshev
    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. Jorge
    Jorge avatar
    12 posts
    Member since:
    Jun 2013

    Posted 10 Nov 2014 in reply to Alex Gyoshev Link to this post

    Hi Alex,

    I tried this approach as well. For example, 

    .BindTo((IEnumerable<Group>)ViewBag.Tree, (NavigationBindingFactory<TreeViewItem> mappings) =>
                                {
                                    mappings.For<Group>(binding => binding.ItemDataBound((item, category) =>
                                        {
                                            item.Text = category.Name;
                                        })
                                        .Children(category => category.Users));
                     
                                    mappings.For<User>(binding => binding.ItemDataBound((item, subCategory) =>
                                    {
                                        item.Text = subCategory.Name;
                                    }));
                                })

    However, this will return the first level group and it's users. So, based on the model in my original post ... the tree displays

    Admin
        John Doe
        Jane Smith

    How can I get the children groups (and their users) as well so that the tree looks like:

    +Admin (Group)
        John Doe (User)
        Jane Smith (User)
       +Support (Group)
            Johnny Support (User)
       +Production (Group)
            Johnny Production (User)
     
  5. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2500 posts

    Posted 11 Nov 2014 Link to this post

    Hello Jorge,

    You need to merge the children in one field, as the last code snippet shows (you cannot bind the children to both the Users and Groups fields). This requires that you have a base class or interface for both Groups and Users, such as:

        public abstract class Item
        {
               public int ID { get; set; }
            public string Name { get; set; }
        }

    ... and join the sub-items (Groups and Users) into one field, say IEnumerable<Item> Items. Thus the binding becomes:

    @(Html.Kendo().TreeView()
        .Name("TreeView")
        .BindTo((IEnumerable<Item>)ViewBag.TreeData, (Kendo.Mvc.UI.Fluent.NavigationBindingFactory<TreeViewItem> mappings) =>
        {
            mappings.For<Group>(binding => binding.ItemDataBound((item, category) =>
                {
                    item.Text = category.Name;
                })
                .Children(category => category.Items));

            mappings.For<User>(binding => binding.ItemDataBound((item, subCategory) =>
            {
                item.Text = subCategory.Name;
            }));
        })
    )

    I'm attaching the relevant model / controller / view files.

    Regards,
    Alex Gyoshev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. Jorge
    Jorge avatar
    12 posts
    Member since:
    Jun 2013

    Posted 11 Nov 2014 in reply to Alex Gyoshev Link to this post

    Thank you, Alex!

    I see the TreeView working correctly now. I have another question though, let's say I add or remove nodes from the tree, how can I post back the data to a controller and determine which node type (user or group) was added or deleted?
  7. Alex Gyoshev
    Admin
    Alex Gyoshev avatar
    2500 posts

    Posted 12 Nov 2014 Link to this post

    Hello Jorge,

    That depends on how you are sending the newly created nodes to the server. You can post new users and groups to different action methods in the controller, thus differentiating between the two.

    Regards,
    Alex Gyoshev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready