React Material UI Custom Input hide/show password - reactjs

I am trying to hide/show the password when a user clicks on the eye icon, but nothing changes.The default is the password is always visible, i want it to be always hidden.
[password text input][1]
My functions look like this
const [password, setPassword] = React.useState("");
const handleClickShowPassword = () => {setShowPassword({showPassword : showPassword}) };
const handleMouseDownPassword = () => {setShowPassword({showPassword : showPassword}) };
My text input code looks like this
<CustomInput
labelText="Password"
id="pass"
value={password}
type={showPassword ? 'text' : 'password'}
formControlProps={{
fullWidth: true
}}
inputProps={{
onChange: (event) => {
const value = event.target.value;
setPassword(value)
},
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
),
autoComplete: "off"
}}
/>
{
password === ""?
<p style={{color:"#D0021B"}}>{passworderror}</p>
:null
}
<p style={{color:"#D0021B"}}>{passwordexist}</p>
</GridItem>
[1]: https://i.stack.imgur.com/litjB.png

If you are using the useState Hook, then your handler should look like this:
const handleTogglePassword = () => setShowPassword(showPassword => !showPassword);
and the IconButton should look like this:
<IconButton
aria-label="toggle password visibility"
onClick={handleTogglePassword}
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
I think you mixed setState for class components and the useState for functional components.
Take a look here: https://reactjs.org/docs/hooks-reference.html#usestate

Related

Button to view update logo

Whenever the page loads, it should load a different logo, but when I click on the icon to view the password in the PASSWORD field, it reloads the logo.
I tried to leave asynchronously but it was not the case, maybe it's a problem with react hooks
export default function Login() {
const [showPassword, setShowPassword] = React.useState(false);
const handleClickShowPassword = () => setShowPassword((show) => !show);
const handleMouseDownPassword = (
event: React.MouseEvent<HTMLButtonElement>
) => {
event.preventDefault();
};
const logo = (): string => {
switch (parseInt((Math.random() * (4 - 1) + 1).toString(), 10)) {
case 1:
return "/logo4.png";
case 2:
return "/logo2.png";
case 3:
return "/logo3.png";
default:
return "/logo3.png";
}
};
return (
<Image
src={logo().toString()}
width={150}
height={150}
alt="Página de login"
></Image>
<br />
<FormControl sx={{ m: 1, width: "25ch" }} variant="outlined">
<InputLabel htmlFor="outlined-adornment-password">
Senha
</InputLabel>
<OutlinedInput
id="outlined-adornment-password"
type={showPassword ? "text" : "password"}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
}
label="Senha"
placeholder="**********"
/>
</FormControl>
);
}
The expectation is not to load the logo function when clicking to view the password

How to hide/unhide password Material uI

I have a Login in my App and I would like to have the option to hide and unhide the password.
This is my TextField:
<TextField
className={classes.textf}
variant="standard"
placeholder="password"
onChange={(password) => setPassword(password)}
/>
The TextField component has a type prop, you can set it to either "text" or "password" to show/hide the value.
const [showPassword, setShowPassword] = useState(false);
// ...
<TextField
type={showPassword ? "text" : "password"}
placeholder="password"
/>
<button onClick={() => setShowPassword(s => !s)}>Toggle visibility</button>
This might resolve your issue,
import * as React from 'react';
import IconButton from '#mui/material/IconButton';
import FilledInput from '#mui/material/FilledInput';
import InputLabel from '#mui/material/InputLabel';
import InputAdornment from '#mui/material/InputAdornment';
import FormControl from '#mui/material/FormControl';
import Visibility from '#mui/icons-material/Visibility';
import VisibilityOff from '#mui/icons-material/VisibilityOff';
export default function InputAdornments() {
const [values, setValues] = React.useState({
password: '',
showPassword: false,
});
const handleChange = (prop) => (event) => {
setValues({ ...values, [prop]: event.target.value });
};
const handleClickShowPassword = () => {
setValues({
...values,
showPassword: !values.showPassword,
});
};
const handleMouseDownPassword = (event) => {
event.preventDefault();
};
return (
<div>
<FormControl sx={{ m: 1, width: '25ch' }} variant="filled">
<InputLabel
htmlFor="filled-adornment-
password">
Password
</InputLabel>
<FilledInput
id="filled-adornment-password"
type={values.showPassword ? 'text' : 'password'}
value={values.password}
onChange={handleChange('password')}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
edge="end">
{values.showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
}
/>
</FormControl>
</div>
);
}

How to use InputProps of TextField in <input /> element

