【问题标题】:React-select isMulti select all filtered optionsreact-select isMulti 选择所有过滤的选项
【发布时间】:2020-01-02 01:30:35
【问题描述】:

我需要在我的多选中添加“全选”选项。如果至少有 1 个过滤选项,则应显示它。点击“全选”然后应该只添加过滤选项(不一定是所有选项)到已选择的选项

  1. 输入为空,因此所有选项都被“过滤”:

单击“全选”选项会将所有选项添加到所选选项。

  1. 输入包含“自定义”,因此只剩下一个选项:

单击“全选”选项只会将那个选项添加到选定的选项中。

添加添加所有初始选项的“全选”选项很容易,但这不是我问题的解决方案。我设法通过手动过滤选项并将它们存储在组件状态中过滤来部分解决了我的问题,但我希望有一个更简单的解决方案。

【问题讨论】:

    标签: javascript reactjs react-select


    【解决方案1】:

    这是我用来转换所有现有多选器的函数:

    import React from "react";
    import ReactSelect from "react-select";
    
    const addSelectAllOptionIfIsMulti = (props) => {
      if (!props.isMulti) {
        return props;
      }
      const selectAllOption = {}; // just an object to be compared to by reference
    
      const getOptionLabel = (obj) =>
        obj === selectAllOption
          ? "Select all"
          : props.getOptionLabel
          ? props.getOptionLabel(obj)
          : obj.label;
    
      const getOptionValue = (obj) =>
        obj === selectAllOption
          ? selectAllOption
          : props.getOptionValue
          ? props.getOptionValue(obj)
          : obj.value;
    
      const onChange = (values) => {
        const selectedOptions = values.includes(selectAllOption)
          ? props.options
          : values;
        props.onChange(selectedOptions);
      };
    
      const options =
        props.options.length === props.value?.length
          ? props.options
          : [selectAllOption, ...props.options];
    
      return { ...props, getOptionLabel, getOptionValue, onChange, options };
    };
    
    function Select({...props}){
      return <ReactSelect {...addSelectAllOptionIfIsMulti(props)}/>
    }
    export default Select;
    

    【讨论】:

      【解决方案2】:

      我会使用filterOptionInputChangeonChange 道具的组合:

      • InputChange中,每次用户更改inputValue 并将其存储到状态时,您都会捕获它。此值将在 onChange 中重复使用。
      • 您需要更改初始filterOption 以始终显示您的Select all。原始逻辑是如果inputValuenull 返回true 否则返回trueinputValue 包含在选项标签或值中。在执行此逻辑之前,我们有另一个条件,如果选项值对应于您的 Select all 选项,则立即返回 true
      • onChange;默认情况下,返回的选项是收到的选项。然后,如果选择了一个选项(因为它是多个可以删除)并且此选项为 Select all,则您的返回值应该是所有选项的副本,并通过 inputValue 过滤它们。

      也许有一种最简单的方法,但我认为这个方法非常有效:

      onChange = (opt, { option }) => {
        let newOpts = opt;
        let string = this.state.searchField;
      
        if (option && option.value === "all") {
          let filteredOptions = clone(options);
      
          filteredOptions = filteredOptions.filter(
            filteredOption =>
              isIncludingString(string, filteredOption) &&
              !newOpts.includes(filteredOption)
          );
      
          string = null;
          newOpts = newOpts
            .concat(filteredOptions)
            .filter(newOpt => newOpt.value !== "all");
        }
        this.setState({
          searchField: string,
          values: newOpts
        });
      };
      
      onInputChange = (string, { action }) => {
        if (action === "input-change") {
          this.setState({
            searchField: string
          });
        }
      };  
      
      filterOption = ({ label, value }, string) => {
        if (value === "all") {
          return true;
        } else if (string) {
          return label.includes(string) || value.toString().includes(string);
        } else {
          return true;
        }
      };
      

      重要提示,在我的示例中,我使用来自lodashclone

      onChange中使用的isIncludingString函数下方。

      function isIncludingString(string, option) {
        let result = false;
        if (
          !string ||
          option.label.toString().includes(string) ||
          option.value.toString().includes(string)
        ) {
          result = true;
        }
        return result;
      }
      

      这里是live example

      【讨论】:

      • 嘿劳拉,谢谢你的回答。我以类似的方式解决了它。例如,如果您想要“全选”包含“3”的值,然后添加包含“4”的值,则会覆盖以前的值,则会出现错误。我也面临同样的问题
      • 我都修好了。更改了 onChange 函数中的一些内容 :) 感谢您的帮助!
      • 对于你所说的“问题”,它更多的是另一个约束;)你可以更新你的问题,我会改变我的代码以适应这个新的要求,也许可以帮助其他人。
      猜你喜欢
      • 2020-07-17
      • 1970-01-01
      • 2011-04-08
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 2022-12-03
      • 2021-08-30
      相关资源
      最近更新 更多