How to View Password from Material UI Textfield?

Viewed 29124

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>
        );
      }
6 Answers

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";

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>

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

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.

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>
    ),
  }
}
/>

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)
Related