-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to add new tags automatically when pasting text on the input #73
Comments
One way you can achieve that is by using the renderInput prop. Probably over engineered, but here is an example of how you could achieve it. I hope that helps. import React, { useCallback, useRef, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import {
InputRendererProps,
ReactTags,
ReactTagsAPI,
TagSelected,
} from "react-tag-autocomplete"; // Importing components and types from 'react-tag-autocomplete'
import { suggestions } from "./countries";
import "./styles.css";
export default function App() {
const api = useRef<ReactTagsAPI>(null); // Ref to hold the instance of ReactTagsAPI
const [selected, setSelected] = useState<TagSelected[]>([]); // State to manage the selected tags
// Function to validate if a new tag can be added
const onValidate = (value: string) => {
return (
selected.filter(
(tag) => tag.label.toLocaleLowerCase() === value.toLocaleLowerCase()
).length === 0
);
};
// Function to add a new tag to the list
const onAdd = useCallback(
(newTag: TagSelected) => {
setSelected([...selected, newTag]);
},
[selected] // Dependency array ensures onAdd function has the latest state
);
// Function to remove a tag from the list
const onDelete = useCallback(
(tagIndex: number) => {
setSelected(selected.filter((_, i) => i !== tagIndex));
},
[selected] // Dependency array ensures onDelete function has the latest state
);
// Function to handle paste events and add tags from clipboard data
const onPaste = useCallback(
(e: React.ClipboardEvent<HTMLInputElement>) => {
const event = e;
const clipboardData = event.clipboardData;
const pastedText = clipboardData?.getData("text").trim() || "";
const existingTagSuggestion = suggestions.find(
(suggestion) =>
suggestion.label.toLocaleLowerCase() ===
pastedText.toLocaleLowerCase()
);
if (onValidate(pastedText)) {
existingTagSuggestion
? setSelected([...selected, existingTagSuggestion])
: setSelected([...selected, { value: uuidv4(), label: pastedText }]);
// Clear the input field after pasting.
// There is probably a better way to do this.
setTimeout(() => {
if (api?.current?.input?.value) {
api.current.input.value = "";
}
}, 5);
}
},
[selected] // Dependency array ensures onDelete function has the latest state
);
// Custom input component for rendering the input field
function customInput({
classNames,
inputWidth,
...inputProps
}: InputRendererProps) {
return (
<input
className={classNames.input}
style={{ width: inputWidth }}
onPaste={onPaste} // Attach custom paste handler
{...inputProps} // Spread other input properties
/>
);
}
return (
<ReactTags
ref={api} // Set the ref to ReactTagsAPI instance
allowNew // Allow new tags that are not in suggestions
activateFirstOption // Automatically activate the first suggestion
labelText="Select tags" // Label for the input field
selected={selected} // Array of selected tags
suggestions={suggestions} // Array of suggestion tags
onAdd={onAdd} // Handler to add a tag
onDelete={onDelete} // Handler to delete a tag
onValidate={onValidate} // Handler to validate a new tag
renderInput={customInput} // Custom input rendering
noOptionsText="No matching tags" // Text to show when no options match
/>
);
} |
Thanks 👍. Will try this out. |
Thanks for your question @mercera and your detailed response @ellunium. There have been multiple discussions about adding similar behaviour to earlier versions of this component, however each time we found that the expected behaviour would change depending on the context, so no consensus was ever reached. Perhaps we could add an |
I have tried out @ellunium's solution and it's working perfectly. Thanks a lot btw :). @i-like-robots yes. I like that idea as well since that would make things much easier. |
As mentioned in the title it would be nice to have an option to add tags automatically when pasting on the input. Current behaviour is to paste the text and press enter or click on add "tag name" which appears in the suggestion list to add the new tag. I have tried to use onInput prop to achieve this functionality but the callback function does not seem to return the event object, Therefore there is no way to know if the input is from pasting or just from typing. :)
The text was updated successfully, but these errors were encountered: