I am using Antd Select with mode="tags".
<Select
mode="tags"
style={{ width: '100%' }}
placeholder="Tags Mode"
onChange={onTagsChange}
onSelect={onTagsSelect}
>
{taskTagList}
</Select>
const onTagsChange = (selectedOption) => {
// handle newValue
}
When the user selects one of the available tags, the id (or key) of selected tag is passed as selectedOption. When the user types a new "tag", the name tag is passed. Seems logically reasonable. If the user types a value which matches the key of one of the present value, the matching value is selected, and the new value is ignored. How can we handle this situation.
Existing key-value pairs in option
Key | Value |
---|---|
1 | "A" |
2 | "B" |
3 | "C" |
So, with the above, if the user Select "C" from the select Dropdown, the selectedOption passed in OnTagsChange function is 3. However, if user types 3 in the select, the selectedOption passed in OnTagsChange function is still actually 3, and the SelectBox now shows "C" !! now the OnTagsChange function has no way of knowing,whether the 3 passed is a new "Value" or an existing "key" !!?
So, the question is, if user manually types 3 in the select, can it be indicated to the onTagsChange function that it is not a key but a new value and show 3 in the Select control instead of "C"? Is this possible to implement?
All pointers/suggestions welcome.
onSelect
function will pass two parameters. First one is value and second one is option object. If selected option is present in options array then it will return you the object for that option. If doesn't exist, it will pass an empty object. You can check if value does not exist in object then that a new value/tag. Now you push that tag in options list.
Since each tag value is unique, you do not need to handle the key. Antd Select component automatically uses value as key for each option.
Here's the complete code that handles the tags selection using state and add a new tag in options state.
import { useState } from "react";
import { Select } from "antd";
function App() {
const [value, setValue] = useState([]);
const [options, setOptions] = useState([{ value: "A" }, { value: "B" }, { value: "C" }]);
return (
<>
<Select
mode='tags'
value={value}
style={{ width: "200px" }}
placeholder='Tags Mode'
onSelect={(value, option) => {
if (!option?.value) {
setOptions([...options, { value }]);
}
}}
onChange={(value, option) => {
setValue(value);
}}
options={options}
/>
</>
);
}
export default App;
In your example, assuming that tags have same label and value. That's why in each option object, there's only value
key. But if you want to have different label and value, you can have options like this:
const options = [
{ label: "Label A", value: "A" },
{ label: "Label B", value: "B" },
{ label: "Label C", value: "C" },
];
For more info, you can follow this link