React-select: Creatable select

Created on 1 Oct 2018  路  15Comments  路  Source: JedWatson/react-select

Hi ,
I work with a leading Gaming Organization , we have started using this component . Lot of good work already done here , hence saved us lot of time .
We have a new feature in the on going sprint which is almost similar to what Create Select provides except for the fact that we only want the
"Create XX" option when the searched value doesn't match any option. is there any prop which we can use for this?
Also instead of "Create XX" , we want "Apply XX" is this possible?

Thanks in Advance

categorquestion issureviewed

Most helpful comment

I found out the bug.

I was using a value as an int on each option:

For example:

options = [
    { value: 1, label: "orange" },
    { value: 2, label: "apple" }
]

It doesn麓t work, if I change this value to String, it works.

I think this is a bug, it should check if the value is a String before doing toLowerCase().

All 15 comments

implement custom formatCreateLabel prop solves your problem.

Hi , I used creatable select , i managed to pull the collection of options which comes from a restful API .
whenever i try to search some thing i am getting the below error.

I am not sure why the input value is undefined
var compareOption = function compareOption(inputValue, option) {
var candidate = inputValue.toLowerCase();
return option.value.toLowerCase() === candidate || option.label.toLowerCase() === candidate;
};

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
at compareOption (Creatable.js:40)
at Creatable.js:49
at Array.some ()
at isValidNewOption (Creatable.js:48)
at Creatable.componentWillReceiveProps (Creatable.js:133)
at callComponentWillReceiveProps (react-dom.development.js:11528)
at updateClassInstance (react-dom.development.js:11720)
at updateClassComponent (react-dom.development.js:13154)
at beginWork (react-dom.development.js:13825)
at performUnitOfWork (react-dom.development.js:15864)
at workLoop (react-dom.development.js:15903)
at HTMLUnknownElement.callCallback (react-dom.development.js:100)
at Object.invokeGuardedCallbackDev (react-dom.development.js:138)
at invokeGuardedCallback (react-dom.development.js:187)
at replayUnitOfWork (react-dom.development.js:15311)
at renderRoot (react-dom.development.js:15963)
at performWorkOnRoot (react-dom.development.js:16561)
at performWork (react-dom.development.js:16483)
at flushInteractiveUpdates$1 (react-dom.development.js:16728)
at batchedUpdates (react-dom.development.js:2143)
at dispatchEvent (react-dom.development.js:4556)
at interactiveUpdates$1 (react-dom.development.js:16715)
at interactiveUpdates (react-dom.development.js:2150)
at dispatchInteractiveEvent (react-dom.development.js:4533)

return (
  <Dropdown
    isOpen={isOpen}
    onClose={this.toggleOpen}
    target={
      <Button
        iconAfter={<ChevronDown />}
        onClick={!this.props.isDisabled ? this.handleDropdownButtonClick : ''}
        isSelected={isOpen}>
        {displayValue}
      </Button>
    }>
    { !this.props.disabled &&
      <div onBlur={this.toggleOpen}>
        <CreatableSelect
          autoFocus
          styles={customStyles}
          backspaceRemovesValue={false}
          components={{ DropdownIndicator, IndicatorSeparator: null}}
          controlShouldRenderValue={false}
          hideSelectedOptions={false}
          isClearable={true}
          isDisabled={this.props.isDisabled}
          menuIsOpen
          onChange={this.onSelectChange}
          options={this.options}
          placeholder="Search..."
          styles={this.selectStyles}
          tabSelectsValue={false}
          value={value}
          matchProp='value'/>
      </div>
    }
  </Dropdown>
);

}
}

My guess is that your option.value is a number which does not have toLowerCase. I have currently the same problem.

You can try to override the isValidNewOption props

private isValidNewOption(inputValue: string, value: ValueType<any>, options: OptionsType<any>) { let returnValue = true; options.forEach((option) => { if (inputValue.toLowerCase() === option.label.toLowerCase()) { returnValue = false; } }); return returnValue; }

@mdcorriveau
Thanks for your response , yes i tried overriding this today morning after having a deeper look into the Creatable.js , My labels are JSX objects and value is never a string . It worked after overriding this function and passing it as props.
Just a quick question , The requirement is to Create XXX' only if no option meets the search criteria .
I can actually implement this logic in isValidNewOption , i can return true only if the input value is not regex matched with any of my options in my options collection.
I am actually interested if i can get any other hookpoint or prop out of the box to achieve this , or if you have a more simpler way to achieve this . Would Appreciate your response . Thanks in advance

This problem is happening with me aswell with any character, not only numbers.

I found out the bug.

I was using a value as an int on each option:

For example:

options = [
    { value: 1, label: "orange" },
    { value: 2, label: "apple" }
]

It doesn麓t work, if I change this value to String, it works.

I think this is a bug, it should check if the value is a String before doing toLowerCase().

I would not change the code of this component in my code, just use what is present in CreatableSelect. An ugly workaround can be to add the method to Number prototype (globally) and remove it when the fix will be made in this component.

// Workaround for CreateableSelect
Number.prototype.toLowerCase = function() {
return this.toString();
};

This issue is fixed by:
https://github.com/JedWatson/react-select/pull/2990

For time being, give the option values as strings.

implement custom formatCreateLabel prop solves your problem.

I didn't see formatCreateLabel prop. can you please share a sample of code?

implement custom formatCreateLabel prop solves your problem.

I didn't see formatCreateLabel prop. can you please share a sample of code?

https://react-select.com/props#creatable-props

formatCreateLabel={(inputValue) => `Apply ${inputValue}`}

I am using custom options object with this props:

<CreatableSelect
      options={options}
      value={value}
      onChange={onChange}
      getOptionLabel={getOptionLabel}
      getOptionValue={getOptionValue}
      placeholder="Select packing"
      isSearchable
      getNewOptionData={(inputValue: string): Coding => ({ code: inputValue, display: inputValue })}
      formatCreateLabel={(inputValue: string) => `Create new... ${inputValue}`}
      isValidNewOption={(inputValue: string) => !!inputValue}
/>

But never renders `Create new... ${inputValue}` The new option is correctly created, 馃

@androBermudez

I am not sure what issues you are running into but formatCreateLabel appears to be working in this sandbox.

Perhaps you could confirm if this is still an issue for you and if so, provide a codesandbox?

In the interest of of clearing out stale issues, I will be closing this as both inactive and resolved. If there are any specific issues or concerns, please feel free to reply and we can continue conversation or re-open this if necessary.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pgoldweic picture pgoldweic  路  3Comments

MalcolmDwyer picture MalcolmDwyer  路  3Comments

mbonaci picture mbonaci  路  3Comments

AchinthaReemal picture AchinthaReemal  路  3Comments

batusai513 picture batusai513  路  3Comments