React radio not resetting the values - reactjs

I am new to reactjs. I have radio buttons that say UserA, UserB, UserC, and User D. I have multiple permission for UserA based on sub-selection of radio buttons(Like Admin, Editor, User). Similarly, for UserD I can have only one permission like SuperAdmin. Whenever I select UserD, it should set the permission to 'Super Admin' which is working. But If I select another radio button, User D is not unselecting.
I believe it is because I am using the name as 'permission' on both the input fields(User D and UserA Admin sub option) which is not resetting the values in the state.
Here is the codepen for your reference. Any help would be much appreciated.
Thank you

You must have all input[radio-button]'s structure similar. You must be updating the state based on a condition. This code worked for me based on the given requirement. I have made some minor changes to the input userD and setState method. I hope this resolves your problem.
export default function Form() {
const [state, setState] = React.useState({
user: '',
testRequest: false,
permission: ''
});
const [disableuserA, setdisableuserA] = React.useState(false);
const [value, setValue] = React.useState(0);
const [selected, setSelected] = React.useState('');
function handleChange(e) {
const value =
e.target.type === 'checkbox' ? e.target.checked : e.target.value;
setState({
...state,
[e.target.name]: value,
...(e.target.name == 'user' &&
e.target.value == 'userD' && { permission: 'superAdmin' })
});
setSelected(e.target.value);
}
return (
<div className="app">
<form onSubmit={handleFormSubmit}>
<div>
<div>
<input
type="checkbox"
name="testRequest"
value={value}
onClick={() => setdisableuserA(!disableuserA)}
checked={state.testRequest}
onChange={handleChange}
/>
Enable this to hide the User A option
</div>
<div className="heading">user</div> <br />
<input
disabled={disableuserA}
type="radio"
name="user"
value="userA"
checked={selected === 'userA' || selected === 'admin'}
onChange={handleChange}
/>
UserA
<input
type="radio"
name="user"
value="userB"
checked={state.user === 'userB'}
onChange={handleChange}
/>
UserB
<input
type="radio"
name="user"
value="userC"
checked={state.user === 'userC'}
onChange={handleChange}
/>
UserC
<input
type="radio"
name="user"
value="userD"
checked={state.user === 'userD'}
onChange={handleChange}
/>
UserD
<br /> <hr />
<div
aria-hidden={
selected !== 'userA' &&
selected !== 'admin' &&
selected !== 'editor' &&
selected !== 'publisher'
? true
: false
}
>
<input
type="radio"
name="permission"
value="admin"
checked={state.permission === 'admin'}
onChange={handleChange}
/>{' '}
Admin
<input
type="radio"
name="permission"
value="editor"
checked={state.permission === 'editor'}
onChange={handleChange}
/>{' '}
Editor
<input
type="radio"
name="permission"
value="publisher"
checked={state.permission === 'publisher'}
onChange={handleChange}
/>{' '}
Publisher
</div>
<br /> <br />
<button type="submit" className="btn-default btn">
Submit{' '}
</button>
</div>
</form>
<pre>{JSON.stringify(state, null, 3)}</pre>
</div>
);
}
Live Demo

Related

Reset input on uncheck checkbox (ReactJS + Formik)

I made this component to create a field if a checkbox is checked, but how can I reset this field value if I write something and then uncheck?
const InputCheckbox = ({name, size}) => {
const [checkAmount, setCheckAmount] = useState(false);
return(
<div>
<label htmlFor={size}>
<Field type="checkbox" name={name} value={size} onClick={()=> {checkAmount === false ? setCheckAmount(true) : setCheckAmount(false)}} />
{size}
</label>
{checkAmount === false ? null : <div className="form-control-amount">
<label htmlFor={`sizeamount.${size}`}>{size}</label>
<Field className="form-control-amount" type="number" name={`sizeamount.${size}`} />
</div>}
</div>
)
}
You can use Formik's setFieldValue function to reset the field when the checkbox is unchecked.
Your component:
const InputCheckbox = ({name, size, setFieldValue }) => {
const [checkAmount, setCheckAmount] = useState(false);
return(
<div>
<label htmlFor={size}>
<Field type="checkbox" name={name} checked={checkAmount} value={size} onClick={()=> {checkAmount === false ? setCheckAmount(true) : setCheckAmount(false); setFieldValue(`sizeamount.${size}`, '')}} />
{size}
</label>
{checkAmount === false ? null : <div className="form-control-amount">
<label htmlFor={`sizeamount.${size}`}>{size}</label>
<Field className="form-control-amount" type="number" name={`sizeamount.${size}`} />
</div>}
</div>
)
}
Usage:
<Formik
initialValues={{
check: true
}}
onSubmit={(values, actions) => {
alert('Form has been submitted');
actions.setSubmitting(false);
}}
>
{({setFieldValue}) => (
<Form>
<InputCheckbox name="check" size={10} setFieldValue ={setFieldValue} />
<button type="submit">Submit</button>
</Form>
)}
</Formik>
Reference: https://formik.org/docs/api/formik
You can
<button
class="btn btn-primary pull-right"
type="reset"
onClick={(e) => {
e.preventDefault();
props.resetForm()
}}
>Eliminar filtros</button>

