Telerik blogs

When you have a lot to display in a dropdown list, you need the Kendo UI for Angular dropdown treeview to organize your data. In addition to letting you get the UI you want, it handles a variety of complex data structures.

The value in using dropdown lists in your UI is obvious: They prevent the user from entering invalid data. Instead of entering data, the user selects from a list of valid options (that doesn’t, of course, stop the user from picking the wrong option—but it does ensure that the user’s selection is, at least, valid).

From a productivity point of view, though, dropdown lists are only useful if they allow the user to select an option quickly. Obviously, as lists get longer, finding options takes longer and longer.

Searchable dropdown lists (i.e., comboboxes) help here but only, of course, if the user knows how to spell the option correctly. Users may not, for example, find the “taxi” item in a list if they’re looking for the “cab” item—we’re back to letting the user enter invalid data.

The dropdowns available with Kendo UI for Angular provide a solution for this by allowing you to group options in the list under headings … the only problem being, of course, that since all the headings and all the items are always displayed, the dropdown list actually gets longer.

The DropDownTree and MultiSelectTree provide an alternative way to handle lists by organizing the lists into a hierarchical treeview—users can open or close the node on the treeview that they need and scan a short list of options under that node to find the option they want. The only difference between the two dropdowns is that DropDownTree lets the user select a single item:

A dropdown list with its list open. The list is organized into a treeview with three heading nodes labeled Marketing, Executive, and Accounting. The Executive node is expanded showing an item nested underneath it labeled Andrew Fuller. That item is highlighted in red and Andrew Fuller also appears in the label at the top of the dropdown as the currently selected item.

The MultiSelectTree, on the other hand, lets the user select multiple items:

A similar display to the previous one but with both the Executive and Marketing nodes expanded and all of the nested nodes have checkboxes beside them. Under the Executive node, the Andrew Fuller item has a check in its checkbox; under the Accounting node one of the two nested nodes – Steven Buchanan – has a check in its checkbox. At the top of the dropdown those two selected items appear in lozenges. Each lozenge has an x at its end to allow the lozenge to be deleted.

Structuring Your Data

The critical success factor in generating a treeview is structuring the data so that the dropdowns can work their magic. Fortunately, these dropdown lists support working with data in two different formats.

Flat Data

The simplest solution is where you have an array of objects that refer to each other. The classic examples are an organization chart or a bill of material (BOM).

An organization chart with Andrew Fuller at the top with three employees reporting to him: Steven Buchanan, Laura Callahan, and Nancy Davolio. Two people report to Laura Callahan in this chart: Michael Suyama and Robert King.

Typically, you’ll get that data as a single array with each entry in the array having a reference to its parent entry. The first step is to define the class that will hold each item in the list. This Employee class gives each employee an id field, an empName field, and a mgr field (the mgr field contains the id of the employee that this employee reports to—the parent record):

export class Employee {
  constructor(
    public id: number,
    public empName: string,
    public mgr: number | null
  ) { }
}

Your next step is to load an array with the data you intend to display in your list. For this example, the entries in the array are hardcoded and loaded into a property on the component:

public orgChart: Employee[] = [
    new Employee( 2, "Nancy Davolio", 1),
    new Employee( 1, "Andrew Fuller", null),
    new Employee( 5, "Michael Suyama", 4),
    new Employee( 4, "Laura Callahan",  1),
    new Employee( 6, "Robert King",  4),
    new Employee( 3, "Steven Buchanan", 1),
  ];

As you can see, the head of the company—Andrew Fuller—reports to no one (which is why the mgr field on the Employee class has to accept a null). Two other employees—Michael Suyama and Robert King—report to Laura Callahan.

The final step is to add the kendo-dropdowntree to your component. There are a number of directives and properties you need to set on the dropdown:

  • kendoDropDownTreeFlatBinding: This points to the array (orgChart, in this example) that holds the list objects and, for this data structure, specifies that you’re using organization/BOM style objects (“flat” binding).
  • parentIdField: The name of the field in the object used to look up the parent record (in this case, the mgr field).
  • valueField: The name of the field in the object that the parentIdField should search to find the parent (in this case, the mgr field holds some other employee’s id field).
  • textField: The name of the field to be displayed in the list (in this case, the empName field).
  • kendoDropDownTreeExpandable: If you omit this, the tree is displayed with all its nodes expanded and the user can’t open or close any node.
