dennisN86
dennisN86

Reputation: 99

Input field validation and displayed conditions

I'm beginner to both javascript and react. As part of a homework, I should validate an input field, where a user enters his/her password. Underneath this password field the conditions the password has to match ar displayed. They should change from red to black when the password meets the condition. The application is seperated into four different components.

Problem now is my limited understanding of both react and javascript. Assuming the implemented Validation.js logic is correct, I don't know how to write a handleInputChange() function which compares this logic with the user input. Might someone lend me a hand on this or drop me a hint on how to proceed?

Thank you

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.querySelector("#root"));

App.js

import React, { Component } from "react";
import Validation from "./Validation";
import Styles from "./Styles";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: "",
      conditions: {
        special: false,
        uppercase: false,
        lowercase: false,
        number: false,
        minLength: false
      }
    };
  }

  handleInputChange(e) {
    console.log(e.target.value);

    
  }

  render() {
    return (
      <div className="wrapper">
        <div className="password field">
          <h1>Password Validation</h1>
          <form onSubmit={this.handleSubmit}>
            <div className="Password">
              <label htmlFor="Password" />
              <input
                type="text"
                placeholder="Type password here"
                onChange={this.handleInputChange}
              />
            </div>
            <div className="conditions">
              <p>The password needs to meet the following conditions:</p>
              <ul style={Styles}>
                <li className="special">
                  One Special Character{" "}
                  {this.state.value === this.state.special}
                </li>
                <li className="uppercase">
                  One Letter Uppercase {this.state.value}
                </li>
                <li className="lowercase">
                  One Letter Lowercase {this.state.value}
                </li>
                <li className="number">One Number {this.state.value}</li>
                <li className="minLength">
                  Minimum Length Of 8 Characters {this.state.value}
                </li>
              </ul>
            </div>
            <div>
              <button className="submit button" type="submit">
                Submit
              </button>
            </div>
          </form>
        </div>
      </div>
    );
  }
}

export default App;

Validation.js

import React from "react";

const Validation = value => {
  let special = `!#$%&'()*+,-./:;<=>?@[\]^_{|}~"`;

  for (let i = 0; i < special.length; i++) {
    if (value.indexOf(special[i]) > -1) {
      this.setState({
        special: true
      });
    }
  }

  let uppercase = `ABCDEFGHIJKLMNOPQRSTUVXYZ`;

  for (let i = 0; i < uppercase.length; i++) {
    if (value.indexOf(uppercase[i]) > -1) {
      this.setState({
        uppercase: true
      });
    }
  }

  let lowercase = `abcdefghijklmnopqrstuvxyz`;

  for (let i = 0; i < lowercase.length; i++) {
    if (value.indexOf(lowercase[i]) > -1) {
      this.setState({
        lowercase: true
      });
    }
  }

  let number = `0123456789`;

  for (let i = 0; i < number.length; i++) {
    if (value.indexOf(number[i]) > -1) {
      this.setState({
        number: true
      });
    }
  }

  let minLength = "";

  for (let i = 0; i < minLength.length; i++) {
    if (minLength[i] >= 7) {
      this.setState({
        minLength: true
      });
    }
  }
};

export default Validation;

Upvotes: 0

Views: 86

Answers (2)

eL_Finito
eL_Finito

Reputation: 407

I think you should create separate functions from validation js and use them. For example:

  //App.js

  hasSpecial(value) {
    const special = '!#$%&'()*+,-./:;<=>?@[\]^_{|}~"';
    return value.split("").some(char => special.includes(char));

    // or with regexp
    return /[!#$%&'()*+,-.\/:;<=>?@[\]^_{|}~"]/.test(value);
  }

  handleInputChange(value) {
    this.setState({
      value,
      conditions: {
        special: this.hasSpecial(value)
      }
    });
  }

  ...

   <input
     type="text"
     placeholder="Type password here"
     onChange={e => this.handleInputChange(e.target.value)}
     value={this.state.value}
   />

I have a few suggestions to improve your code and your skills:

  • Use const instead of let or var. link
  • Use Array's methods (map, some, reduce, forEach) instead of 'for' link
  • You can't import React in Validation.js file
  • Use object destructuring. eg.: const { value, condition: { special } } = this.state; link

Upvotes: 3

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15698

Sounds like a darn good place to make use of regular expressions (regEx)

You can write some very clean validation code like this with regEx.

I've written up an example for you here, but also see below: https://codesandbox.io/s/nkqx1zmp6j

import React from "react";

class Input extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      text: "",
      validationError: ""
    };
  }

  handleOnChange = event => {
    this.setState({
      text: event.target.value
    });
  };

  checkPassword = event => {
    event.preventDefault();
    let pattern = /^(?=.*[0-9])(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9!@#$%^&*]{5,20}$/;
    let password = this.state.text;

    if (!pattern.test(password)) {
      this.setState({
        validationError:
          "Your password needs a number, special character, lowercase letter, capital letter and can only be between 5 and 20 characters"
      });
    } else {
      console.log(true);
      this.setState({
        validationError: ""
      });
    }
  };
  render() {
    return (
      <div>
        <form onSubmit={this.checkPassword}>
          <input value={this.state.text} onChange={this.handleOnChange} />
          <button type="submit">Submit</button>
        </form>
        <p>{this.state.validationError}</p>
      </div>
    );
  }
}

export default Input;

Upvotes: 1

Related Questions