Select child nodes when root node is selected

Viewed 23

I have created a 2 level material-ui treeview. When root node is selected I need to select all the child nodes. Can someone help how to do this with material-ui treeview.

Please refer material-ui treeview child select on root selection

When John is selected, all it's child nodes i.e ruby,go,java should be selected.

1 Answers

You can do this by using the TreeView as a controlled component like this:

import { useEffect, useState } from "react";
import {
  ArrowDropDown,
  ArrowDropDownCircle,
  ArrowRight
} from "@mui/icons-material";
import { TreeItem, TreeView } from "@mui/lab";

const getChildrenIdsOfParent = (id, items) => {
  const parent = items.find((i) => "" + i.id === "" + id);
  if (parent) {
    return parent.languages.map((l) => "" + l.id);
  }
  return [];
};

const CustomTreeView = (props) => {
  const [selected, setSelected] = useState([]);
  const [expanded, setExpanded] = useState([props.items[0].id]);

  useEffect(() => {
    let newSelected = [...selected];
    expanded.forEach((pid) => {
      const childrenIds = getChildrenIdsOfParent(pid, props.items);
      newSelected = [...newSelected, ...childrenIds];
    });
    setSelected([...new Set(newSelected)]);
  }, [expanded, props.items]);

  const handleToggle = (event, nodeIds) => {
    setExpanded(nodeIds);
  };

  const handleSelect = (event, nodeIds) => {
    setSelected(nodeIds);
  };

  return (
    <TreeView
      multiSelect={props.selectType}
      defaultExpandIcon={<ArrowRight />}
      defaultCollapseIcon={<ArrowDropDown />}
      defaultEndIcon={<ArrowDropDownCircle />}
      sx={{
        flexGrow: 1,
        overflowX: "hidden",
        overflowY: "auto",
        backgroundColor: "#E1E1E1",
        border: "solid 1px #B0B0B0"
      }}
      expanded={expanded}
      selected={selected}
      onNodeToggle={handleToggle}
      onNodeSelect={handleSelect}
    >
      {props.items.map((item) => (
        <TreeItem
          nodeId={item.id}
          key={item.id}
          label={item.name}
          width="350px"
        >
          {item.languages.map((lang) => (
            <TreeItem
              nodeId={lang.id}
              key={lang.id}
              label={lang.name}
              width="350px"
            ></TreeItem>
          ))}
        </TreeItem>
      ))}
    </TreeView>
  );
};

export default CustomTreeView;

You can take a look at this sandbox for a live working example.

Related