React Materialize Switch Always Has the Value "on" - reactjs

I'm using the React Switch component straight from this website: http://react-materialize.github.io/react-materialize/?path=/story/components-switch--switch. I put this into my SideNav like so:
<Switch
id="Switch-11"
offLabel="Off"
onChange={(e) => exampleFunction(e)}
onLabel="On"
/>
I did it so that when the switch is clicked, it would call "exampleFunction()" which contains this:
const exampleFunction = (e) => {
console.log(e.target.value)
}
The problem is that when I look at the console for the value of the switch, it is always "on," even if I press it multiple times. I'm a little lost as to why this happens. Any advice would be appreciated. Thanks.

If you want to know whether the checkbox is checked, you need to use e.target.checked, looking at the source code from materialize, we can see the onChange is passed directly to the input element, so you need to use the checked attribute of the input element.
The value attribute has the following definition:
The value property sets or returns the value of the value attribute of a checkbox.
For checkboxes, the contents of the value property do not appear in the user interface. The value property only has meaning when submitting a form. If a checkbox is in checked state when the form is submitted, the name of the checkbox is sent along with the value of the value property (if the checkbox is not checked, no information is sent).
From: https://www.w3schools.com/jsref/prop_checkbox_value.asp

Related

How to correctly synchronize the internal state of the input field with the React Hook Form value

I am using the MUI component library with RHF.
For quick form creation, I want to create my collection of form fields to be controlled by RHF.
But I'm facing a problem synchronizing the internal state of some complex fields, like DatePicker, with the state of the form.
For simple input components like TextField I don't create an additional internal state because I don't need to transform the value entered by the user before sending it to the form.
However, components like the DatePicker work with complex objects like the Moment object. I want to get a formatted value like "2022-02-02" after submitting the form, so I create an internal state that contains the Moment value and call RHF onChange with the formatted value I want.
const [momentValue, setMomentValue] = useState(() => getMomentDateTime(value));
const handleChange = useCallback(
(newValue) => {
setMomentValue(newValue);
onChange(
newValue && newValue.isValid()
? newValue.format(format)
: '',
);
},
[format, onChange],
);
This approach works fine until the external action is on the field.
For example, I have two date input fields at the level above. When I change the first one, I should automatically set the second one to "date of the first field + 1 day". To do this, I use setValue. This method will update the form's value but not the internal state's value. Therefore, the UI will not be updated.
I have to use useEffect, keep track of the form value change, compare it to the internal value, and update as needed.
useEffect(() => {
if (value !== momentValue.format(format)) {
setMomentValue(getMomentDateTime(value));
}
}, [format, momentValue, value]);
I wouldn't say I like this approach. A similar check for MultipleSelect looks even more complicated.
How can this problem be solved correctly? Thanks.

react-select onChange how to access user input and not select option value?

I'm new to this library, I'm not sure if I missed something in the docs...
I'm trying to console.log the user's input through an onChange event (your average onChange that fires every time the input field changes). However the event only fires when a user selects an option, and the value that get's logged is the value of one of the select options, not the user input.
I'm guessing it's because it's more of a select option type of component, rather than an input component.
How do I go around implementing what I want here?
<Select onChange = {handleChange} options = {data} />
const handleChange = (e) => {
console.log(e)
}
EXTRA NOTE:
My purpose for accessing the user input is, because my data array containst more than 7000 items, to change the data array to render less than 10 items according to use input, so that my app doesn't lag.

How to enable tabbing through a select field in an Antd form?

By default with AntD forms when tabbing through fields and coming across a Select field, the user inputted value doesn't stay when tabbing to the next field. How do I fix that? I've been trying various ways of using onBlur to set the Select field when the user tabs out of it but can't get it to work.
I created a simple codesandbox here to illustrate my problem.
CodeSandBox Example
For example to reproduce what i'm referring to..
input something into the first input field and then hit tab to move focus to the second input field (the select dropdown).
input one of the options using the keyboard such as "A".
Tab to the third field. Note the second field (the Select dropdown) doesn't stay populated with the inputted value. The only way to get it to stay is to use your mouse to select it. Which isn't a good user experience.
It's the normal behavior of antd. It doesn't stay because the Select has no value and even you type the exact value and hit the tab it will not stay because it has no value, you need to select in options list in order the input to stay. The purpose of the search is to select an option quickly, not setting the value on the Select
One solution is to make the Select to be a controlled component, meaning the value will be based on state value:
this.state = {
...
second: undefined,
}
onSearch = (value) => {
if (value.trim()) {
this.setState(() => ({ second: value.toUpperCase() }));
}
};
<Select
value={this.state.second}
onSearch={this.onSearch}
>
Beware that this is not the better approach, the user can type anything to it even the input was not on the option list. I suggest to look on antd component called Autocomplete. You can achieve the same goal but a good choice if you allow the user to type in to it even the input is not in the option list.

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