-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to set current value or how to enable edit of the selected tag? #1558
Comments
This is critical for my application. I looked into 2 and couldn't find any options to do this and would greatly appreciate a workaround (couldn't come up with that either). |
Is what you both are referring to is the ability to modify an existing selection's text, ie. Say the selected text is "AAAAA" and you want to select "AAAAB" you want to delete the last letter and change it... You can't. You have to delete the whole thing and start again? If so, then I wholeheartedly agree, this seems like a really silly little bug... @JedWatson any ideas? |
@Siyfion yes, correct it is one option and another one is to set current value, thus we could remove element onclick and add set current value with focus, which will end with editing mode. |
@JedWatson I also need this for my application. Any ideas how can we implement it ? |
This would be great to implement. Does maybe one of the 137 PRs of this writing solve this? |
I have this requirement too when the select is Creatable |
@JedWatson pushing up this, just noticed that we need the same thing it's opened from February |
Looks like this ticket is a dupe of #1868 and the suggested solution is to create your own value and option component which handles the rendering and focus/edit etc. behaviour. I haven't tried myself so would be nice if somebody has a codepen/jsfiddle. |
I've just run into the same issue and haven't been able to find a solution yet. |
I see not only me has the same problem! SOLUTION, please come :P |
I was not able to resolve it. Had to do some workaround, not even close to the react-select. |
Has anyone found a solution for this? The library is great but this feature would greatly improve UX. |
Just encountered this problem: I was hoping to replace an editable-text control that I had with react-select, so that text can still be edited, just with a list of suggestions. But I can't, because react-select does not allow editing... |
I was not able to resolve it as well.. anyone came up with a solution?? |
Two years later... Another +1. @JedWatson ? |
Another +1. @JedWatson ? |
With v2.x you can overwrite the internal components of the Here is a very basic example of a Easy to implement with the help of the documentation and a look into the core code here on github. If you are looking for editable option in a simple |
Another +1, a little shocked this isn't a core feature. |
@jonnydodad Easy (using my example as reference): Edit onChange = (option, action) => {
// If you want to keep the option in the menu, make a copy of the option as this is a reference to the element in the options array.
var newOption = Object.assign({}, option);
this.setState({ value: newOption });
} Remove the SingleValue = ({ children, ...props}) => {
return (<components.SingleValue {...props}>
<input
type="text"
{ ... }
/>
</components.SingleValue>)
}; Update onEditChange = (e) => {
/* ... */
this.setState({ value: newOption })
} And for good measure remove the selection of <CreatableSelect
{ ... }
value={this.state.value}
/> And et voilà: You can now edit every option you have selected. |
@Rall3n wow awesome thank you so much! |
@jonnydodad I went with a different approach. I pulled a reference to the internals via ref <CreatableSelect
ref={ref => {
this.select = ref;
}}
/> I assigned the input value of the ref manually when the component is focused handleFocus = element => {
if (this.state.value) {
this.select.state.inputValue = this.state.value.label;
}
}; and then removed focus when the menu becomes closed handleMenuClose = () => {
this.select.blur();
}; |
Would be interested in a solution for when |
@inottawa The approach you suggested is working fine if onFocus is triggered on mouse click. If it is happening because of pressing tab key then the behaviour is similar to what we get by default. Here is the Codesandbox |
I still need this but for the AsyncSelect. Setting select.state.value etc doesn't work .. and it seems like the AsyncSelect has a select which has a select which has a select .. really weird structure 😄 |
I was struggling to get In the example code below, import is not as described in the docs, because I could not fetch Hope this helps. 'use strict'
import React from 'react'
import { AsyncCreatable } from 'react-select'
export default class MyComponent extends React.Component {
constructor(props) {
super(props)
this.select = null
this.state = {value: null, isLoading: false, menuIsOpen: false}
if (props.value) this.state.value = {label: props.value}
this.setRef = this.setRef.bind(this)
this.loadOptions = this.loadOptions.bind(this)
this.onChange = this.onChange.bind(this)
this.onInputChange = this.onInputChange.bind(this)
this.onFocus = this.onFocus.bind(this)
this.onKeyDown = this.onKeyDown.bind(this)
this.onMenuClose = this.onMenuClose.bind(this)
}
// Set reference to the select element.
// Note the nested `select` objects!
setRef(element) {
this.select = element
? element.select.select.select
: null
}
// Load options and set loading state.
loadOptions(value) {
this.setState({isLoading: true})
return new Promise(resolve => {
setTimeout(() => {
resolve([
{value: "123", label: "Fake data"}
])
this.setState({isLoading: false})
}, 1000)
})
}
// Gets called when an option is chosen or created.
onChange(value) {
this.setState({value: value})
}
// Toggle menu by presence of input.
// Reset value if input is emptied.
onInputChange(value, context) {
this.setState({menuIsOpen: !!value})
if (!value && context.action === "input-change") {
this.onChange(null)
}
}
// Restore input value.
onFocus() {
if (this.state.value) {
this.select.handleInputChange({
currentTarget: {value: this.state.value.label}
})
}
}
// Close menu when pressing enter. Submit does not work on mobile.
onKeyDown(event) {
if (event.keyCode === 13 && !this.state.isLoading) {
this.onMenuClose()
}
}
// Blur select element to trigger onFocus on next click.
onMenuClose() {
this.select.blur()
}
render() {
const { value, menuIsOpen } = this.state
return (
<AsyncCreatable
ref={this.setRef}
value={value}
menuIsOpen={menuIsOpen}
loadOptions={this.loadOptions}
// Let the select field appear as regular input.
components={{DropdownIndicator: null, IndicatorSeparator: null}}
placeholder="Enter your text..."
// Hook into events to make the editing work.
onChange={this.onChange}
onInputChange={this.onInputChange}
onFocus={this.onFocus}
onKeyDown={this.onKeyDown}
onMenuClose={this.onMenuClose}
// Create the new option at the top of the list.
createOptionPosition="first"
/>
)
}
} |
here's my example for isMulti new example using @Rall3n as a base |
My approach by replacing hidden SingleValue and enchanced Input. import React, { useCallback, useMemo, useState } from "react";
import { components as cs } from "react-select";
import CreatableSelect from "react-select/creatable";
import { colourOptions } from "./docs/data";
const NewSingleValue = () => null;
const NewInput = ({ value: inputValue, isHidden, ...props }) => {
const {
selectProps: { value, getOptionLabel }
} = props;
const label = useMemo(() => {
if (!value) {
return "";
}
return getOptionLabel(value);
}, [getOptionLabel, value]);
const v = useMemo(() => {
if (!inputValue) {
return label;
}
return inputValue;
}, [inputValue, label]);
const hidden = useMemo(() => {
if (v) {
return false;
}
return isHidden;
}, [isHidden, v]);
return <cs.Input isHidden={hidden} value={v} {...props} />;
};
const components = {
...cs,
Input: NewInput,
SingleValue: NewSingleValue
};
const CreatableSingle = props => {
const [value, setValue] = useState(null);
const handleInputChange = useCallback((inputValue, actionMeta) => {
console.group("Input Changed");
console.log(inputValue);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
}, []);
const handleChange = useCallback((value, actionMeta) => {
console.group("Value Changed");
console.log(value);
console.log(`action: ${actionMeta.action}`);
console.groupEnd();
setValue(value);
}, []);
return (
<CreatableSelect
components={components}
isClearable
onChange={handleChange}
onInputChange={handleInputChange}
options={colourOptions}
value={value}
/>
);
};
export default CreatableSingle; https://codesandbox.io/s/unr3u Should work for AsyncCreatable too. |
Here is my take at an editable Select. It's not AsyncCreatable, but should work the same way. import React, { useState, useRef } from "react";
import Select, { components } from "react-select";
const Input = (props) => <components.Input {...props} isHidden={false} />;
export default function EditableSelect() {
// This needs to become a controlled component so track state
const [value, setValue] = useState();
const [inputValue, setInputValue] = useState("");
const options = useRef([
{ label: "Editable Options", value: 1 },
{ label: "Black Magic", value: 2 },
{ label: "Very Possible ", value: 3 }
]).current;
const selectRef = useRef();
const onInputChange = (inputValue, { action }) => {
// onBlur => setInputValue to last selected value
if (action === "input-blur") {
setInputValue(value ? value.label : "");
}
// onInputChange => update inputValue
else if (action === "input-change") {
setInputValue(inputValue);
}
};
const onChange = (option) => {
setValue(option);
setInputValue(option ? option.label : "");
};
const onFocus = () => value && selectRef.current.select.inputRef.select();
return (
<div style={{ fontFamily: "sans-serif", textAlign: "center" }}>
<Select
ref={selectRef}
options={options}
isClearable={true}
value={value}
inputValue={inputValue}
onInputChange={onInputChange}
onChange={onChange}
onFocus={onFocus}
controlShouldRenderValue={false}
components={{
Input
}}
/>
<button onClick={onFocus} disabled={!value} style={{ margin: "1rem 0" }}>
Hocus Focus!
</button>
</div>
);
} |
@cention-sany just a heads up that there is a prop called |
That all said, this thread is very similar to many others and I have created a discussion here to better discuss the behavior and perhaps what a prop implementation might look like. I will close this issue and further discussion about this behavior can be had in the provided link. |
// onInputChange => update inputValue
if (action === 'input-change') {
setInputValue(inputValue);
if (inputValue.trim().length == 0 && value) {
selectRef.current.commonProps.clearValue();
}
} |
@Gian-Marco-27 cool man, that was exactly what I was searching for, thanks! |
+1 for this Still happening to me in almost 2025, this feels like a core functionality that should be supported. I have tried everything in this thread and nothing has worked for my scenario. Having to hack together the entire component just to do something like this really doesn't leave a good feeling. |
Hi guys,
The question is simple how to set current value of the input? Like when I put focus there and see already written text.
Or how to enable editing of the existing tag, that I could click and continue typing?
Thanks.
The text was updated successfully, but these errors were encountered: