Skip to content

Search query not working, Expand/Collapse not functioning after dragging at nodes, and Button actions not working #946

Open
@Kranthi32

Description

@Kranthi32

I'm facing a couple of issues while using react-sortable-tree in my Next js project: using "react-sortable-tree": "^2.7.1", version

Search query not working: The search functionality is not returning expected results. When I search for a node, no matching nodes are highlighted or returned.

Image

Expand/Collapse issue after dragging nodes: After dragging nodes from one place to another, the expand/collapse functionality doesn't work on the node level. The nodes remain expanded or collapsed, and I cannot toggle them properly after moving. at node level expand and collapse and buttons as well.

I created a new node configuration and moved to under contact:

Image

Image

please find below my code can any one help to resolve this.

import React, { useEffect, useState } from 'react';
import dynamic from 'next/dynamic';
import { FaPlus, FaChevronDown, FaChevronUp, FaSearch } from 'react-icons/fa';

const SortableTree = dynamic(() => import('react-sortable-tree'), { ssr: false });
import 'react-sortable-tree/style.css';

interface TreeNode {
title: string;
expanded?: boolean;
children?: TreeNode[];
}

const Tree = () => {
const [treeData, setTreeData] = useState<TreeNode[]>([]);
const [newNodeTitle, setNewNodeTitle] = useState('');
const [searchText, setSearchText] = useState('');
const [matchedNodeIds, setMatchedNodeIds] = useState<string[]>([]);

useEffect(() => {
setTreeData([
{
title: 'Profile',
expanded: true,
children: [
{ title: 'Official' },
{ title: 'Contact' },
{ title: 'License/Passport' },
{ title: 'Education' },
{ title: 'Family' },
],
},
{
title: 'Time Tracking',
expanded: false,
children: [{ title: 'Timesheet Entry' }],
},
]);
}, []);

/*** Expand All Nodes ***/
const expandAll = () => {
const updatedTree = treeData.map((node) => ({
...node,
expanded: true,
children: node.children ? node.children.map((child) => ({ ...child, expanded: true })) : [],
}));
setTreeData(updatedTree);
};

/*** Collapse All Nodes ***/
const collapseAll = () => {
const updatedTree = treeData.map((node) => ({
...node,
expanded: false,
children: node.children ? node.children.map((child) => ({ ...child, expanded: false })) : [],
}));
setTreeData(updatedTree);
};

/*** Add a new node to the main tree ***/
const addNode = () => {
if (newNodeTitle.trim() === '') return;
setTreeData([...treeData, { title: newNodeTitle, expanded: false }]);
setNewNodeTitle('');
};

/*** Search Node in the Tree ***/
const handleSearch = (e: React.ChangeEvent) => {
const query = e.target.value;
setSearchText(query);

};

return (
<div style={{ height: 1000, padding: '10px', fontFamily: 'Arial, sans-serif' }}>
{/* Top Controls /}
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
{/
Create Node Input */}
<input
type="text"
value={newNodeTitle}
onChange={(e) => setNewNodeTitle(e.target.value)}
placeholder="Enter node title"
style={{ padding: '5px', width: '180px', borderRadius: '5px', border: '1px solid #ccc' }}
/>
<button
onClick={addNode}
style={{
padding: '5px 10px',
cursor: 'pointer',
borderRadius: '50%',
background: '#4CAF50',
color: 'white',
border: 'none',
}}
title="Add Node"
>

    {/* Search Box */}
    <input
      type="text"
      value={searchText}
      onChange={handleSearch}
      placeholder="Search node..."
      style={{ padding: '5px', width: '180px', borderRadius: '5px', border: '1px solid #ccc' }}
    />
    <FaSearch style={{ color: '#666' }} />

    {/* Expand and Collapse Buttons */}
    <div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
      <button
        onClick={expandAll}
        style={{
          marginRight: '10px',
          padding: '10px 20px',
          backgroundColor: '#FFFFFF',
          color: 'black',
          border: '1 px solid black',
          borderRadius: '5px',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <span style={{ fontSize: '18px', marginRight: '8px' }}>+</span>
        <span>Expand All Nodes</span>
      </button>

      <button
        onClick={collapseAll}
        style={{
          marginRight: '10px',
          padding: '10px 20px',
          backgroundColor: '#FFFFFF',
          color: 'black',
          border: '1 px solid black',
          borderRadius: '5px',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <span style={{ fontSize: '18px', marginRight: '8px' }}>-</span>
        <span>Collapse All Nodes</span>
      </button>

    </div>
  </div>

  {/* Tree View */}
  <div style={{ height: 400 }}>
    <SortableTree
      treeData={treeData}
      isVirtualized={true}
      searchQuery={searchText}
      onChange={(newTreeData: TreeNode[]) => {
        setTreeData(newTreeData);
        console.log('Updated Tree Data:', newTreeData);
      }}
      canNodeHaveChildren={() => true}
      generateNodeProps={({ node, path }) => ({
        title: (
          <span
            style={{
              fontWeight: matchedNodeIds.includes(path.join('-')) ? 'bold' : 'normal',
              backgroundColor: matchedNodeIds.includes(path.join('-')) ? '#ffff99' : 'transparent',
              padding: '2px 5px',
              borderRadius: '4px',
            }}
          >
            {node.title}
          </span>
        ),
        onClick: () => {
          node.expanded = !node.expanded;
          setTreeData([...treeData]);
        },
      })}
    />
  </div>
</div>

);
};

export default Tree;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions