Eddie
Eddie

Reputation: 47

React-select's selection not working together with onChange

I've run into a tiny problem - I'm using React-select's components, this is what I want to do - I have a few pairs of these components, in each pair one must be disabled unless the first value contains a certain value, e.g.:

Select 1's options: A B C Other

Select 2 is not disabled if Select 1 has option 'Other' selected.

I'm using these in a big functional component and was wondering if there was an easy way to do this. This is what I've tried so far:

Select 1:

    <Select
      isMulti={true}
      closeMenuOnSelect={false}
      options={options}
      getOptionLabel={(option) => option.name}
      getOptionValue={(option) => option}
      onChange={onChange}
      value={selected}
    />
    
Select 2:

    <Select
      isMulti={true}
      closeMenuOnSelect={false}
      options={options}
      getOptionLabel={(option) => option.name}
      getOptionValue={(option) => option}
      onChange={onChange}
      isDisabled={containsOther}
    />

Method for checking Select 1 selected values and setting them:

    let selected;
    
    const onChange = (data) => {
        console.log('on change = ' + JSON.stringify(data))
        selected = data
    }

Then I would also call some kind of a method from inside onChange, to set the 'containsOther' boolean to true, if from all selected values there is a value 'Other'. The problem is that I would have to do this for each pair of selects where I have to conditionally enable/disable one of them, and that would mean I would have to make multiple methods that are almost the same.

Is there an easy way of doing this, because this doesn't look clean?

Upvotes: 1

Views: 3031

Answers (1)

Janez Kuhar
Janez Kuhar

Reputation: 4256

Select 1's options: A B C Other

Select 2 is not disabled if Select 1 has option 'Other' selected.

Simply store the selected options (selection) of your first <Select /> component and then filter the array to see if option "Other" is selected.

You could do something like this:

const App = () => {
  const options = [
    { id: 1, name: "A" },
    { id: 2, name: "B" },
    { id: 3, name: "C" },
    { id: 4, name: "Other" }
  ];

  const [selection, setSelection] = useState([]);

  const onChange = (data) => {
    console.log("on change = " + JSON.stringify(data));
    setSelection(data);
  };

  return (
    <div>
      <Select
        isMulti={true}
        closeMenuOnSelect={false}
        options={options}
        getOptionLabel={(option) => option.name}
        getOptionValue={(option) => option}
        onChange={onChange}
        value={selection}
      />
      <Select
        isDisabled={
          selection.filter((element) => element.name === "Other").length < 1
        }
        options={options}
        getOptionLabel={(option) => option.name}
        getOptionValue={(option) => option}
      />
    </div>
  );
};

A live example: CodeSandbox

Upvotes: 3

Related Questions