26

My code works properly and when I write in the password field, the text is hidden. Is there any way to add a functionality where the user has the option to view the password if he/she wants?

 const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); return ( <div> <div className='main-content'> <form className="form" noValidate autoComplete="off"> {[{ label: "Email", state: email , type: "text", function: setEmail}, { label: "Password", state: password , type: "password", function: setPassword}, ].map((item, index) => ( <div> <TextField id="outlined-basic" key={index} label={item.label} variant="outlined" type= {item.type} onChange= {e => item.function(e.target.value)} /> <br></br><br></br> </div> ) )} </form> </div> </div> ); } 
0

7 Answers 7

71

You can change the type of the value based on some true/false state.

// Add these variables to your component to track the state const [showPassword, setShowPassword] = useState(false); const handleClickShowPassword = () => setShowPassword(!showPassword); const handleMouseDownPassword = () => setShowPassword(!showPassword); 
// Then you can write your text field component like this to make the toggle work. <TextField label='Some label' variant="outlined" type={showPassword ? "text" : "password"} // <-- This is where the magic happens onChange={someChangeHandler} InputProps={{ // <-- This is where the toggle button is added. endAdornment: ( <InputAdornment position="end"> <IconButton aria-label="toggle password visibility" onClick={handleClickShowPassword} onMouseDown={handleMouseDownPassword} > {showPassword ? <Visibility /> : <VisibilityOff />} </IconButton> </InputAdornment> ) }} /> 

In your example you use a loop to go through your field. Replacing your text field with my example would add the toggle to all the fields. Which is (probably) not what you want, so you would have to find a different way to render those fields.


// Required imports from the example. import { TextField, InputAdornment, IconButton } from "@material-ui/core"; import Visibility from "@material-ui/icons/Visibility"; import VisibilityOff from "@material-ui/icons/VisibilityOff"; 
Sign up to request clarification or add additional context in comments.

5 Comments

Navigation via tabs gets stuck on the icon button. Solution: <IconButton .... tabIndex = {- 1}>
on newer versions of MUI, these are the imports: import TextField from '@mui/material/TextField'; import InputAdornment from '@mui/material/InputAdornment'; import IconButton from '@mui/material/IconButton'; import VisibilityIcon from '@mui/icons-material/Visibility'; import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
I think that on onMouseDown event you want every time show password. So change function handleMouseDownPassword to set show true. Like this: const handleMouseDownPassword = () => setShowPassword(true);
It works without mouseDown. So what is the point?
Best answer. Two things I would change: 1) Delete const handleMouseDownPassword = () => setShowPassword(!showPassword); 2) Replace {showPassword ? <Visibility /> : <VisibilityOff />} with: {showPassword ? <VisibilityOff /> : <Visibility /> }
12

you can use the Input element of material UI that provides the facility to add an icon at the end of the text field and you can play with one click of the icon to hide and show password

here is how it looks:

hidden password mode enter image description here

show password mode enter image description here

<FormControl className={clsx(classes.margin, classes.textField)}> <InputLabel htmlFor="standard-adornment-password">Password</InputLabel> <Input id="standard-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} > {values.showPassword ? <Visibility /> : <VisibilityOff />} </IconButton> </InputAdornment> } /> </FormControl> 

ref link: https://material-ui.com/components/text-fields/#InputAdornments.js

2 Comments

This is the official answer.
Very nice, thank you! This should be marked as the correct answer
8

Well, I guess something like this. It won't work well with multiple password fields.

const [showPassword, setShowPassword] = useState(false); const handleClick = () => { setShowPassword(prev => !prev); } return ( <form className="form" noValidate autoComplete="off"> {[ { label: "Email", state: email, type: "text", function: setEmail }, { label: "Password", state: password, type: "password", function: setPassword, }, ].map((item, index) => ( <div> <TextField InputProps={{ endAdornment: item.type ? 'password' ( <InputAdornment position="end"> <IconButton onClick={handleClick} edge="end" > {showPassword ? <Visibility /> : <VisibilityOff />} </IconButton> </InputAdornment> ) : null }} id="outlined-basic" key={index} label={item.label} variant="outlined" type={showPassword ? 'text' : item.type} onChange= {e => item.function(e.target.value)} /> <br></br><br></br> </div> )) } </form> 

Comments

3

You can use InputAdornment in InputProps within a material UI <TextField> as follows:

  • Start by importing InputAdornment and Icons using:

import InputAdornment from "@material-ui/core/InputAdornment"; import Visibility from "@mui/icons-material/Visibility"; import VisibilityOff from "@mui/icons-material/VisibilityOff";

  • Define the state and the functions to show/hide password:

state = { toggle_password: false, } togglePasswordHide = () => { this.setState({ toggle_password: !this.state.toggle_password }); };

  • Next inside the <TextField> add InputProps like this:

<TextField margin = "normal" required fullWidth name = "password" label = "Password" type = { toggle_password ? "text" : "password" } id = "password" size = "small" autoComplete = "current-password" onChange = { handleChange } value = { values.password } InputProps = { { endAdornment: ( <InputAdornment position="end"> { toggle_password ? ( <Visibility className = "cursor_pointer" onClick = { this.togglePasswordHide } /> ) : ( <VisibilityOff onClick = { this.togglePasswordHide } /> ) } </InputAdornment> ), } } />

Comments

1

You can add a "Show" button next to the password field selecting which the type of the input changes from type=password to type=text.

Comments

1

Most answers suggest to use <InputAdornment> with <FormControl>. However you can easily do this in fewer steps with <TextField> without using <InputAdornment>.

import IconButton from '@mui/material/IconButton' import Visibility from '@mui/icons-material/Visibility' import VisibilityOff from '@mui/icons-material/VisibilityOff' const [showPassword, setShowPassword] = React.useState(false) return ( <div> <Box sx={{ display: 'flex', position: 'relative' }}> <TextField id="password" label="Password" type={showPassword ? 'text' : 'password'} fullWidth/> <IconButton onClick={() => { setShowPassword(!showPassword) }} sx={{ position: 'absolute', right: 0, top: 0 }}> {showPassword ? <VisibilityOff /> : <Visibility />} </IconButton> </Box> </div> ) 

CodeSandbox

Comments

-1

Add a function over a "show-pwd" btn click.Perform below tasks:

  1. get the current value of the password field.
  2. set the type of password field from "password" to "text"
  3. set the value of password field to the value you fetched.(this may or may not be required)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.