skip to Main Content

I have an input field that has some validations, such as size, capital letters, special characters, among others.

Validation is like any other input field, if the user enters the requirement, then the requirement turns green, if something is missing, then it turns red.

The problem is, I want to apply these styles only after the user finishes typing the password. For example, if the requirement is to have at least 6 characters, then if the user leaves the input field, and the size of the entered value to 5, then the label turns red.

Initially, I would like all verification labels to be black, and only turn green or red depending on what the user typed.

Here’s my code I put into codesandbox.io

enter image description here

import React from "react";

class Password extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "",
      req: {
        len: "invalid",
        cap: "invalid",
        num: "invalid",
        spec: "invalid"
      }
    };
  }
  handleChange = (e) => {
    this.setState({ text: e.target.value });
  };
  render() {
    let reqState = {};

    reqState.len = this.state.text.length >= 7 ? "valid" : "invalid";
    reqState.cap = this.state.text.match(/[A-Z]/) ? "valid" : "invalid";
    reqState.low = this.state.text.match(/[a-z]/) ? "valid" : "invalid";
    reqState.num = this.state.text.match(/[0-9]/) ? "valid" : "invalid";
    reqState.spec = this.state.text.match(/[~!@#$%^&*-_]/)
      ? "valid"
      : "invalid";

    return (
      <div style={styles.login}>
        <input
          type="password"
          style={styles.inputs}
          placeholder="Password"
          value={this.state.text}
          onChange={this.handleChange}
        />

        <h4>Password Requirements</h4>
        <div style={styles.reqs}>
          <ul style={styles.requirements}>
            <li style={styles[reqState.len]}>8-13 Characters</li>
            <li style={styles[reqState.cap]}>At least 1 Capitalcase</li>
            <li style={styles[reqState.low]}>At least 1 lowercase</li>
            <li style={styles[reqState.num]}>At least 1 number</li>
            <li style={styles[reqState.spec]}>At least 1 special character</li>
          </ul>
        </div>
      </div>
    );
  }
}

export default Password;
const styles = {
  login: {
    width: "75%"
  },
  inputs: {
    display: "block",
    margin: "0 auto",
    marginTop: "20px",
    padding: "12px",
    borderRadius: "0.5"
  },
  button: {
    padding: "16px",
    marginTop: "20px",
    backgroundColor: "#113163",
    color: "#efefef",
    fontSize: "large"
  },
  reqs: {
    margin: "0 auto",
    width: "60%"
  },
  requirements: {
    textAlign: "left"
  },
  valid: {
    color: "green"
  },
  invalid: {
    color: "red"
  }
};

Can u tell me how can I do that? Thank you in advance!!


AFTER @mandy8055 CODE

enter image description here


2

Answers


  1. You can achieve your desired state by using blur event. You just need to add a new property touched to your state to keep track of whether the input field has been touched (focused and blurred) by the user. Something like:

    class Password extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          touched: false,
          // rest of state
      }
      handleBlur = () => {
        this.setState({ touched: true });
      };
      render() {
       // Rest of code
    
        const getStyle = (state) => !this.state.touched)? styles.default : styles[state];
    
        return (
          <div style={styles.login}>
            <input
              type="password"
              style={styles.inputs}
              placeholder="Password"
              value={this.state.text}
              onChange={this.handleChange}
              onBlur={this.handleBlur}
            />
    
            <h4>Password Requirements</h4>
            <div style={styles.reqs}>
              <ul style={styles.requirements}>
                <li style={getStyle(reqState.len)}>8-13 Characters</li>
                <li style={getStyle(reqState.cap)}>At least 1 Capitalcase</li>
                <li style={getStyle(reqState.low)}>At least 1 lowercase</li>
                <li style={getStyle(reqState.num)}>At least 1 number</li>
                <li style={getStyle(reqState.spec)}>At least 1 special character</li>
              </ul>
            </div>
          </div>
        );
      }
    }
    

    EDIT:

    As per your comment, to apply only the valid styles while user is typing, you need to modify the getStyle function which I provided. Add one condition:

    const getStyle = (state) => {
          if (!this.state.touched) {
            if (state === "valid") {
              return styles.valid;
            }
            return styles.default;
          } else {
            return styles[state];
          }
        };
    

    CODE SANDBOX

    Login or Signup to reply.
  2. This code will work for you on Password.js:

    import React from "react";
    
    const styles = {
      login: {
        width: "75%"
      },
      inputs: {
        display: "block",
        margin: "0 auto",
        marginTop: "20px",
        padding: "12px",
        borderRadius: "0.5"
      },
      button: {
        padding: "16px",
        marginTop: "20px",
        backgroundColor: "#113163",
        color: "#efefef",
        fontSize: "large"
      },
      reqs: {
        margin: "0 auto",
        width: "60%"
      },
      requirements: {
        textAlign: "left"
      },
      valid: {
        color: "green"
      },
      invalid: {
        color: "red"
      },
      untouched: {
        color: "black"
      }
    };
    
    class Password extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          text: "",
          req: {
            len: "invalid",
            cap: "invalid",
            num: "invalid",
            spec: "invalid"
          },
          blurred: false
        };
      }
      setBlurred = (e) => {
        this.setState({ blurred: true });
      };
      handleChange = (e) => {
        this.setState({ text: e.target.value });
      };
      render() {
        let reqState = {};
    
        reqState.len = this.state.blurred ? this.state.text.length >= 7 ? "valid" : "invalid" : "untouched";
        reqState.cap = this.state.blurred ? this.state.text.match(/[A-Z]/) ? "valid" : "invalid" : "untouched";
        reqState.low = this.state.blurred ? this.state.text.match(/[a-z]/) ? "valid" : "invalid" : "untouched";
        reqState.num = this.state.blurred ? this.state.text.match(/[0-9]/) ? "valid" : "invalid" : "untouched";
        reqState.spec = this.state.blurred ? this.state.text.match(/[~!@#$%^&*-_]/)
          ? "valid"
          : "invalid" : "untouched";
    
        return (
          <div style={styles.login}>
            <input
              type="password"
              style={styles.inputs}
              placeholder="Password"
              value={this.state.text}
              onChange={this.handleChange}
              onBlur={this.setBlurred}
            />
    
            <h4>Password Requirements</h4>
            <div style={styles.reqs}>
              <ul style={styles.requirements}>
                <li style={styles[reqState.len]}>8-13 Characters</li>
                <li style={styles[reqState.cap]}>At least 1 Capitalcase</li>
                <li style={styles[reqState.low]}>At least 1 lowercase</li>
                <li style={styles[reqState.num]}>At least 1 number</li>
                <li style={styles[reqState.spec]}>At least 1 special character</li>
              </ul>
            </div>
          </div>
        );
      }
    }
    
    export default Password;
    

    In the code above, I added an onBlur event handler in combination with the untouched style. Therefore, everything will be black until the password is touched and then blurred (lost focus).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search