1

I'm using antd library and reactJS. I want the user to be able to input multiple values into a select multiple input statement, and the user can input the same value at once. Something like: [20, 100, 100]. Currently in normal multiple or tags mode, when the user enters another input that already exists, the input will be removed. Basically, I wanted to keep it there. These are the codes I got from antd docs:

const children = [];

function handleChange(value) {
  console.log(`selected ${value}`);
}

ReactDOM.render(
  <Select mode="tags" style={{ width: '100%' }} placeholder="Tags Mode" onChange={handleChange}>
    {children}
  </Select>,
  document.getElementById('container'),
);

I have tried:

  1. Setting a unique key for each of the values selected. But I found difficulties in modifying the current options that the user selected. There is no API provided that I can use to update the current options.

  2. Setting a unique key as the user selects the option by appending Date.now() to the key. But again, I'm not sure how to do this on the select props. Something like this:

ReactDOM.render(
  <Select
    mode="tags"
    style={{ width: "100%" }}
    placeholder="Tags Mode"
    onChange={handleChange}
    value={Date.now() + '' + selectedValue}
  >
    {children}
  </Select>

But again, selectedValue is not a valid variable that I can use.

  1. I tried adding labelInValue, but it just added the id and value, with no option to customize the id.
  • According to the documentation (https://ant.design/components/select/#components-select-demo-big-data =>. https://codesandbox.io/s/solitary-voice-m3vme?from-embed=&file=/index.js) you should add the prop mode="multiple" to use multiple selections. Then the handle change would be provided the comma separated values – user3252327 Nov 16 '22 at 01:13
  • Also note that the children shouldn't be an empty array but some Option components with correct keys and display text. Typically your `value` set to Date.now() + selectedValue seems a bit fishy it should probably be referencing an existing Option provided in the children array – user3252327 Nov 16 '22 at 01:20
  • Hi. Actually I'm using the tags (https://ant.design/components/select/#components-select-demo-tags) here but I'm keeping my option open. What I really want is so that user can enter multiple same input like [10, 10, 2]. In normal multiple or tag mode, if user enter 10, following by another 10, it will be removed. Basically I want to remove this behavior – Ruslan Ashaari Nov 16 '22 at 01:27
  • My bad, I totally misread the question. But then why would you want the user to be able to select multiple times the same value? I feel like it's not the purpose of a (multi) select (at least it wouldn't be something I would expect from a generic framework implementation of a multi select) – user3252327 Nov 16 '22 at 01:35
  • Then instead of multi-select input, do you have any idea on what should I use to enable the user to enter multiple same values at once? – Ruslan Ashaari Nov 16 '22 at 02:15
  • Hm I don't know a solution out of the box, personally I would look for a library that provides this capability or just reimplement a component from scratch that supports a list of options and allows duplicate selection – user3252327 Nov 16 '22 at 02:20
  • I can give you a solution to solve that issue but you need to handle each and every case for select/deselect tags. I recommend you to create an issue in antd github. – Muhammad Nouman Rafique Nov 16 '22 at 04:29
  • Can you please share the solution? I'll work it out from there. Thanks @MuhammadNoumanRafique – Ruslan Ashaari Nov 16 '22 at 04:50

1 Answers1

0

Note: This solution only fix the problem that when ever we have a tag in select and you try to add the same tag, it do not remove the existing selected tag from Antd Select.

import { Select } from "antd";
import { useState } from "react";

function App() {
  const [value, setValue] = useState([]);
  const [searchValue, setSearchValue] = useState("");
  // const [options, setOptions] = useState([]);

  const onSelect = (value) => {
    setValue((prev) => [...prev, value]);
    setSearchValue("");

    // If you want to show tags after user added removes it, you can enable this code
    // Enable options and setOptions
    // setOptions((prev) => {
    //   const index = prev.find((o) => o.value === value);
    //   if (!index) {
    //     return [...prev, { label: value, value }];
    //   }
    //   return prev;
    // });
  };

  const onDeselect = (value) => {
    if (value !== searchValue) {
      setValue((prev) => prev.filter((v) => v !== value));
    }
    setSearchValue("");
  };

  return (
    <div className='App'>
      <Select
        // options={options}
        mode='tags'
        searchValue={searchValue}
        onSearch={setSearchValue}
        value={value}
        style={{ width: "100%" }}
        placeholder='Tags Mode'
        onSelect={onSelect}
        onDeselect={onDeselect}
      />
    </div>
  );
}

export default App;