Edit this page

Expand Selected Nodes Asynchronously

The TreeView for ASP.NET MVC enables you to do Ajax binding by using Entity Framework and to asynchronously expand the selected nodes when loadOnDemand is set to true.

To see the complete implementation of the approach, refer to the GitHub project on asynchronously expanding the selected nodes of the TreeView in ASP.NET MVC applications.

Configuration

Create the Application

  1. Create a new ASP.NET MVC application. If you have installed the Telerik UI for ASP.NET MVC Visual Studio Extensions, create a Telerik UI for ASP.NET MVC application.

  2. If you decide not to use the Visual Studio extensions, follow the procedure for adding Telerik UI for ASP.NET MVC to existing applications:

Add the New Item

  1. In the Visual Studio solution explorer, right-click Models.
  2. Select Add > New Item.
  3. On the Add New Item dialog, select Data > ADO.NET Data Model.
  4. Provide the Northwind.edmx name to the model and click Next. As a result, the Entity Data Model Wizard starts.

Set the Entity Data Model

  1. Select Generate from database and click Next.
  2. Configure a connection to the Northwind database and click Next.

    Figure 1. A new entity model New entity data model

  3. Select all tables and click Finish.

Configure the New Action Method

  1. Open Controllers/HomeController.cs and add a new action method which will return JSON. Each time the user expands a parent node, the TreeView makes an Ajax request to this action method. The action method returns only the child nodes of the expanded parent node. The TreeView provides the unique identifier of the parent node or, when it makes the initial request, null.

        public JsonResult Employees_Read(int? id)
        {
            using (var northwind = new NORTHWNDEntities())
            {
                var employeesQuery = northwind.Employees.Select(c => new HierarchicalViewModel
                {
                    ID = c.EmployeeID,
                    Name = c.FirstName,
                    ParentID = null,
                    HasChildren = c.Orders.Any()
                })
                .Union(northwind.Orders.Select(c => new HierarchicalViewModel
                {
                    ID = c.OrderID,
                    Name = c.ShipAddress,
                    ParentID = c.EmployeeID,
                    HasChildren = c.Order_Details.Any()
                }))
                .Union(northwind.Order_Details.Select(c => new HierarchicalViewModel
                {
                    ID = c.OrderID,
                    Name = c.Product.ProductName,
                    ParentID = c.Order.OrderID,
                    HasChildren = false
                }));
    
                var result = employeesQuery.ToList()
                    .Where(x => id.HasValue ? x.ParentID == id : x.ParentID == null)
                    .Select(item => new {
                        id = item.ID,
                        Name = item.Name,
                        expanded = item.Expanded,
                        hasChildren = item.HasChildren
    
                    });
    
                return Json(result, JsonRequestBehavior.AllowGet);
            }
        }
    
  2. Open Views/Index.cshtml and add a TreeView.

        @(Html.Kendo().TreeView()
            .Name("treeview")
            .DataTextField("Name")
            .DataSource(dataSource => dataSource
                .Read(read => read
                    .Action("Employees_Read", "Home")
                )
            )
        )
    
  3. Add a button which will asynchronously load child nodes with the load() method in the child data source and, therefore, asynchronously expand the currently selected node.

    @(Html.Kendo().Button()
        .Name("expandNode")
        .Content("Expand selected node")
        .Events(e => e.Click("onExpandClick"))
    )
    
    <script>
        function onExpandClick(e) {
            var tree = $("#treeview").data("kendoTreeView"),
                selected = tree.select(),
                dataItem = tree.dataItem(selected);
    
            var load = function (item) {
                var that = this,
                    chain = $.Deferred().resolve();
    
                chain = chain.then(function () {
                    that.expand(that.findByUid(item.uid));
                    return item.load();
                }).then(function () {
                    if (item.hasChildren) {
                        var childrenChain = $.Deferred().resolve();
    
                        item.children.data().forEach(function (child) {
                            (function (child) {
                                childrenChain = childrenChain.then(function () {
                                    return load.bind(that)(child);
                                })
                            })(child)
                        })
    
                        return childrenChain;
                    }
                });
    
                return chain;
            }
    
            if (selected.length == 0) {
                alert("Select item first!");
                return;
            }
    
            load.bind(tree)(dataItem);
        }
    </script>
    
  4. Press CTRL+F5 to build and run the application. Select a node and click the Expand selected node button.

See Also