React Form: Password Confirmation and Not Required Field

Now that we have form validation using state, Let's add some improvements to our form app so that we can advance into more complex stuff later. We are going to add a password confirmation field, and an optional comment textarea element into our form. With what we have learned so far, this should be pretty easy 👌

Password Confirmation Field

As it works in any platform, password confirmation field only need to be not empty and its value matched password field. We can add another state into our app for this field's value.

this.state = {
  email: '',
  username: '',
  password: '',
  comment: '',
  passwordConfirmation:'',
  formErrors: {
    email: '',
    username:'', 
    password: '', 
    passwordConfirmation: '',
  },
  formValidity: {
    email: false,
    username: false, 
    password: false, 
    passwordConfirmation: false,
  },
  canSubmit: false,
};

Next, let's update our form to render a password confirmation field:

<div className="form-group">
  <label htmlFor="passwordConfirmation">Password Confirmation</label>
  <input
    className={`form-control ${this.errorClass(this.state.formErrors.passwordConfirmation)}`}
    id="passwordConfirmation"
    name="passwordConfirmation"
    type="password"
    placeholder="Enter password again"
    value={this.state.passwordConfirmation}
    onChange={this.handleChange}
  />
  <div className="invalid-feedback">{this.state.formErrors.passwordConfirmation}</div>
</div> 

Now it's time for the validation logic. First, we have to check if the current field being validated is the password confirmation field. We will compare the value with password property value from state only if it is password confirmation field. Also, since our state property name is passwordConfirmation, it will be nice to make it prettier during error as password confirmation. We have to change fieldValidationErrors to use label in the assignment.

validateField(name, value) {
  const isPasswordConfirmation = name === "passwordConfirmation"
  // using label instead of name now
  const label = name === "passwordConfirmation"? 'password confirmation' : name

  /*

   ... the rest of the code
  
  */

  validity[name] = value.length >0
  fieldValidationErrors[name] = validity[name] ? '': `${label} is required and cannot be empty`

  if(validity[name]) {
    if(isPassword){
      validity[name] = value.length >= 5;
      fieldValidationErrors[name] = validity[name] ? '': `${label} should be 5 characters or more`
    }
    if(isEmail){
      validity[name] = emailTest.test(value);
      fieldValidationErrors[name] = validity[name] ? '' : `${label} should be a valid email address`
    }
    // password confirmation validation
    if(isPasswordConfirmation){
      validity[name] = value === this.state.password
      fieldValidationErrors[name] = validity[name] ? '' : `${label} should match password`
    }
  }

  /*

   ... the rest of the code
  
  */
  
}

Finally, we only need to add formValidity.passwordConfirmation to our canSubmit function evaluation to keep disabling submit button until the state property returns true.

this.setState({ 
  canSubmit: this.state.formValidity.email 
  && this.state.formValidity.username 
  && this.state.formValidity.password 
  && this.state.formValidity.passwordConfirmation })

Creating Not Required Field

In our current form, we have all our fields as required fields. But what if we want to add a new field that is not required? A field that can be empty if the user doesn't want to provide any information? Actually, it's pretty easy to do in React. We just have to add an if statement before our entire validateField method. Since we're keeping tracks of all required fields with our formValidity and formErrors state property, that means we can check if the name of the field being validated is included in the state property. Let's update our validateField method

validateField(name, value) {
  if(Object.keys(this.state.formValidity).includes(name)){
    /*
    ... the rest of the code here
    */
  }
}

Wow, that was easy! Let's test it our by adding a new field below our password confirmation.

<div className="form-group">
<label htmlFor="comment"> Comment:</label>
  <textarea 
  className="form-control"
  id="comment"
  name="comment" 
  value={this.state.comment} 
  onChange={this.handleChange} />
</div>

All that's left now is to add a new state property for comment and print it into the alert box on submit.

// update to state, just add a new property here
this.state = {
  comment: '',
}

// update to alert box
alert(`Your registration detail: \n 
        Email: ${email} \n 
        Username: ${username} \n
        Password: ${password} \n
        Comment: ${comment || 'no comment'}`
)

You can get the complete source code in here

Moving On

We are going to learn more advanced stuff with React form. I'm going to explore 3 things in the next posts:

  1. How to populate React form with saved data from external source
  2. How to make a wizard form for extremely long and complicated registration form
  3. How to create dynamic form inputs

Don't forget to subscribe below so that you'll be notified when the next post is released 🔔


Get my weekly newsletter ✉️
Let's explore the exciting world of React together.
No Spam. Unsubscribe anytime