Stateful Tree Grid
The following example shows how to make a stateful tree grid component with some common tree functionalities.
This way, the state (expanded folders) of the grid will be preserved, even if we reload grid data.
Keep in mind that a record's state will be preserved only if the value of the record's expanded property after reload is nullish (null or undefined).
To make grid stateful, restoreExpandedNodesOnLoad property should be set to true on TreeAdapter.
Additionally, keyField property on either Grid or data adapter has to be specified.
The Code also showcases usage of some builtin Cx functions for easier tree manipulation, like updateTree and removeTreeNodes.
| Name | Phone | City | Notified |
|---|---|---|---|
| 161-421-6509 | New Lillyhaven | No | |
| 648-756-5595 | Lethaberg | No | |
| 287-032-2866 | New Hubert | No | |
| 970-716-3391 | South Chance | No | |
| 087-861-1860 | South Diannachester | No | |
| 818-660-8495 | New Ova | No | |
| 144-267-0241 | Oletamouth | No | |
| 167-062-4816 | Haleymouth | No | |
| 170-911-3807 | Maciport | No | |
| 349-382-7832 | Port Gaetanohaven | No | |
| 567-475-3896 | Reillyberg | No | |
| 819-330-4209 | North Kayleymouth | No |
| Name | Phone | City | Notified |
|---|
ControllerIndex
<div controller={PageController}> <FlexRow spacing style="margin-bottom: 10px"> <Button onClick="load" text="Reload" mod="primary" /> <Button onClick="expandCollapseTree" text="Expand All" text-expr="{$page.treeExpanded} ? 'Collapse All' : 'Expand All'" /> <Button onClick="addFolder" text="Add Folder" /> <Button onClick="addLeaf" text="Add File" /> <Button onClick="deleteRecord" text="Delete" mod="danger" disabled-expr="!{$page.selection}" /> </FlexRow> <Grid emptyText="Loading data..." records-bind="$page.data" mod="tree" style={{ width: "100%", opacity: expr("{$page.loading} ? 0.4 : 1"), height: 400, }} scrollable={true} dataAdapter={{ type: TreeAdapter, restoreExpandedNodesOnLoad: true, }} keyField='recordId' selection={{ type: KeySelection, bind: "$page.selection", keyField: 'recordId' }} columns={[ { header: "Name", field: "fullName", sortable: true, items: ( <cx> <TreeNode expanded-bind="$record.$expanded" leaf-bind="$record.$leaf" level-bind="$record.$level" loading-bind="$record.$loading" text-bind="$record.fullName" icon-bind="$record.icon" /> </cx> ), }, { header: "Phone", field: "phone" }, { header: "City", field: "city", sortable: true }, { header: "Notified", field: "notified", sortable: true, value: { expr: '{$record.notified} ? "Yes" : "No"' }, }, ]} onRowContextMenu={(e, instance) => { openContextMenu( e, <cx> <Menu> <MenuItem onClick="deleteRecordFromContextMenu" autoClose> Delete </MenuItem> <PureContainer visible-expr="!{$record.$leaf}"> <MenuItem onClick="addFolderFromContextMenu" autoClose> Add Folder </MenuItem> <MenuItem onClick="addLeafFromContextMenu" autoClose> Add File </MenuItem> </PureContainer> </Menu> </cx>, instance ); }} /> </div>