Create elements on the page that will host the controls.
Initialize the controls passing the id of the host element as a parameter,
followed by an optional initialization object.
The examples below demonstrate all this.
Creating Trees
To create trees, you will normally have to set three properties:
itemsSource defines the array that contains the hierarchical data.
Each item in the array contains information about a node and (optionally)
an array of child nodes.
displayMemberPath defines the name of the property in the items
that contains the text to be displayed in the tree nodes. By default, this
property is set to the string 'header'.
childItemsPath defines the name of the property in the items that
contains the array of child nodes. By default, this property is set to the
string 'items'.
There are also properties for binding node images, checkboxes, and collapsed
state to the itemsSource array.
By default, the TreeView expands the first node of each level when it loads
the tree. You can customize that behavior using the collapsedMemberPath
property to control the collapsed state of each node, or call the
collapseToLevel method after the tree is loaded to collapse all nodes
deeper than the level you want to show.
Once the tree is loaded, you can select, collapse, or expand nodes using the
mouse or the keyboard. You can also use the keyboard to search for nodes.
The TreeView control uses animations to expand and collapse nodes by default.
You can turn this feature off by setting the isAnimated property to
false.
It also collapses sibling nodes automatically when a node is expanded.
You can turn this feature off by setting the autoCollapse property
to false.
By default, the TreeView control expands collapsed nodes when the user
clicks anywhere on the node. You can change this by setting the
expandOnClick property to false, in which case only clicks
on the collapsed/expanded glyph will affect the collapsed state.
/* default trees on this sample */
.wj-treeview {
height: 350px;
font-size: 120%;
margin-bottom: 8px;
background: white;
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
}
Result (live):
Styling and CSS
You can customize the appearance of the TreeView using CSS.
This example changes the collapse/expand icons, uses different
font sizes depending on node level, and adds a vertical bar to
the left of the level one nodes.
Use the checkbox below the TreeView to toggle the custom style
and see the difference.
// create and bind the 'CSS' TreeView
var tvCss = new wijmo.nav.TreeView('#tvCss', {
displayMemberPath: 'header',
childItemsPath: 'items',
itemsSource: items
});
// toggle style when user checks the checkbox
document.getElementById('tvCssCheck').addEventListener('change', function(e) {
wijmo.toggleClass(tvCss.hostElement, 'custom-tree', e.target.checked);
});
The simplest and most common use for the TreeView control is navigation.
The TreeView's hierarchical structure and auto-search functionality make
it easy for users to drill-down and find the items they are interested in.
You can use the selectedItemChanged or itemClicked events
for navigation. The difference is that selectedItemChanged occurs
when the user moves the selection with the keyboard, and itemClicked
occurs when the user clicks an item or presses the Enter key.
// create and bind the 'Navigation' TreeView
var tvNav = new wijmo.nav.TreeView('#tvNav', {
displayMemberPath: 'header',
childItemsPath: 'items',
itemsSource: items,
itemClicked: function (s, e) {
document.getElementById('tvNavItem').innerHTML =
'Navigating to <b>*** ' + s.selectedItem.header + ' ***</b>';
}
});
Result (live):
Accordion Trees
Accordions are multi-pane panels that keep only one panel expanded
at a time. They are commonly used for navigation.
You can use the TreeView control to implement accordions.
Use CSS to customize the header display and to hide the
collapse/expand glyphs, and make sure the autoCollapse
property is set to true (the default), so non-active panels
are automatically collapsed.
Set the showCheckboxes property to true and the TreeView will
add checkboxes to each node.
When checkboxes are displayed, the TreeView manages their
hierarchy so that when a checkbox is checked or cleared, the new
value is automatically applied to all child nodes, and reflected
on the state of the parent nodes.
When items are checked or unchecked, the checkedItemsChanged
event is raised, and the checkedItems property is updated
with a list of the items that are currently checked.
// create and bind the 'Disable Items' TreeView
var tvDisable = new wijmo.nav.TreeView('#tvDisable', {
displayMemberPath: 'header',
childItemsPath: 'items',
itemsSource: items,
});
// disable selected node
document.getElementById('btnDisableNode').addEventListener('click', function () {
var nd = tvDisable.selectedNode;
if (nd) {
nd.isDisabled = true;
}
});
// enable all nodes
document.getElementById('btnEnableAllNodes').addEventListener('click', function () {
for (var nd = tvDisable.getFirstNode(); nd; nd = nd.next()) {
nd.isDisabled = false;
}
});
Result (live):
Custom Node Content
You can customize the content of the TreeView nodes using the formatItem
event. The event handler parameters include the element that represents the node
and the data item being rendered.
The example below uses the formatItem event to add a "new" badge to the
right of new items on the tree.
// create and bind the 'Custom Content' TreeView
var tvFmtItem = new wijmo.nav.TreeView('#tvFmtItem', {
displayMemberPath: 'header',
childItemsPath: 'items',
itemsSource: items,
formatItem: function (s, e) {
if (e.dataItem.newItem) {
e.element.innerHTML +=
'<img style="margin-left:6px" src="resources/new.png"/>';
}
}
});
Result (live):
Lazy Loading
Lazy loading is useful when you are dealing with large hierarchical data sources
and would like to avoid the delays involved in loading the entire data set at once.
The TreeView control makes lazy-loading super easy. Only two steps are required:
Set the items property in the parent node data item to an empty array.
Set the TreeView's lazyLoadFunction property to a function to be called
when the user expands the node. This function takes two parameters: the parent node
and a callback function to be invoked when the data becomes available.
The tree in example below starts with three lazy-loaded nodes.
When you expand them, the lazyLoadFunction is invoked. The function
uses a setTimeout to simulate an http delay and returns data for three
child nodes, one of which is also a lazy-loaded node.
The example also uses some CSS to animate the node icons while they are being
loaded.
// create and bind the 'Lazy Load' TreeView
var tvLazyLoad = new wijmo.nav.TreeView('#tvLazyLoad', {
displayMemberPath: 'header',
childItemsPath: 'items',
itemsSource: [ // start with three lazy-loaded nodes
{ header: 'Lazy Node 1', items: []},
{ header: 'Lazy Node 2', items: [] },
{ header: 'Lazy Node 3', items: [] }
],
lazyLoadFunction: function (node, callback) {
setTimeout(function () { // simulate http delay
var result = [ // simulate result
{ header: 'Another lazy node...', items: [] },
{ header: 'A non-lazy node without children' },
{ header: 'A non-lazy node with child nodes', items: [
{ header: 'hello' },
{ header: 'world' }
]}
];
callback(result); // return result to control
}, 2500); // 2.5sec http delay
}
});
Result (live):
Lazy Loading and OData
This example shows how you can use the TreeView control to display
hierarchical data from OData sources.
The sample starts by loading the Northwind employees table. When the
data is loaded, the code adds an "Orders" empty array to each employee.
The lazyLoadFunction is used to load the orders when an employee
node is expanded.
The orders table also adds an "Order_Details" empty array to each
order. The lazyLoadFunction is used to load the order details
when an order node is expanded.
Set the allowDragging property to true to allow users to drag nodes to new
positions within the TreeView.
When dragging is allowed, users may drag any node to any position within the tree.
You can customize this behavior by handling the TreeView drag/drop events:
dragStart: Occurs when a drag/drop operation is about to start. You
may examine the node about to be dragged and cancel the operation by
setting the event's cancel parameter to true.
dragOver: Occurs while the user drags the node over other nodes on
the tree. You may examine the current target node and drop position and
prevent the drop or modify its location setting the event's cancel
and position parameters.
drop: Occurs when the user drops the node into its new location.
You may examine the current target node and drop position and
prevent the drop or modify its location setting the event's cancel
and position parameters.
dragEnd: Occurs after the drag/drop operation is finished, even if
it was canceled and the source node was not moved.
The example below shows how to provide standard and customized drag/drop
operations on a TreeView control:
// create and bind the drag/drop TreeView
var allowDraggingParentNodes = true,
allowDroppingIntoEmpty = true;
var tvDragDrop = new wijmo.nav.TreeView('#tvDragDrop', {
displayMemberPath: 'header',
childItemsPath: 'items',
imageMemberPath: 'img',
showCheckboxes: true,
allowDragging: true,
itemsSource: items,
// use dragStart event to honor the allowDraggingParentNodes setting
// by setting the 'cancel' event parameter to true
dragStart: function (s, e) {
if (e.node.hasChildren) {
if (!allowDraggingParentNodes) {
e.cancel = true; // prevent dragging parent nodes
} else {
e.node.isCollapsed = true; // collapse parent nodes when dragging
}
}
},
// use dragOver event to honor the allowDroppingIntoEmpty setting
// by changing the 'position' event parameter to 'Before'
dragOver: function (s, e) {
if (!allowDroppingIntoEmpty &&
!e.dropTarget.hasChildren &&
e.position == wijmo.input.DropPosition.Into) {
e.position = wijmo.input.DropPosition.Before;
}
},
});
Result (live):
Drag and Drop Between Trees
Setting the allowDragging property to true allows users to drag and drop nodes
within the same TreeView.
To allow dragging and dropping nodes between different TreeView controls, you must
handle the dragOver event and set the cancel parameter to false if
the move is valid.
In the example below, users can drag nodes within and between the two trees:
// create trees to drag/drop between
var tvDragDrop1 = new wijmo.nav.TreeView('#tvDragDrop1', {
displayMemberPath: 'header',
childItemsPath: 'items',
allowDragging: true,
dragOver: dragOverBetweenTrees,
itemsSource: [
{ header: 'Item 1.1' },
{ header: 'Item 1.2' },
{ header: 'Item 1.3' },
]
});
var tvDragDrop2 = new wijmo.nav.TreeView('#tvDragDrop2', {
displayMemberPath: 'header',
childItemsPath: 'items',
allowDragging: true,
dragOver: dragOverBetweenTrees,
itemsSource: [
{ header: 'Item 2.1' },
{ header: 'Item 2.2' },
{ header: 'Item 2.3' },
]
});
// allow drag/drop between tvDragDrop1 and tvDragDrop2
function dragOverBetweenTrees(s, e) {
var t1 = e.dragSource.treeView,
t2 = e.dropTarget.treeView;
if (t1 == tvDragDrop1 || t1 == tvDragDrop2) {
if (t2 == tvDragDrop1 || t2 == tvDragDrop2) {
e.cancel = false;
}
}
}
Result (live):
Editing Nodes
The TreeView control provides editing support. Set the isReadOnly
property to false and users will be able to edit the content of the nodes
by pressing the F2 key.
Edits made to node contents are automatically applied to the items in
the itemsSource array using the properties specified by the
displayMemberPath property.
You may customize the editing behavior using the following events:
nodeEditStarting, nodeEditStarted,
nodeEditEnding, and nodeEditEnded.
In the example below, we enable editing only for nodes that contain no
children. To edit, select a node and press F2:
// create and bind the 'Editable Nodes' TreeView
var tvEdit = new wijmo.nav.TreeView('#tvEdit', {
displayMemberPath: 'header',
childItemsPath: 'items',
imageMemberPath: 'img',
showCheckboxes: true,
itemsSource: items,
isReadOnly: false,
nodeEditStarting: function (s, e) {
if (e.node.hasChildren) {
e.cancel = true;
}
}
});
Result (live):
RTL support
Some languages render content from the right to the left of the page
(Arabic and Hebrew are typical examples) .
HTML accommodates this with the 'dir' attribute. Setting 'dir' to 'rtl'
on any element causes the element's content to flow from right to left.
The TreeView supports this automatically. If the element hosting the tree
has the 'dir' attribute set to 'rtl', the tree will render with nodes
extending from right to left. You don't have to set any properties on the
control.
Note that the 'dir' attribute value is inherited, so if you set it on the
body tag for example, the entire page will be rendered from right to left,
including the tree.
Note also that CSS has a 'direction' attribute that performs the same
function as the 'dir' element attribute. The 'dir' attribute is generally
considered more appropriate for several reasons, including the fact that
it can be used in CSS rules.
// demonstrate RTL support (no need to set any properties)
var tvRtl = new wijmo.nav.TreeView('#tvRtl', {
displayMemberPath: 'header',
childItemsPath: 'items',
imageMemberPath: 'img',
showCheckboxes: true,
allowDragging: true,
itemsSource: items
});