Clear values in number input in React

I have two radio buttons, under each there are two number inputs. The goal is to clear the values that belong to deselected radio immediately on selecting the other radio.
I tried to resolve it by adding the ternary operator to defaultValue:
defaultValue={props.xxx ? props.yyy.toString() : ''}
But this works only when I refresh the page after selecting the radio, which isn't what I need. What is the way to clear the fields immediately when I select the other radio? I have read all similar questions here, but nothing helped in my situation.
The code is like this:
<Input
type="radio"
id="radio1"
label=""
name="radio"
onChange={() => onSomeChange(AbC, true)}
defaultChecked={props.aaa === true}
/>
<div className={cx({hidden: props.ooo})}>
{props.xxx === AbC && (
<div>
<Input
type="number"
id="min-number"
name="min-max1"
label=""
defaultValue={props.xxx ? props.yyy.toString() : ''}
onBlur={(e) => onOtherChange(true, inputValue(e.target.value))}
/>
<Input
type="number"
id="max-number"
name="min-max1"
label=""
defaultValue={props.xxx ? props.yyy.toString() : ''}
onBlur={(e) => onOtherChange(false, inputValue(e.target.value))}
/>
</div>
)}
<Input
type="radio"
id="radio2"
label=""
name="radio"
onChange={() => onSomeChange(AbC, true)}
defaultChecked={props.aaa === true}
/>
<div className={cx({hidden: !props.ooo})}>
{props.xxx === AbC && (
<div>
<Input
type="number"
id="min-number2"
name="min-max2"
label=""
defaultValue={props.xxx ? props.yyy.toString() : ''}
onBlur={(e) => onOtherChange(true, inputValue(e.target.value))}
/>
<Input
type="number"
id="min-number2"
name="min-max2"
label=""
defaultValue={props.xxx ? props.yyy.toString() : ''}
onBlur={(e) => onOtherChange(false, inputValue(e.target.value))}
/>
</div>
)}
If you just have only 2 radio inputs and 2 text inputs, you could handle it like this for 1 radio (you could do the same for other radios in your components).
const [radioValueA, setRadioValueA] = setState(false);
const [textValueA, setTextValueA] = setState(false);
onChangeRadio = (radioType, changedValue) => {
if (radioType === 'A') {
setTextValueA('');
setRadioValueA(changedValue);
} else {
// handle other radio button - should be switch if there are many radio input
}
}
// Radio A
<Input
type="radio"
checked={radioValueA}
onChange={event => onChangeRadio('A', event.target.value)}
/>
// Text A
<Input
type="text"
checked={textValueA}
onChange={event => setTextValueA(event.target.value)}
/>
The main ideas is you must control the input text value then set it to empty (clear) when radio button onChange event trigger

react hooks: remember me checkbox in Login form not working

I have a login form functional component built using react-hooks comprising of userid, password and rememberMe checkbox.
For some reason, the checkbox is not working as in, when I click on it, it does tick or untick. Which is basically its state is not changing.
userid, password and rememberMe checkbox needs to be sent to the backend. That's why I have to couple it with inputs. If it was an independent checkbox than it would have been easy.
I have handleChange() for userid, password and I have handleChechbox() for handling checkbox.
Below is the complete code.
const Login = (props) => {
const [inputs, setInputs] = useState({
userid: "",
password: "",
rememberPassword: false,
});
const [submitted, setSubmitted] = useState(false);
const { userid, password, rememberPassword } = inputs;
// reset login status
useEffect(() => {
dispatch(loginActions.logout());
}, []);
function handleChange(e) {
const { name, value } = e.target;
setInputs((inputs) => ({ ...inputs, [name]: value }));
}
function handleChechbox(e) {
const { name, value } = e.target;
console.log("eeeeee check", e.target.type);
console.log("eeeeee check", e.target.checked);
console.log("eeeeee check inputs", inputs);
console.log("eeeeee check inputs remember", inputs.rememberPassword);
if (e.target.type === "checkbox" && !e.target.checked) {
setInputs((inputs) => ({ ...inputs, [name]: "" }));
} else {
setInputs((inputs) => ({ ...inputs, [name]: value }));
}
}
function handleSubmit(e) {
e.preventDefault();
setSubmitted(true);
if (inputs) {
// get return url from location state or default to home page
const { from } = location.state || {
from: { pathname: "/admin/summary" },
};
dispatch(loginActions.login(inputs, from));
// props.history.push("/admin/summary");
}
}
return (
<div className="Login">
<div className="login-form-container">
<div className="content">
<Form className="login-form" onSubmit={handleSubmit}>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-user"></i>
</InputGroupAddon>
<input
autoFocus
type="email"
aria-label="Username"
aria-describedby="Username"
aria-invalid="false"
placeholder="Username or Email"
name="userid"
value={userid}
onChange={(event) => handleChange(event)}
className={
"form-control" + (submitted && !userid ? " is-invalid" : "")
}
/>
{submitted && !userid && (
<div className="invalid-feedback">
Username or Email is required
</div>
)}
</InputGroup>
<InputGroup>
<InputGroupAddon
className="input-group-addon"
addonType="prepend"
>
<i className="fa fa-lock"></i>
</InputGroupAddon>
<input
type="password"
name="password"
placeholder="Password"
aria-label="password"
aria-describedby="password"
value={password}
onChange={(event) => handleChange(event)}
className={
"form-control" + (submitted && !password ? " is-invalid" : "")
}
/>
{submitted && !password && (
<div className="invalid-feedback">Password is required</div>
)}
</InputGroup>
<div className="form-actions">
<br />
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
id="rememberPassword"
name="checkbox"
checked={rememberPassword}
onChange={(event) => handleChechbox(event)}
// required
/>
<label className="form-check-label" for="rememberPassword">
Remember me
</label>
</div>
</div>
</Form>
</div>
</div>
</div>
);
};
You're reading the name attribute which is 'checkbox' not 'rememberPassword'. I'd imagine a simple console log of inputs would reveal you're setting the wrong property name.
Anyway your input is controlled, you don't need to read DOM values since you know that the value is and what it should change to.
function handleRememberMeChange(e) {
setInputs((inputs) => ({ ...inputs, rememberPassword: !inputs.rememberPassword }));
}
If you want it to work generically from an attribute then use id or change name to "rememberPassword". And use e.target.checked not e.target.value.
Also it's fine to do onChange={handleChechbox} instead of onChange={(event) => handleChechbox(event)} it's the same thing.

