TreeSelect is a form component to choose from hierarchical data.
import { TreeSelect } from 'primereact/treeselect';
<script src="https://unpkg.com/primereact/core/core.min.js"></script>
<script src="https://unpkg.com/primereact/treeselect/treeselect.min.js"></script>
TreeSelect component requires an array of TreeNode objects as its options and keys of the nodes as its value.
<TreeSelect value={selectedNodeKey} options={nodes} onChange={(e) => setSelectedNodeKey(e.value)} placeholder="Select Item"></TreeSelect>
In example below, nodes are retrieved from a remote data source.
export const TreeSelectDemo = () => {
const [nodes, setNodes] = useState(null);
const [selectedNodeKey, setSelectedNodeKey] = useState(null);
useEffect(() => {
let nodeService = new NodeService();
nodeService.getTreeNodes().then(data => setNodes(data));
}, []);
return (
<TreeSelect value={selectedNodeKey} options={nodes} onChange={(e) => setSelectedNodeKey(e.value)} placeholder="Select Item"></TreeSelect>
)
}
export class NodeService {
getTreeNodes() {
return fetch('data/treenodes.json').then(res => res.json()).then(d => d.root);
}
}
The json response sample would be as following.
{
"root": [
{
"key": "0",
"label": "Documents",
"data": "Documents Folder",
"icon": "pi pi-fw pi-inbox",
"children": [{
"key": "0-0",
"label": "Work",
"data": "Work Folder",
"icon": "pi pi-fw pi-cog",
"children": [{ "key": "0-0-0", "label": "Expenses.doc", "icon": "pi pi-fw pi-file", "data": "Expenses Document" }, { "key": "0-0-1", "label": "Resume.doc", "icon": "pi pi-fw pi-file", "data": "Resume Document" }]
},
{
"key": "0-1",
"label": "Home",
"data": "Home Folder",
"icon": "pi pi-fw pi-home",
"children": [{ "key": "0-1-0", "label": "Invoices.txt", "icon": "pi pi-fw pi-file", "data": "Invoices for this month" }]
}]
},
{
"key": "1",
"label": "Events",
"data": "Events Folder",
"icon": "pi pi-fw pi-calendar",
"children": [
{ "key": "1-0", "label": "Meeting", "icon": "pi pi-fw pi-calendar-plus", "data": "Meeting" },
{ "key": "1-1", "label": "Product Launch", "icon": "pi pi-fw pi-calendar-plus", "data": "Product Launch" },
{ "key": "1-2", "label": "Report Review", "icon": "pi pi-fw pi-calendar-plus", "data": "Report Review" }]
},
{
"key": "2",
"label": "Movies",
"data": "Movies Folder",
"icon": "pi pi-fw pi-star-fill",
"children": [{
"key": "2-0",
"icon": "pi pi-fw pi-star-fill",
"label": "Al Pacino",
"data": "Pacino Movies",
"children": [{ "key": "2-0-0", "label": "Scarface", "icon": "pi pi-fw pi-video", "data": "Scarface Movie" }, { "key": "2-0-1", "label": "Serpico", "icon": "pi pi-fw pi-video", "data": "Serpico Movie" }]
},
{
"key": "2-1",
"label": "Robert De Niro",
"icon": "pi pi-fw pi-star-fill",
"data": "De Niro Movies",
"children": [{ "key": "2-1-0", "label": "Goodfellas", "icon": "pi pi-fw pi-video", "data": "Goodfellas Movie" }, { "key": "2-1-1", "label": "Untouchables", "icon": "pi pi-fw pi-video", "data": "Untouchables Movie" }]
}]
}
]
}
Name | Type | Default | Description |
---|---|---|---|
key | any | null | Unique key of the node. |
label | string | null | Label of the node. |
data | any | null | Data represented by the node. |
icon | string | null | Icon of the node to display next to content. |
children | TreeNode[] | null | An array of treenodes as children. |
style | string | null | Inline style of the node. |
className | string | null | Style class of the node. |
selectable | boolean | null | Whether the node is selectable when selection mode is enabled. |
leaf | boolean | null | Specifies if the node has children. Used in lazy loading. |
Tree expansion state is managed in two ways, in uncontrolled mode only initial expanded state of a node can be defined using expandedKeys property whereas in controlled mode expandedKeysproperty along with onToggle properties are used for full control over the state. If you need to expand or collapse the state of nodes programmatically then controlled mode should be used. Example below demonstrates both cases;
import React, { Component } from 'react';
import { TreeSelect } from 'primereact/treeselect';
import { Button } from 'primereact/button';
import { NodeService } from '../service/NodeService';
export const TreeSelectDemo = () => {
const [nodes, setNodes] = useState(null);
const [expandedKeys, setExpandedKeys] = useState({});
useEffect(() => {
nodeService = new NodeService();
nodeService.getTreeNodes().then(data => setNodes(data));
}, [])
const toggleMovies = () => {
let expandedKeys = {...expandedKeys};
if (expandedKeys['2'])
delete expandedKeys['2'];
else
expandedKeys['2'] = true;
setExpandedKeys(expandedKeys);
}
return (
<div>
<h3 className="first">Uncontrolled</h5>
<TreeSelect value={nodes} />
<h5>Controlled</h5>
<Button onClick={toggleMovies} label="Toggle Movies" />
<TreeSelect value={nodes} expandedKeys={expandedKeys}
onToggle={e => setExpandedKeys(e.value)} style={{marginTop: '.5em'}} />
</div>
)
}
TreeSelect supports "single", "multiple" and "checkbox" selection modes. Define selectionMode, value and onChange properties to control the selection. In single mode, selectionKeys should be a single value whereas in multiple or checkbox modes an object is required. By default in multiple selection mode, metaKey is necessary to add to existing selections however this can be configured with metaKeySelection property. Note that in touch enabled devices, Tree does not require metaKey.
import React, {Component} from 'react';
import {TreeSelect} from 'primereact/treeselect';
import {NodeService} from '../service/NodeService';
export const TreeSelectionDemo = () => {
const [nodes, setNodes] = useState(null);
const [selectedNodeKey1, setSelectedNodeKey1] = useState(null);
const [selectedNodeKey2, setSelectedNodeKey2] = useState(null);
const [selectedNodeKey3, setSelectedNodeKey3] = useState(null);
useEffect(() => {
let nodeService = new NodeService();
nodeService.getTreeNodes().then(data => setNodes(data));
}, [])
return (
<div>
<h5>Single Selection</h5>
<TreeSelect value={selectedNodeKey1} options={nodes} selectionMode="single" onChange={e => setSelectedNodeKey1(e.value)} />
<h5>Multiple Selection</h5>
<TreeSelect value={selectedNodeKey2} options={nodes} selectionMode="multiple" onChange={e => setSelectedNodeKey2(e.value)} />
<h5>Checkbox Selection</h5>
<TreeSelect value={selectedNodeKey3} options={nodes} selectionMode="checkbox" onChange={e => setSelectedNodeKey3(e.value)} />
</div>
)
}
Value passed to and from the TreeSelect via the value property should be a an object with key-value pairs where key is the node key and value is a boolean to indicate selection. On the other hand in "checkbox" mode, instead of a boolean, value should be an object that has "checked" and "partialChecked" properties to represent the checked state of a node. Best way to clarify it is prepopulating a TreeSelect with an existing value.
data() {
return {
selectedNodeKey1: '2-1',
selectedNodeKey2: {'1-1': true, '0-0-0': true},
selectedNodeKey3: {'1': {checked: true, partialChecked: true}, '1-0': {checked: true}}
nodes: null
}
},
A comma separated list is used by default to display selected items whereas alternative chip mode is provided using the display property to visualize the items as tokens.
<TreeSelect value={selectedNodeKeys} display="chip" options={nodes} onChange={(e) => setSelectedNodeKeys(e.value)} selectionMode="multiple" placeholder="Select Items" />
Label of an option is used as the display text of an item by default, for custom content support define a valueTemplate that gets the selected nodes as a parameter. For custom filter support define a filterTemplate function that gets the option instance as a parameter and returns the content for the filter element. In addition header, footer and emptyMessage templates are provided for further customization.
const [filterValue, setFilterValue] = useState('');
const filterInputRef = useRef();
const valueTemplate = () => {
return (
<span>Custom Content</span>
)
}
const filterTemplate = (options) => {
let {filterOptions} = options;
return (
<div className="flex gap-2">
<InputText value={filterValue} ref={filterInputRef} onChange={(e) => myFilterFunction(e, filterOptions)} />
<Button label="Reset" onClick={() => myResetFunction(filterOptions)} />
</div>
)
}
const myResetFunction = (options) => {
setFilterValue('');
options.reset();
filterInputRef && filterInputRef.current.focus()
}
const myFilterFunction = (event, options) => {
let _filterValue = event.target.value;
setFilterValue(_filterValue);
options.filter(event);
}
<TreeSelect value={selectedNodeKeys} options={nodes} onChange={(e) => setSelectedNodeKeys(e.value)} valueTemplate={valueTemplate} placeholder="Select Items" filter filterTemplate={filterTemplate}/>
Filtering is enabled by setting the filter property to true, by default label property of a node is used to compare against the value in the text field, in order to customize which field(s) should be used during search define filterBy property.
In addition filterMode specifies the filtering strategy. In lenient mode when the query matches a node, children of the node are not searched further as all descendants of the node are included. On the other hand, in strict mode when the query matches a node, filtering continues on all descendants.
<TreeSelect options={nodes} filter />
<TreeSelect options={nodes} filter filterBy="data.name,data.age" />
<TreeSelect options={nodes} filter filterMode="strict" />
Any valid attribute is passed to the root element implicitly, extended properties are as follows;
Name | Type | Default | Description |
---|---|---|---|
id | string | null | Unique identifier of the element. |
value | any | null | A single or an object of keys to control the selection state. |
name | string | null | Name of the input element. |
style | object | null | Inline style of the component. |
className | string | null | Style class of the component. |
disabled | boolean | false | When present, it specifies that the component should be disabled. |
options | array | null | An array of options to display. |
scrollHeight | string | 400px | Maximum height of the options panel. |
placeholder | string | null | Hint text for the input field. |
tabIndex | number | null | Index of the element in tabbing order. |
inputId | string | null | Identifier of the input element. |
ariaLabel | string | null | Used to define a string that labels the component. |
ariaLabelledBy | string | null | Contains the element IDs of labels. |
selectionMode | string | null | Defines the selection mode, valid values "single", "multiple", and "checkbox". |
panelClassName | string | null | Style class of the overlay panel element. |
panelStyle | string | null | Inline style of the overlay panel element. |
appendTo | DOM element | string | document.body | DOM element instance where the overlay panel should be mounted. Valid values are any DOM Element and 'self'. The self value is used to render a component where it is located. |
emptyMessage | string | null | Text to display when there is no data. |
display | string | comma | Defines how the selected items are displayed, valid values are "comma" and "chip". |
metaKeySelection | boolean | true | Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically. |
valueTemplate | any | null | The template of selected values. |
filterTemplate | any | null | The template for filter element. |
panelHeaderTemplate | any | null | The template of header. |
panelFooterTemplate | any | null | The template of footer. |
transitionOptions | object | null | The properties of CSSTransition can be customized, except for "nodeRef" and "in" properties. |
dropdownIcon | string | pi pi-chevron-down | Icon class of the dropdown icon. |
filter | boolean | false | When specified, displays an input field to filter the items. |
filterValue | string | null | When filtering is enabled, the value of input field. |
filterBy | string | label | When filtering is enabled, filterBy decides which field or fields (comma separated) to search against. |
filterMode | string | lenient | Mode for filtering valid values are "lenient" and "strict". Default is lenient. |
filterPlaceholder | string | null | Placeholder text to show when filter input is empty. |
filterLocale | string | undefined | Locale to use in filtering. The default locale is the host environment's current locale. |
filterInputAutoFocus | boolean | true | When the panel is opened, it specifies that the filter input should focus automatically. |
resetFilterOnHide | boolean | false | Clears the filter value when hiding the dropdown. |
Name | Parameters | Description |
---|---|---|
onShow | - | Callback to invoke when the overlay is shown. |
onHide | - | Callback to invoke when the overlay is hidden. |
onChange | event.originalEvent: browser event event.value: Selected node key(s). | Callback to invoke when selection changes. |
onToggle | event.originalEvent: browser event event.node: Toggled node instance. | Callback to invoke when a node is toggled. |
onNodeSelect | event.originalEvent: browser event event.node: Selected node instance. | Callback to invoke when a node is selected. |
onNodeUnselect | event.originalEvent: browser event event.node: Unselected node instance. | Callback to invoke when a node is unselected. |
onNodeExpand | event.originalEvent: browser event event.node: Expanded node instance. | Callback to invoke when a node is expanded. |
onNodeCollapse | event.originalEvent: browser event event.node: Collapsed node instance. | Callback to invoke when a node is collapsed. |
onFilterValueChange | event.originalEvent: Browser event event.value: the filtered value | Callback to invoke when filter value changes. |
Name | Parameters | Description |
---|---|---|
filter | value: the filter value | Filters the data. |
Following is the list of structural style classes
Name | Element |
---|---|
p-treeselect | Container element. |
p-treeselect-label-container | Container of the label to display selected items. |
p-treeselect-label | Label to display selected items. |
p-treeselect-trigger | Dropdown button. |
p-treeselect-panel | Overlay panel for items. |
p-treeselect-items-wrapper | List container of items. |
This section is under development. After the necessary tests and improvements are made, it will be shared with the users as soon as possible.
None.
Built-in component themes created by the PrimeReact Theme Designer.
Premium themes are only available exclusively for PrimeReact Theme Designer subscribers and therefore not included in PrimeReact core.
Beautifully crafted premium create-react-app application templates by the PrimeTek design team.