Is there any way to use the InputProps in <input /> element instead of <TextField /> of Material UI?
My Input.js component where I have used InputProps:
const Input = ({name, handleChange, type, handleShowPassword}) => {
return(
<input
name={name}
onChange={handleChange}
require
type={type}
InputProps={name === 'password' && {
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={handleShowPassword}>
{type === 'password' ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
),
}}
/>
)
}
export default Input
SignUp.js:
const SignUp = () => {
return (
<div>
<Input name="firstName" handleChange={handleChange} />
<Input name="password" type={showPassword ? 'text' : 'password'} handleShowPassword={handleShowPassword} />
</div>
)
}
export default SignUp
Please any help would be appreciated or feel free to share if there are any other ways to achieve the result.
My suggestion is you need to use Tailwindcss, and install tailwindcss/forms package.
I just found one tailwind component that are using
<input/>
for that functionality.
Here's the link for that : https://www.hyperui.dev/components/marketing/forms

React useRef not working with Material UI TextField

why is useRef not working with Material UI TextField but works fine with a traditional html input element?
The UI:
I have a Textfield input element and above it I have a list of buttons (letters from the latin alphabet, special characters). I can focus the input bar when the component renders the first time, but if I click on one of the buttons above the input, the focus is not back on the input bar.
What I tried so far
const Search = (props) => {
const [searchTerm, setSearchTerm] = useState("");
const inputRef = useRef(null);
const handleLatinButton = (letter) => {
inputRef.current.focus();
setSearchTerm(searchTerm + letter);
};
const handleSubmit = (e) => {
e.preventDefault();
History.push("/?q=" + searchTerm);
props.onFormSubmit(searchTerm, optionValue);
setSearchTerm("");
};
useEffect(() => {
const params = new URLSearchParams(location.search);
const q = params.get("q");
setSearchTerm(q);
inputRef.current.focus();
}, []); // Am I missing something here in the array?
JSX
<Button letter="č" handleLatinButton={handleLatinButton} />
<Button letter="ḍ" handleLatinButton={handleLatinButton} />
...
<form onSubmit={handleSubmit}>
<TextField
fullWidth
label="Search..."
value={searchTerm}
onChange={handleChange}
ref={inputRef}
autoFocus="true"
InputProps={{
endAdornment: (
<InputAdornment position="start">
<IconButton type="submit">
<SearchIcon />
</IconButton>
</InputAdornment>
),
}}
/>
</form>
If I replace TextField with input, the focus works after I click on one of the latin buttons.
It's just the way MUI handles the ref...
<TextField
fullWidth
label="Search..."
value={searchTerm}
onChange={handleChange}
change this >>> ref={inputRef}
for this >>> inputRef={inputRef}
autoFocus="true"
InputProps={{
endAdornment: (
<InputAdornment position="start">
<IconButton type="submit">
<SearchIcon />
</IconButton>
</InputAdornment>
),
}}
/>
perhaps to avoid confusion change the ref name

Any way to render Icon based on text field name using material UI?

<TextField
margin='dense'
fullWidth
value={this.props.value}
name={this.props.name}
type={this.props.type}
error={this.props.error !== ''}
helperText={this.props.error !== '' ? this.props.error : ' '}
onChange={ e => this.handleChange(e) }
label={this.props.label}
variant= {this.props.variant}
id={this.props.name}
InputProps={{
endAdornment: (
<AccountCircle />
),
}}
/>
Is there any way to display different Icons based on Text field name? I mean, If the name is Email then display EmailIcon. If profile then displays AccountCircle.
here is a simple solution so you can start it from here
let icon = null;
if (this.props.name === "Password") {
icon = <Visibility />;
} else if (this.props.name === "Account") {
icon = <AccountCircle />;
}
return (
<div className={classes.root}>
<TextField
label={this.props.name}
className={classNames(classes.margin, classes.textField)}
InputProps={{
endAdornment: icon
}}
/>
</div>
);
here I have put the name as a prop in this component and depend on that prop I change the icon. you can change this to switch if you wish.
hope you got an idea.
here is a link of a demo: https://codesandbox.io/s/moo68122lp
You can do it in an elegant way, by abstracting like this:
import { AccountCircle, UserIcon, PhoneIcon } from 'some/ui/library';
const icons = {
account: AccountCircle,
user: UserIcon,
phone: PhoneIcon,
};
const FieldIcon = ({ name }) => {
const Icon = icons[name];
return Icon ? (<Icon />) : null;
};
const YourComponent = props => (
<TextField
margin='dense'
fullWidth
value={props.value}
name={props.name}
type={props.type}
error={props.error !== ''}
helperText={props.error !== '' ? props.error : ' '}
label={props.label}
variant= {props.variant}
id={props.name}
InputProps={{
endAdornment: (
<FieldIcon name={props.name} />
),
}}
/>
);

Resources