setting defaultChecked in radio button is not working in react

I need to set the defaultChecked on page load which can later be changed by the user
<input
ref={(element) => (this['input' + item.key] = element)}
name={item.key}
placeholder='Config value'
defaultChecked={item.value === true}
value='true'
type='radio'
onChange={(event) => this.validateCValue(event.target.value, item)}
/>
<label> True</label>
Radio inputs can only be checked but not unchecked, if you set it to true, the user will not be able to uncheck it, maybe you meant to use a checkbox?
const [checked, setChecked] = useState(true);
const handleChange = () => {
setChecked(checked => !checked);
};
return (
<div className="App">
<input
placeholder="Config value"
defaultChecked={checked}
type="checkbox"
onChange={handleChange}
/>
<label>{checked ? "checked" : "not checked"}</label>
</div>
);
this works for me use "checked" tp set radio button default value
<div onChange={this.sethandleValueChange.bind(this)} className={` ${(this.state.IsControlSet && this.state.RadioBtnVal=="" ? styles.control_border_red : "")}`}>
<input type="radio" value="Yes" name="RadioBtnVal" checked={this.state.RadioBtnVal=="Yes"} disabled={(this.state.FormName!="View") ? false : true}/> Yes<br/>
<input type="radio" value="No" name="RadioBtnVal" checked={this.state.RadioBtnVal==="No"} disabled={(this.state.FormName!="View") ? false : true}/> No
</div>

Reactjs Typescript form input elements value not working

I am new to React and doing a multi step contact form. I have made a handleChange function where i get value of the input, so when i go previous or next, content of the input is shown so you can edit it. First input works great, but i get problem when i put value={text} in the second input, when i click next it's stucks on the first input. Please help.
import React, {useState} from "react";
import {useStep} from "react-hooks-helper";
const Contact: React.FC = () => {
const [text, setText] = useState("")
const {index, navigation: {previous, next},} = useStep({steps: 4});
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const {value} = e.target
setText(value)
}
return (
<div className="contact">
<div className="contact-inner">
<form>
{index === 0 && <label>
<input onChange={handleChange} value={text} type="text" name="name"
placeholder={"Please enter your name"}/>
</label>}
{index === 1 && <label htmlFor="email">
<input type="text" name="email" placeholder="Please enter your email"/>
</label>}
{index === 2 && <label>
<input type="text" name="title"
placeholder="Please enter the title"/>
</label>}
{index === 3 && <label>
<textarea className="content" name="content" placeholder="Please enter your message"/>
</label>}
</form>
<div className="buttons">
<button className="previous" onClick={previous}>previous</button>
<button className="next" onClick={next}>{index === 3 ? 'Submit' : 'Next'}</button>
</div>
</div>
</div>
)
}
export default Contact
Right now you only have one text state, you should probably create a state for each of your inputs:
const [contact, setContact] = useState({
name: "",
email: "",
title: ""
});
Then you can display the correct value for each input:
<input name='email' value={contact.email} ...
And update your handleChange function:
function handleChange(event) {
const {name, value} = event.target;
setContact({ ...contact, [name]: value });
}

Resources