Toggle Password Visibility for multiple password inputs - reactjs

So if I'm using on input I can toggle password visibility.
I'm having trouble with it only toggling one input at a time.
D
Currently my code looks like this..
const [isPasswordShown, setPasswordShown] = useState(false);
const togglePassword = () => {
setPasswordShown(isPasswordShown ? false : true);
};
const renderTogglePasswordIcon = () => {
return (
<FontAwesomeIcon
onClick={togglePassword}
icon={isPasswordShown ? faEye : faEyeSlash}
/>
);
};
<Input
variant={InputVariants.text}
type={isPasswordShown ? "text" : "password"}
name="password"
label="Password"
error={errors.password?.message}
onChange={(e) => handlePasswordInput(e)}
ref={register}
/>
<i>{renderTogglePasswordIcon()}</i>
<Input
variant={InputVariants.text}
type={isPasswordShown ? "text" : "password"}
name="passwordConfirmation"
label="Confirm Password"
error={errors.passwordConfirmation?.message}
ref={register}
onChange={(e) => confirmPassword(e)}
/>
<i>{renderTogglePasswordIcon()}</i>

Do you want to toggle the inputs separately or only one of the inputs?
I would only use the toggle function for one input element. So you can set the html type to password hardcoded in the second element:
<Input
variant={InputVariants.text}
type={isPasswordShown ? "text" : "password"}
name="password"
label="Password"
error={errors.password?.message}
onChange={(e) => handlePasswordInput(e)}
ref={register}
/>
<i>{renderTogglePasswordIcon()}</i>
<Input
variant={InputVariants.text}
type="password"
name="passwordConfirmation"
label="Confirm Password"
error={errors.passwordConfirmation?.message}
ref={register}
onChange={(e) => confirmPassword(e)}
/>
<i>{renderTogglePasswordIcon()}</i>
Otherwise you can use a second parameter

Related

Multiple required conditions of an input with .includes() method

I'm making validation of an email input in my React App, but I want that input should have both # and .(dot) while submitting the form. I tried the .some() method but if only one condition is true then it will return true but I want both:
const emailValidation = ["#", "."];
<input
type="text"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
onBlur={(e) => {
setIsEmailValid(
emailValidation.some((el) => e.target.value.includes(el))
);
}}
/>
<input
type="text"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
onBlur={(e) => {
setIsEmailValid(
emailValidation.every((el) => e.target.value.includes(el))); }}
/>
Here you just need to use every() method instead of some()

How can I set the textfield as disabled and when typed, it will be enabled again?

How can I code this where the textfield's original state will be disabled and then when typed in, it will be enabled. Then that textfield will be the only one be updated when submitted?
<form onSubmit={handleSubmit}>
<TextField
id="input"
margin="dense"
type="text"
label="Name"
placeholder={user.displayName}
value={displayName}
fullWidth
onChange={(e) => setdisplayName(e.target.value)}
/>
<TextField
disabled
margin="dense"
type="text"
label="address"
value={address}
fullWidth
onChange={(e) => setAddress(e.target.value)}
/>
<Button type="submit">Update</Button>
</form>
Even though you disable one input, It still re-render everytime you typing (because you setState on change). You can use ref like this to prevent unnecessary render.
const nameRef = useRef(null);
const addressRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
console.log(nameRef.current.value);
console.log(addressRef.current.value);
};
return (
<div>
<form onSubmit={handleSubmit}>
<TextField
id="input"
margin="dense"
type="text"
label="Name"
placeholder={user.displayName}
fullWidth
inputRef={nameRef}
/>
<TextField
margin="dense"
type="text"
label="address"
fullWidth
inputRef={addressRef}
/>
<Button type="submit">Update</Button>
</form>
)
You can add a validation on handleSubmit because if a textfield is disabled, you need another action to make it enable and it's not ok for the user also.
You can try to add something like:
const handleSubmit = () => {
if ((displayName === "" || displayName == null) && (address == "" || address === null) {
//show error for user that both fields have to be completed
} else {
//do the form submit
}
}

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

How to use innerRef in ReactStrap ? #TypeError: Cannot read property 'username' of undefined

I want to fetch form data from innerRef in Reactstrap. But I am getting TypeError: Cannot read property 'username' of undefined
Code
<FormGroup>
<Label htmlFor="username"> Username</Label>
<Input
innerRef={(input) => (this.username.value = input)}
type="text"
name="username"
id="username"
/>
</FormGroup>
ErrorScreenshot
You can do something like this;
For stateless function component:
const Header = () => {
let username: any;
let password: any;
let checkbox: any;
const handleLogin = (event: any) => {
console.log(
"Username" +
username?.value +
"Password" +
password?.value +
"Checkbox" +
checkbox?.value
);
event.preventDefault();
};
return (
<Form onSubmit={handleLogin}>
<FormGroup>
<Label htmlFor="username">Username</Label>
<Input
type="text"
id="username"
name="username"
innerRef={(x) => (username = x)}
/>
</FormGroup>
<FormGroup>
<Label htmlFor="password">Password</Label>
<Input
type="password"
id="password"
name="password"
innerRef={(x) => (password = x)}
/>
</FormGroup>
<FormGroup check>
<Label>Remember</Label>
<Input type="checkbox" name="remember" innerRef={(x) => (checkbox = x)} />
</FormGroup>
<Button className="bg-primary" type="submit" name="submit">
Login
</Button>
</Form>
);
};

Focus kickout on custom redux form input

I got this redux form input :
<Field
component={MyCustomComponent}
name={name}
type={type}
/>
Using this custom element (bootstrap) :
<FormGroup controlId='login'>
<FormControl name={name} placeholder={name} value={props.value} onChange={input.onChange} {...props} />
</FormGroup>
And I use it like so :
<Input type='text' name='email' placeholder='Email' {...email} />
<Input type='password' name='password' placeholder='Password' {...password} />
Something strange happens. When I select the input and I try to write something inside, I am automatically kicked out of the input (focus).
When I try to write it again, everything works.
It's only when I select it for the first time after that the page is loaded.
Full form :
<Form onSubmit={handleSubmit(this.onLogin)}>
<div>
<Input type='text' name='email' placeholder='Email' {...email} />
<Input type='password' name='password' placeholder='Password' {...password} />
</div>
<Button type='submit' bsStyle='primary' bsSize='large' active>
<FormattedMessage
id='login.select-label'
defaultMessage='Login'
/>
</Button>
</Form>
Full input :
export const Input = (props) => {
const { name, type } = props
const MyCustomComponent = ({input}: props) => (
<FormGroup controlId='login'>
<FormControl name={name} placeholder={name} value={props.value} onChange={input.onChange} {...props} />
</FormGroup>
)
return (
<Field
component={MyCustomComponent}
name={name}
type={type}
/>
)
}

Resources