React Select,为多选文本输入添加复制粘贴功能



我有一个react-select组件(使用CreatableSelect生成(,它是一个多选文本输入,允许用户添加关键字作为选项。

它工作得很好,但我需要一种方法,允许用户复制一些逗号分隔的文本,并将其粘贴到组件中,这样每个项目都将作为一个选项添加。

例如,如果文本是";123456789";,预期输出将是3个单独的选项:分别为123、456和789。

这是我的组件

import React, {KeyboardEventHandler} from 'react';
import CreatableSelect from 'react-select/creatable';
import { ActionMeta, OnChangeValue } from 'react-select';
const MultiSelectTextInput = (props) => {
const components = {
DropdownIndicator: null,
};
interface Option {
readonly label: string;
readonly value: string;
}
const createOption = (label: string) => ({
label,
value: label,
});
const handleChange = (value: OnChangeValue<Option, true>, actionMeta: ActionMeta<Option>) => {
console.group('Value Changed');
console.log(value);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
props.setValue(value);
};
const handleInputChange = (inputValue: string) => {
props.setInputValue(inputValue);
};
const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (event) => {
if (!props.inputValue) return;
switch (event.key) {
case 'Enter':
case 'Tab':
if (props.value.map(v => v.label).includes(props.inputValue)) {
console.log('Value Already Exists!')
props.setInputValue('');
}
else {
console.group('Value Added');
console.log(props.value);
console.groupEnd();
props.setInputValue('');
props.setValue([...props.value, createOption(props.inputValue)])
}
event.preventDefault();
}
};
return (
<CreatableSelect
id={props.id}
instanceId={props.id}
className="w-100"
components={components}
inputValue={props.inputValue}
isClearable
isMulti
menuIsOpen={false}
onChange={handleChange}
onInputChange={handleInputChange}
onKeyDown={handleKeyDown}
placeholder={props.placeholder}
value={props.value}
/>
);
};
export default MultiSelectTextInput;

我从(next.js项目的(页面调用这个组件,如下所示。该组件修改调用它的页面的状态。

...
import MultiSelectTextInput from "../components/Form/MultiSelect/MultiSelectTextInput";
...
const NcciLite = () => {
const [value, setValue] = useState<any>([]);
const [inputValue, setInputValue] = useState<any>('');
...
return (
<React.Fragment>
<Container fluid={true}>
<Breadcrumbs title="Tools" breadcrumbItem="NCCI Lite" />
<Row>
<Col>
<Card>
<CardBody>
<CardTitle className="mb-4 fw-light">...</CardTitle>
<Form onSubmit={event => event.preventDefault()}>
...
<Row className="mb-4">
<Col>
<div className="d-inline-flex col-md-9">
<MultiSelectTextInput
id="codes"
value={value}
setValue={setValue}
inputValue={inputValue}
setInputValue={setInputValue}
placeholder="Type Next Code(s) or Paste Here"
/>
</div>
</Col>
</Row>
...
</Form>
</CardBody>
</Card>
</Col>
</Row>
</Container>
</React.Fragment>
};
export default NcciLite;

如有任何帮助,将不胜感激

好吧,我会回答我自己的问题。我以为这会很困难,但事实并非如此。只有几行javascript代码。

改良组件

import React, {KeyboardEventHandler} from 'react';
import CreatableSelect from 'react-select/creatable';
import { ActionMeta, OnChangeValue } from 'react-select';
const MultiSelectTextInput = (props) => {
const components = {
DropdownIndicator: null,
};
interface Option {
readonly label: string;
readonly value: string;
}
const createOption = (label: string) => ({
label,
value: label,
});
const handleChange = (value: OnChangeValue<Option, true>, actionMeta: ActionMeta<Option>) => {
// console.group('Value Changed');
// console.log(value);
// console.log(`action: ${actionMeta.action}`);
// console.groupEnd();
props.setValue(value);
};
const handleInputChange = (inputValue: string) => {
props.setInputValue(inputValue);
};
const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (event) => {
if (!props.inputValue) return;
switch (event.key) {
case 'Enter':
case 'Tab':
if (props.value.map(v => v.label.trim()).includes(props.inputValue.trim())) {
// console.log('Value Already Exists!')
props.setInputValue('');
}
else {
// console.group('Value Added');
// console.log(props.value);
// console.groupEnd();
if (!props.customizedSetter && props.inputValue.trim().indexOf(',') > -1) {
props.setInputValue('');
const values = props.inputValue.trim().split(',').filter(iv => !props.value.map(v => v.label.trim()).includes(iv.trim()));
for (let i = 0; i < values.length; i++) {
props.setValue((oldValue) =>[...oldValue, createOption(values[i].trim())]);
}
}
else {
props.setInputValue('');
props.setValue([...props.value, createOption(props.inputValue.trim())]);
}
}
event.preventDefault();
}
};
return (
<CreatableSelect
id={props.id}
instanceId={props.id}
className="cs w-100"
components={components}
inputValue={props.inputValue}
isClearable
isMulti
menuIsOpen={false}
onChange={handleChange}
onInputChange={handleInputChange}
onKeyDown={handleKeyDown}
placeholder={props.placeholder}
value={props.value}
/>
);
};
export default MultiSelectTextInput;

最新更新