Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I expand the option without using the arrow button in antd select?

Tags:

reactjs

antd

I would like to know if this is possible in antd tree select. As you can see in the image. How can I expand the option without using the arrow button? I just want to click the word "Expand to load" and then drop down options will show.

enter image description here

like image 943
user3818576 Avatar asked Oct 22 '25 14:10

user3818576


1 Answers

I was playing around with their code in codesandbox.io.

This is what I came up with: https://codesandbox.io/s/loving-frog-pr1qu?file=/index.js

You'll have to create a span node when populating the title of your tree elements, where the span elements will listen for a click event.

  const treeData = [
    {
      title: <span onClick={() => expandNode("0-0")}>0-0</span>,
      key: "0-0",
      children: [
        {
          title: <span onClick={() => expandNode("0-0-0")}>0-0-0</span>,
          key: "0-0-0",
          children: [
            {
              title: "0-0-0-0",
              key: "0-0-0-0"
            },
            {
              title: "0-0-0-1",
              key: "0-0-0-1"
            },
            {
              title: "0-0-0-2",
              key: "0-0-0-2"
            }
          ]
        },
        {
          title: <span onClick={() => expandNode("0-0-1")}>0-0-1</span>,
          key: "0-0-1",
          children: [
            {
              title: "0-0-1-0",
              key: "0-0-1-0"
            },
            {
              title: "0-0-1-1",
              key: "0-0-1-1"
            },
            {
              title: "0-0-1-2",
              key: "0-0-1-2"
            }
          ]
        },
        {
          title: "0-0-2",
          key: "0-0-2"
        }
      ]
    },
    {
      title: <span onClick={() => expandNode("0-1")}>0-1</span>,
      key: "0-1",
      children: [
        {
          title: "0-1-0-0",
          key: "0-1-0-0"
        },
        {
          title: "0-1-0-1",
          key: "0-1-0-1"
        },
        {
          title: "0-1-0-2",
          key: "0-1-0-2"
        }
      ]
    },
    {
      title: "0-2",
      key: "0-2"
    }
  ];

Then use a custom function to set the expandedKeys state and pass it as a prop to the Tree component. I tried using the filter method on the previous state for removing keys but it kept giving me an error so I fell back to using the for loop.

  const expandNode = (key) => {
    setAutoExpandParent(false);
    setExpandedKeys((prev) => {
      const outArr = [];
      if (prev.includes(key)) {
        for (let i = 0; i < prev.length; i++) {
          if (prev[i] !== key) {
            outArr.push(prev[i]);
          }
        }
        return outArr;
      } else {
        prev.push(key);
        return prev;
      }
    });
  };

Note: I used antd's "Controlled Tree" example as the template and progressed from there.


Update

As I was using this solution for a project of mine, I found out a more robust method.

  1. Instead of individually overriding the title properties on the data array, it is possible to override the titleRender prop on the tree component. titleRender is available from antd v.4.5.0.
  2. Style the span tags as inline-block with width and height set to 100%. This makes the entire node block (instead of just the span text) listen for the onClick event when the tree has a prop of blockNode={true}.
  3. Got rid of the for loop and successfully used filter method instead in the toggle expand method. This is more performant than looping.

I created a custom ClickExpandableTree component.

import React, { useState } from "react";
import { Tree } from "antd";

const ClickExpandableTree = props => {
  const [expandedKeys, setExpandedKeys] = useState([]);
  const [autoExpandParent, setAutoExpandParent] = useState(true);

  const toggleExpandNode = key => {
    setExpandedKeys(prev => {
      const outArr = [...prev];
      if (outArr.includes(key)) {
        return outArr.filter(e => e !== key);
      } else {
        outArr.push(key);
        return outArr;
      }
    });
    setAutoExpandParent(false);
  };

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

  return (
    <Tree
      onExpand={onExpand}
      expandedKeys={expandedKeys}
      autoExpandParent={autoExpandParent}
      titleRender={record => (
        <span
          key={record.key}
          onClick={() => toggleExpandNode(record.key)}
          style={{ display: "inline-block", width: "100%", height: "100%" }}
        >
          {record.title}
        </span>
      )}
      {...props}
    />
  );
};

export default ClickExpandableTree;

like image 54
Scratch'N'Purr Avatar answered Oct 26 '25 03:10

Scratch'N'Purr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!