Sunday 18 October 2020

Filter treeNodes in Ant Design Tree

I'm using a Searchable Tree component in Ant Design. I would like to filter treeNodes on search. So that if a search value is found, a treeNode is shown. If not, it is hidden (i. e. filtered).

There is a filterTreeNode prop in API. Is it possible to filter treeNodes (hide unrelevant treeNodes from search) with this prop? If not, how can achieve the desired result?

Here is my code for filterTreeNode function:

const filterTreeNode = (node) => {
  const title = node.title.props.children[2];
  const result = node.key.indexOf(searchValue) !== -1 ? true : false
  console.log(searchValue);
  console.log(result);
  return result;
};

I can see that the result (true or false) is logged in the console, but with the Tree itself nothing happens.

Here is a link to codesandbox and the full code for the component:

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Tree, Input } from "antd";
import gData from "./gData.js";

const { Search } = Input;

const dataList = [];
const generateList = (data) => {
  for (let i = 0; i < data.length; i++) {
    const node = data[i];
    const { key } = node;
    dataList.push({ key, title: key });
    if (node.children) {
      generateList(node.children);
    }
  }
};
generateList(gData);

const getParentKey = (key, tree) => {
  let parentKey;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some((item) => item.key === key)) {
        parentKey = node.key;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey;
};

const SearchTree = () => {
  const [expandedKeys, setExpandedKeys] = useState([]);
  const [autoExpandParent, setAutoExpandParent] = useState(true);
  const [searchValue, setSearchValue] = useState("");

  const onExpand = (expandedKeys) => {
    setExpandedKeys(expandedKeys);
    setAutoExpandParent(false);
  };

  const onChange = (e) => {
    const { value } = e.target;
    const expandedKeys = dataList
      .map((item) => {
        if (item.title.indexOf(value) > -1) {
          return getParentKey(item.key, gData);
        }
        return null;
      })
      .filter((item, i, self) => item && self.indexOf(item) === i);
    if (value) {
      setExpandedKeys(expandedKeys);
      setSearchValue(value);
      setAutoExpandParent(true);
    } else {
      setExpandedKeys([]);
      setSearchValue("");
      setAutoExpandParent(false);
    }
  };

  const filterTreeNode = (node) => {
    const title = node.title.props.children[2];
    const result = title.indexOf(searchValue) !== -1 ? true : false;
    console.log(searchValue);
    console.log(result);
    return result;
  };

  const loop = (data) =>
    data.map((item) => {
      const index = item.title.indexOf(searchValue);
      const beforeStr = item.title.substr(0, index);
      const afterStr = item.title.substr(index + searchValue.length);
      const title =
        index > -1 ? (
          <span>
            {beforeStr}
            <span className="site-tree-search-value">{searchValue}</span>
            {afterStr}
          </span>
        ) : (
          <span>{item.title}</span>
        );
      if (item.children) {
        return { title, key: item.key, children: loop(item.children) };
      }

      return {
        title,
        key: item.key
      };
    });
  return (
    <div>
      <Search
        style=
        placeholder="Search"
        onChange={onChange}
      />
      <Tree
        onExpand={onExpand}
        expandedKeys={expandedKeys}
        autoExpandParent={autoExpandParent}
        treeData={loop(gData)}
        filterTreeNode={filterTreeNode}
      />
    </div>
  );
};

ReactDOM.render(<SearchTree />, document.getElementById("container"));


from Filter treeNodes in Ant Design Tree

No comments:

Post a Comment