我正在使用react-select
显示可搜索的项目下拉列表,用户可以从中选择多个项目。我的列表很长,用户经常希望选择多个与同一过滤器字符串匹配的项目,这是一个繁琐的过程,因为每次选择一个项目时,下拉菜单都会消失,您需要重新输入搜索。
例如,以下沙箱中有一个react-select
,其中列出了很多苹果和奶酪。为了选择所有苹果,必须不断输入“ Apple”并一次选择一个苹果。
https://codesandbox.io/s/2l99lry5p
出于桌面用户界面的背景,我自然希望能够键入搜索查询,然后按Ctrl-A
选择所有匹配的搜索结果并将其添加到我的列表中,或将Ctrl-Click
添加到樱桃中从匹配集中选择多个项目。但据我所知,react-select中不支持任何此类热键。
react-select
API是否可以通过任何方式实现“全选”热键(甚至页面上显式的“全选”按钮也可以)。我看不到任何程序方式来访问与过滤器匹配的对象集。这是我需要分叉react-select
来实现的事情,还是可以通过现有的API通过某种方式实现?
答案 0 :(得分:1)
反应选择具有内置的道具,可用于防止菜单在选择时关闭并保留搜索字符串。
首先通过将closeMenuOnSelect
设置为false
来防止菜单在选择时关闭。
然后,如果操作等于onInputChange
,则state
将搜索字符串存储在'input-change'
中。
将inputValue
设置为this.state.value
会将搜索字符串保留在输入字段中。
class Foo extends Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
handleInputChange = (value, e) => {
if (e.action === 'input-change') {
this.setState({value});
}
}
render() {
return (
<Select
isMulti
name="colors"
options={options.map(x => MakeOption(x))}
className="basic-multi-select"
classNamePrefix="select"
/* added these props */
closeMenuOnSelect={false}
onInputChange={this.handleInputChange}
inputValue={this.state.value}
/>
)
}
}
答案 1 :(得分:1)
实现“全选”选项的一种非常简单的方法是使用自定义组件覆盖React-Select组件。为此,您首先需要将其导入为
import { default as ReactSelect } from 'react-select';
然后创建一个自定义组件,该组件定义一个名为“ allowSelectAll”的新属性,并在将该属性设置为“ true”时选择所有选项。
const Select = props => {
if (props.allowSelectAll) {
if (props.value && (props.value.length === props.options.length)) {
return (
<ReactSelect
{...props}
value={[props.allOption]}
onChange={selected => props.onChange(selected.slice(1))}
/>
);
}
return (
<ReactSelect
{...props}
options={[props.allOption, ...props.options]}
onChange={selected => {
if (
selected.length > 0 &&
selected[selected.length - 1].value === props.allOption.value
) {
return props.onChange(props.options);
}
return props.onChange(selected);
}}
/>
);
}
return <ReactSelect {...props} />;
};
Select.propTypes = {
options: PropTypes.array,
value: PropTypes.any,
onChange: PropTypes.func,
allowSelectAll: PropTypes.bool,
allOption: PropTypes.shape({
label: PropTypes.string,
value: PropTypes.string
})
};
Select.defaultProps = {
allOption: {
label: "Select all",
value: "*"
}
};
注意:您只需复制并粘贴上面给出的代码,它就可以正常工作。
完成后,您可以简单地使用新的“选择”组件,并将“ allowSelectAll”属性设置为true。
<Select allowSelectAll={true} isMulti={true} isSearchable={true} options={options} />
答案 2 :(得分:0)
我破解了我想要的东西,但是很丑陋:
https://codesandbox.io/s/j7453qrmv
要使用:
方法:
onInputChanged
进行连接。 onInputChanged
中,获取匹配项以组件状态存储它们Select
附近添加了一个按钮,允许用户选择将匹配的项目集复制到另一个状态变量chosenItems
react-select
Select
组件具有一个value
属性,您可以提供该属性以编程方式选择项目。我将state.chosenItems
传递给了这个。这可行,但是有很多事情使这很痛苦:
onInputChanged
处理程序。我试图通过DOM查询来获取匹配项,但由于onInputChanged
还为时过早,因此无法正常工作。因此,我不是依靠react-select
的过滤逻辑,而是在onInputChanged
处理程序中复制过滤逻辑。这不是很好,因为我的过滤逻辑与显示的匹配项列表之间可能会有差异。react-select
都会清除搜索,这会再次调用onInputChanged
事件。因此,通过单击自定义的“添加所有匹配项”按钮,它将删除过滤器,清除列表,调用onInputChanged
并使用新的匹配项列表设置状态。为了解决这个问题,我需要有一个previousMatchingOptions
状态变量,该变量跟踪先前调用onInputChanged
时的匹配项。这似乎是一个可怕的骇客。react-select
集成得不太好。如果它是它们组件的一部分而不是它的一部分,那就更好了。values
组件的Select
属性,您可以绕过该组件对其状态的内部管理,因此,在没有重新实现所有功能的情况下,添加,删除和清除项目的常规方法不起作用在自定义onChange
处理程序中进行修改,该处理程序修改了传递到state.chosen
的{{1}}。自己管理这似乎也不可取。所以,我有一个解决方案,但是如果有人提出的建议更干净和/或更简单,我将很高兴听到它!
似乎分叉控件并在组件内部进行这些更改可能是更好的方法。
values
中,我尝试使用一些onInputChanged
黑客直接从DOM获取匹配的搜索结果,尽管这种方法因为getElementsByClassName
答案 3 :(得分:0)
您可以像这样使用filterOption
函数:
<select
options={[{label: 'test', value: 1, customData: 'bla blub test'}]}
filterOption={(option, filter) => {
const { customData } = option.customData;
if(customData.toLowerCase().indexOf(filter.toLowerCase()) >= 0) {
return true;
}
}} />
希望这会对您有所帮助:)