<kendo-dropdowntree
           [kendoDropDownTreeFlatBinding]="orgChart"
           parentIdField="mgr"
           valueField="id"
           textField="empName"
           kendoDropDownTreeExpandable
           class="employee">
</kendo-dropdowntree>

The result looks like in a DropDownTree (and pretty much the same in a MultiSelectTree).

A treeview dropdown list with Andrew Fuller as the top node. That node has been expanded showing the four people nested under his node. One of those people has two people reporting to her – that node has also been expanded to show two more items nested under her.

As you can see, even though the items in the array weren’t in the right order, all the employees are nested correctly in the dropdown’s list.

Nested Children

Another common scenario is for each parent object to have an array of child items. This Department class, for example, has an employees field that holds an array of employee objects:

export class Department {
  constructor(
    public id: string,
    public deptName: string,
    public employees: Employee[]
  ) { }
}

To put it another way, each Department object is the parent in a two-level hierarchy with Employee children.

Loading a Departments property on the component that hold an array of these Department objects with their child Employee objects might look like this:

public Departments: Department[] = [

    new Department( "Mkt", "Marketing",
              [new Employee( 5, "Michael Suyama", 4),
              new Employee( 4, "Laura Callahan", 1),
              new Employee( 6, "Robert King", 4)]
    ),

    new Department( "Exec", "Executive",
          [new Employee( 1, "Andrew Fuller", null)]),     
          
    new Department( "Acct", "Accounting",
          [new Employee( 2, "Nancy Davolio", 1),
          new Employee( 3, "Steven Buchanan", 1)]
    ),
];

Now it’s just a matter of adding the dropdown to display these objects. Only these three changes are required to handle this data structure, compared to the org chart/BOM:

  • kendoDropDownTreeHierarchyBinding: Points to the array holding the data and specifies that there’s a property holding the child objects.
  • childrenField: The name of the field holding the nested objects.
  • textField: An array containing the name of the fields to be displayed for each level in the hierarchy (i.e., “deptName” for the parent Department object, “empName” for the child Employee object).

You still need a valueField and the kendoDropDownTreeExpandable directive.

<kendo-dropdowntree          
          [kendoDropDownTreeHierarchyBinding]="Departments"
          childrenField="employees"
          [textField]="['deptName','empName’]"
          valueField="id"
          kendoDropDownTreeExpandable>
    </kendo-dropdowntree>

The resulting dropdown would look like this:

A treeview dropdown list showing three top level nodes: Marketing, Executive, and Accounting. The Marketing node has been expanded to show three nodes nested underneath it: Michael Suyama, Laura Callahan, and Robert King.

Configuring the MultiSelectTree is identical to the DropDownTree—the difference being that the user gets to select multiple items. Here’s the previous example using the MultiSelectTree:

<kendo-multiselecttree          
          [kendoDropDownTreeHierarchyBinding]="Departments"
          childrenField="employees"
          [textField]="['deptName','empName’]"
          valueField="id"
          kendoDropDownTreeExpandable>
</kendo-multiselecttree>

A dropdown list with its list open. The list is organized into a treeview with three heading nodes labeled Marketing, Executive, and Accounting. The Executive node is expanded showing an item nested underneath it labeled Andrew Fuller. That item is highlighted in red and Andrew Fuller also appears in the label at the top of the dropdown as the currently selected item.

More Features

There are more features on these controls. You can, for example, ensure that you can recreate the last configuration (i.e., when the user closes the list and reopens it, you can expand any nodes that were expanded when the list was closed). If you’d prefer to retrieve child objects as you need them, you can take advantage of the fetchChildren and hasChildren properties to wire up a retrieval function.

Plus, these dropdowns share functionality with the Kendo UI for Angular dropdowns: you can style these dropdowns, provide templates to control how parts of the components are displayed, bind the retrieved values either with form templates (ngModel) or reactive forms (FormGroup), set a default value, or add a default item, among other features.

And that’s all worth doing. But you’ve already addressed the key issue: Loading your data.


Peter Vogel
About the Author

Peter Vogel

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter also writes courses and teaches for Learning Tree International.

Related Posts

Comments

Comments are disabled in preview mode.