Search code examples
javascriptantd

Remove element from Select Antd


I use Ant-design component Select/Custom dropdown (codesandbox) but it does not have a function to delete an item from a special dropdown menu and if you add a button for each item Option then when you click on it the item Select closes. Who faced such a problem?


Solution

  • The trick here is to use event.stopPropagation() which will just stop event bubbling to HTML elements that are higher in the hierarchy.

    The delete handler that stops propagation.

      const deleteItem = (e, index) => {
        e.stopPropagation();
        e.preventDefault();
        const updated = [...items];
        updated.splice(index, 1);
        setItems(updated);
      };
    

    The whole code with a button that deletes an item from a dropdown.

    import React from "react";
    import "antd/dist/antd.css";
    import "./index.css";
    import { PlusOutlined } from "@ant-design/icons";
    import { Divider, Input, Select, Space, Typography, Button } from "antd";
    import { useState } from "react";
    const { Option } = Select;
    let index = 0;
    
    const App = () => {
      const [items, setItems] = useState(["jack", "lucy"]);
      const [name, setName] = useState("");
    
      const onNameChange = (event) => {
        setName(event.target.value);
      };
    
      const addItem = (e) => {
        e.preventDefault();
        setItems([...items, name || `New item ${index++}`]);
        setName("");
      };
    
      const deleteItem = (e, index) => {
        e.stopPropagation();
        e.preventDefault();
        const updated = [...items];
        updated.splice(index, 1);
        setItems(updated);
      };
    
      return (
        <Select
          style={{
            width: 300
          }}
          placeholder="custom dropdown render"
          dropdownRender={(menu) => (
            <>
              {menu}
              <Divider
                style={{
                  margin: "8px 0"
                }}
              />
              <Space
                align="center"
                style={{
                  padding: "0 8px 4px"
                }}
              >
                <Input
                  placeholder="Please enter item"
                  value={name}
                  onChange={onNameChange}
                />
                <Typography.Link
                  onClick={addItem}
                  style={{
                    whiteSpace: "nowrap"
                  }}
                >
                  <PlusOutlined /> Add item
                </Typography.Link>
              </Space>
            </>
          )}
        >
          {items.map((item, index) => (
            <Option key={item}>
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center"
                }}
              >
                <div>{item}</div>
                <Button onClick={(e) => deleteItem(e, index)} danger size="small">
                  Delete
                </Button>
              </div>
            </Option>
          ))}
        </Select>
      );
    };
    
    export default App;