In this article, Ed Charbeneau walks you through one of the newest (and most-requested) controls we've introduced for ASP.NET MVC and ASP.NET Core developers: the DropDownTree!
With the R2 2018 release came the top-most voted feedback item to our list of UI components, the DropDownTree for ASP.NET MVC and the DropDownTree for ASP.NET Core. The DropDownTree is a TreeList component embedded inside a ComboBox. This bit of UI makes for easy selection of hierarchical values in a small footprint. Included in the update is the option for ASP.NET Core Tag Helpers, an HTML like syntax for declaring UI elements. In addition, the DropDownTree features easy to use enhancements, on demand loading, and client-side filtering. In this article we'll discuss how to use the DropDownTree in several scenarios and which features best fit your application.
As of the R2 2018 release, Telerik UI for ASP.NET Core supports Tag Helpers for every UI component available including the new DropDownTree. ASP.NET Core Tag Helpers work similarly to Razor HTML Helpers with some added benefits. While both Tag Helpers and HTML Helpers produce the same output there are key differences in how the two are expressed. Tag Helpers utilize HTML like “tags” and “attributes” which provide a syntax that requires less context-switching (from HTML to C#).
The following example uses an HTML helper to initialize a DropDownTree component. The properties chain from the DropDownTree()
method and set the data-source, describe the model, and enable features.
<!-- Html Helper -->
@(Html.Kendo().DropDownTree()
.Name("dropdowntree")
.DataTextField("Name")
.HtmlAttributes(new { style = "width:300px" })
.DataSource(dataSource => dataSource
.Model(model => model
.Id("EmployeeID")
.HasChildren("HasChildren")
)
.Read(read => read
// The action method which will return JSON
.Action("Employees_Read", "Home")
)
)
)
Expressing the same component using a Tag Helper produces a syntax that closely resembles HTML. Instead of using methods to set properties, the Tag Helper uses attributes.
<!-- Tag Helpler -->
<kendo-dropdowntree name="dropdowntree1" datatextfield="Name" placeholder="Employee name" style="width:300px">
<hierarchical-datasource>
<transport>
<!-- The action method which will return JSON -->
<read url="@Url.Action("Employees_Read", "Home")" datatype="json" />
</transport>
<schema type="json">
<hierarchical-model id="EmployeeID" has-children="HasChildren">
</hierarchical-model>
</schema>
</hierarchical-datasource>
</kendo-dropdowntree>
Developers get great IntelliSense support with both HTML Helpers and Tag Helpers. However, when using Tag Helpers, developers benefit from IntelliSense for standard HTML and CSS as well. This was often lost with HTML helpers as standard HTML and CSS needed to be defined with C# anonymous types.
When working with large hierarchical data sets, performance is often a concern. Fetching large hierarchical data sets from the server could be a potential performance bottleneck in terms of both database and network traffic. The DropDownTree has built-in feature to compensate for this scenario. By enabling the Load On Demand, the DropDownTree will only load data for visible nodes within the DropDownTree's view.
In the following example we'll see how the DropDownTree behaves with and without On Demand loading.
On the server-side, we'll use a controller action Employees_Read
to return a list of Employees as JSON data. If the parameter employeeId
is passed to the method, it will return a list of employees that are child records of the corresponding employeeId
. If no employeeId
is supplied, the root node is returned.
public JsonResult Employees_Read(int? employeeId)
{
// Get employees who report to employeeId (null for root nodes)
var employees = db.Employees.Where(employee => employeeId.HasValue ? employee.ReportsTo == employeeId : employee.ReportsTo == null);
// Project the results
var result = employees.Select(employee => new
{
EmployeeID = employee.EmployeeId,
Name = employee.FullName,
HasChildren = employee.Employees.Any()
}).ToList();
return Json(result);
}
On the client-side of the application we'll setup a DropDownTree with on demand loading disabled, this is the default behavior for the DropDownTree.
<kendo-dropdowntree name="dropdowntree1" datatextfield="Name" placeholder="Employee name" style="width:300px">
<hierarchical-datasource>
<transport>
<!-- The action method which will return JSON -->
<read url="@Url.Action("Employees_Read", "Home")" datatype="json" />
</transport>
<schema type="json">
<hierarchical-model id="EmployeeID" has-children="HasChildren">
</hierarchical-model>
</schema>
</hierarchical-datasource>
</kendo-dropdowntree>
On the initial call, employeeId
will be null, thus Employees_Read
will get the root node for the tree. As each Tree node is bound to the data-source an additional call is made to the Employees_Read
for each record that has child nodes. Even though the DropDownTree nodes have not been expanded, the data is fetched.
We can see the calls being made within the browser's console.
By adding the load-on-demand
property to the DropDownTree and setting the value to true
we can modify the behavior so it only fetches data as needed.
<kendo-dropdowntree ... load-on-demand="true">
As before, the initial call to employeeId
will be null fetching the root node for the tree. However, the DropDownTree will not fetch child nodes until the user expands a tree node.
Inspecting the network traffic in the browser's console shows that each node is loaded only when the user needs the data.
Performance improvements when using “load on demand” will depend on the number of nodes within the data set and its size. With this approach unnecessary database calls and network requests are avoided.
Allowing users to quickly find data in a list is a common UI pattern in combo boxes. Enabling users to search within a given data set provides a fast and efficient means to selecting the desired item. With the DropDownTree, client-side filtering can be enabled with multiple search patterns: Contains
, StartsWith
, or EndsWith
. Selecting any of these three search options prompts the user with filter input which is capable of traversing the entire tree and displaying only items that match the query.
To enable client-side filtering, the filter property is set to one of aforementioned FilterTypes
.
<kendo-dropdowntree ... filter="FilterType.Contains">
When a user filters a DropDownTree matching items are shown while parent items remain visible in the view. By keeping parent items visible, the filtered items remain in context to their relationship. The simplicity of search and subtitle details like maintaining the parent-child relationship are what make an elegant user experience.
While Tag Helpers, Load On Demand, and Client-Side filtering are some of the top reasons to check out the new DropDownTree, there's still many more features worth checking out. Like many components in the UI for ASP.NET Core, the DropDownTree offers keyboard navigation for out-of-the-box accessibility, localization support, custom templates, themes and much more.
If you're not currently using Telerik UI for ASP.NET Core in your .NET apps, then start a 30 day free trial and see what they have to offer.
Ed