You're viewing the legacy site. Visit cxjs.io/docs for the latest documentation. Legacy site. Visit cxjs.io/docs for new docs.

Documentation

Report Edit

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.

NamePhoneCityNotified
Cayla Raynor
081-684-2145North GuyNo
Sydnie Rempel
786-973-1539ElsafortNo
Mercedes Abshire
403-546-4221MadalynchesterNo
Eden Koch
440-864-1222JimmieviewNo
Myrtle Nader
914-787-2364South ColumbusNo
Hilda Hyatt
704-598-0143DibbertlandNo
Destin Windler
501-150-2385North ScottieNo
Alfonzo Cassin
988-599-1358BartellfurtNo
Althea Sauer
118-625-3320West KarleeNo
Dominic Harber
424-357-2458South MarioNo
Jana Reynolds
643-116-4232North EloiseNo
Waino Ferry
677-006-0422KubmouthNo
NamePhoneCityNotified
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>
Copied!Cx Fiddle