React Select Keep Input Value After Selection - reactjs

I am currently working with react-select with single selection. After selecting a particular value, I would like the user to be able to edit the typed in text (not necessarily the same as the rendered option (formatOptionLabel).
https://codesandbox.io/s/react-select-course-dfmn2?file=/src/Selector.tsx
For example, if I typed in PHYS101, and then select the option PHYS101 ... joe, and then proceed to edit the text, for backspace the form would be come PHYS10 and if I type A then it would be PHYS101A.
I attempted to use the onInputChange and onChange props, but I cannot get it to work consistently. I would appreciate any suggestions or snippets of code I could use.

There is a similar issue. Maybe that could help.
Here is a link to the issue. react-select custom tag edit feature
OR
If you wanna switch over to some other library for your specific purpose.
You could use react-selectize.
You can provide props to edit the selected option.

I solved it like this.
I pulled a reference to the internals via ref
<Select
ref={selectRef}
onChange={onOptionSelect}
/>
and in the useEffect.
useEffect(() => {
const selectObj = selectRef?.current
if (selectedOption?.value && selectObj) {
selectObj.state.inputValue = selectedOption?.value
}
}, [selectedOption])

Related

Multiple selector by Material-UI

I wan to make multiple selector like this.
Choices are prepared in advance, and then user can select a few items.
At first, I think I use <Switch> component but this visual is different from what I want.
then I read about <Select> but, it is also different.
My current answer is using multiple <Button> , (but it looks a bit not cool...??)
Am I right?? or Is there any alternative??
I think this could help you to use Chip in material-ui
and then use an array to push the newly selected item to it.
const [theArray, setTheArray] = useState(initialArray);
and in a onChange kind of function push selected item to save them
setTheArray([...theArray, newElement]);

react hook form - watch vs onchange , which one would be the right approach

I am using watch,setValue and getValues to update one dropdown selected value based on another dropdown selected value.
It can be also done using dropdown list's onChange so, onChange, setValue and getValues so no need to use of watch.
Can you please guide, watch is performance cost then using onChange or it will be fine with watch how its implemented below (without onChange).
const dropdownList_1_watch_value = watch(dropdownList_1);
useEffect(()=>{
if (dropdownList_1_watch_value !== 'specificValue') && getValues(dropdownListControlName) !== defaultValue)
{
setValue(another_dropdownListControlName, defaultValue);
}},[dropdownList_1_watch_value]);
return (
<>
// list of dropdown list components and other controls
</>
);
Regarding performance there shouldn't be much of a difference between those to.
I will cite from a blog post:
React Watcher should be used sparingly, in cases where you can't
really solve the problem any other way. In most cases, where you need
to do something when some prop changes, you don't really need it. Why?
Because in most cases you can usually trigger the event together with
the action with caused the prop to be changed, e.g. when triggering a
filtering change on a listing.
Full post: http://sborrazas.com/blog/react-watcher

SunEditor In React - Validate Text Was Inputted?

Problem
I want to validate that a user has inputted actual text into the editor, ignoring html tags and whitespace.
Details
I'm using the ReactJS SunEditor Component
I'm using Typescript
Here's an example of the content when a user doesn't type in anything:
<p><br>
</p>
and another
<p> </p>
Attempted Solutions
I've tried putting a regex in the onChange event, but it's pretty clunky and probably won't take into account all the different ways non-textual content is represented; I need a better way.
const regex = /(<([^>]+)>)/ig;
Vague Ideas
I see that the SunEditor javascript api has a utility method, onlyZeroWidthSpace that returns a boolean; it may work, but I don't see how I can access it. I'm using Typescript, so maybe there's an issue there?
Thanks for your help!
Hi I am the author of the SunEditor React Component. Please the core SunEditor instance can be accessed by attaching a ref to the SunEditor component (You can review this from the documentation). Also to get plane text (non-html text), Please use the getText method on the editor object.
Example below:
editorRef.current.editor.getText()
Notice that editorRef is the ref attached to the SunEditor Component.
Here's a funky way of doing it that seems to work. Any other suggestions are quite welcome and invited.
<SunEditor
...
onChange={content => {
const contentTestContainer = document.createElement('div');
contentTestContainer.innerHTML = content;
const textContent = contentTestContainer.textContent;
if (textContent) {
props.getFieldHelpers('description').setValue(content);
}
}}
/>
All event handler is bind the core object.
onChange
editor.onChange = (contents, core) => {
// You can use the util object
core.util.onlyZeroWidthSpace();
}
You can try this:
onBlur = {(e) => console.log(e.target.innerText)}

Obtaining Selected Value in React-Select

I'm trying to implement this example that obtains the user selected value, but using the async select version.
I want to obtain the value that the user selected, but going through the docs on react-select this isn't clear how to do. If you set state equal to the inputValue, as soon as you click on the 'submit' button the inputValue is cleared. You get back
" "
instead of
user selected value
I'm not sure how to obtain the user selected value using the async select component. I have my API data successfully populating & filtering the suggestions box, but I can't figure out how to get the selected value.
I've tried numerous methods and lastly tried using the refs approach like in the above link, but the stored value shows up as null. Instead of storing the user selected value. Here is the link to my broken codesandbox.
Can anyone help or point me in the right direction?
Edit
Here is a link to a working demo if anyone gets stuck on this in the future.
So, what you got wrong is props of react-select to get value on on-change. Use onChange instead of onInputChange on your AsyncSelect Component. Both props are for different purpose. Here is a doc for all props available for react-select. https://react-select.com/props
Try code below
textChange = inputValue => { // whole object of selected option
this.setState({ inputValue:inputValue.value });
};
render(){
....
<AsyncSelect
defaultOptions
loadOptions={this.promiseOptions}
onChange={this.textChange} /** onChange triggers only when user change the
options but onInputChange triggers on each change which is for different
purpose like for e.g. when user type, fetch similar options **/
name="options"
/>
}

Testing if something is on screen with react

I have an input field with a submit button and when someone enters something that text appears on the screen. how can I test that in react?
I know how to simulate the button click but what would the expectation be? or how would I actually be able to tell if the text is there?
You would need to use refs to check the values of input fields using React. The refs provide the hooking interface between virtual DOM element of input fields to access it values.
You scry for that input element by id or type or class. And you can access the text of that element by looking at .value
I'm not sure I understand the question... the first part of your question makes me think you want to detect when a user is typing some text in an input field, but the second part makes me think you want to automate a test, placing some text in the input and simulating click on a button, kinda confusing ...
In my last project I used that package instead of a classic input: react-contenteditable
You can hook your code to events that this component is firing:
render() {
const { selectedDbItem } = this.props
return (
<div>
<ContentEditable
onBlur={(e)=>this.onBlurField(e, 'supplier')}
className="field-value"
html={selectedDbItem ? selectedDbItem.supplier : ''}
disabled={false}
onChange={(e)=>this.onChangeField(e, 'supplier')}
onKeyDown={(e) => this.onKeyDown(e)}
/>
</div>
You can then implement the callbacks onBlur, onChange, onKeyDown (for input filtering for example ...) in the containing component.
Hope that helps

Resources