Selecting created option on menu close/select blur using creatable component

Viewed 1308

Is there some way to instruct react-select to select an option on menu close or select blur, but only if it is the one created (not from default list)?

Context:

I have a list of e-mail addresses and want to allow user to select from the list or type new e-mail address and then hit Submit button. I do the select part with react-select's Creatable component and it works.

import CreatableSelect from 'react-select/creatable';

<CreatableSelect
    options={options}
    isMulti={true}
    isSearchable={true}
    name={'emailAddresses'}
    hideSelectedOptions={true}
    isValidNewOption={(inputValue) => validateEmail(inputValue)}
/>

But what happens to my users is that they type new e-mail address, do not understand they need to click the newly created option in dropdown menu and directly hit the Submit button of the form. Thus the menu closes because select's focus is stolen and form is submitted with no e-mail address selected.

I look for a way how can I select the created option before the menu is closed and the typed option disappears.

1 Answers

You can keep track of the inputValue and add the inputValue as a new option when the onMenuClose and onBlur callbacks are triggered.

Keep in mind that both onBlur and onMenuClose will fire if you click anywhere outside of the select area. onMenuClose can also fire alone without onBlur if you press Esc key so you will need to write additional logic to handle that extra edge case.

function MySelect() {
  const [value, setValue] = React.useState([]);
  const [inputValue, setInputValue] = React.useState("");
  const isInputPreviouslyBlurred = React.useRef(false);
  const createOptionFromInputValue = () => {
    if (!inputValue) return;
    setValue((v) => {
      return [...(v ? v : []), { label: inputValue, value: inputValue }];
    });
  };
  const onInputBlur = () => {
    isInputPreviouslyBlurred.current = true;
    createOptionFromInputValue();
  };
  const onMenuClose = () => {
    if (!isInputPreviouslyBlurred.current) {
      createOptionFromInputValue();
    }
    else {} // option's already been created from the input blur event. Skip.
    isInputPreviouslyBlurred.current = false;
  };
  return (
    <CreatableSelect
      isMulti
      value={value}
      onChange={setValue}
      inputValue={inputValue}
      onInputChange={setInputValue}
      options={options}
      onMenuClose={onMenuClose}
      onBlur={onInputBlur}
    />
  );
}

Live Demo

Edit React - react-select Create New Option When Blur

Related