Frontend Development

Validating ReactJS Forms

Validating ReactJS Forms

In this snippet i will show you how to validate Reactjs forms with a ready made package called react-form-validator-core and we will see the various validation rules as well as how to create a custom rule.

 

 

 

Validating Reactjs applications can sometimes be done with a little vanilla javascript by writing a custom code to handle form validation. But when the web app becomes too big, code becomes too complicated, for that reason using a package to handle this situation is the better solution, so in this tutorial i will show how to validate forms simply by using this package react-form-validator-core.

 

This package comes with two predefined components:

  • ValidatorForm: Represent the html <form /> element but enhanced with some props useful for validation.
  • ValidatorComponent: This component represent any html input, so you need to create a custom element using this component as we will see below.

Let’s start with a simple registration form:

Register.js

import React, { Component } from 'react';

class Register extends Component
{

	state = {
		email: '',
		first_name: '',
		last_name: '',
		password: ''
	};

	handleSubmit = (e) => {
		alert('submitted successfully');
	}

	handleChange = (e) => {

		this.setState({
			[e.target.name]: e.target.value
		});
	}

	render(){

        return(
            <div className="row">
            	<div className="col-md-9 col-md-offset-3">
	                <form
	            		ref="form"
	           			 onSubmit={this.handleSubmit}
	        		>
						
                                     <div className="form-group">
                                       <input type="text" name="first_name" className="form-control"
                                          value={this.state.first_name} onChange={this.handleChange}
                                       />
                                     </div>

                                     <div className="form-group">
                                       <input type="text" name="last_name" className="form-control"
                                          value={this.state.last_name} onChange={this.handleChange}
                                       />
                                     </div>

                                     <div className="form-group">
                                       <input type="text" name="email" className="form-control"
                                          value={this.state.email} onChange={this.handleChange}
                                       />
                                     </div>

                                     <div className="form-group">
                                       <input type="password" name="password" className="form-control"
                                          value={this.state.password} onChange={this.handleChange}
                                       />
                                     </div>

			         

	            		      <button type="submit" className="btn btn-primary">submit</button>
	        		</form>
        		</div>
            </div>
        )
    }
}

export default Register;

In the above component we created a simple registration form. When you change any of the fields it stores it’s value in the state. When the user click submit the form show an alert message. But what if the user not left any of the fields unfilled we need to show an error message to fill that field.

So we will refactor that form to use the validation components mentioned above. First we need to create a custom component that represent the <input /> element. This component extends from ValidatorComponent. Second we need to replace the <form /> tag with <ValidatorForm /> component.

 

Register.js

import React, { Component } from 'react';
import { ValidatorForm } from 'react-form-validator-core';
import TextInput from './TextInput';

class Register extends Component
{

	state = {
		email: '',
		first_name: '',
		last_name: '',
		password: ''
	};

	handleSubmit = (e) => {
		alert('submitted successfully');
	}

	handleChange = (e) => {

		this.setState({
			[e.target.name]: e.target.value
		});
	}

	render(){

        return(
            <div className="row">
            	<div className="col-md-9 col-md-offset-3">
	                <ValidatorForm
	            		ref="form"
	           			 onSubmit={this.handleSubmit}
	        		>
						<TextInput
			                onChange={this.handleChange}
			                name="first_name"
			                className="form-control"
			                value={this.state.first_name}
			                validators={['required']}
			                errorMessages={['first name required']}
			            />

			            <TextInput
			                onChange={this.handleChange}
			                name="last_name"
			                className="form-control"
			                value={this.state.last_name}
			                validators={['required']}
			                errorMessages={['last name required']}
			            />

			            <TextInput
			                onChange={this.handleChange}
			                name="email"
			                className="form-control"
			                value={this.state.email}
			                validators={['required', 'isEmail']}
			                errorMessages={['email required', 'email is not valid']}
			            />

						<TextInput
			                onChange={this.handleChange}
			                name="password"
			                type="password"
			                className="form-control"
			                value={this.state.password}
			                validators={['required', 'minStringLength:5']}
			                errorMessages={['password required', 'password must have a minimum length is 5 characters']}
			            />

			            



	            		<button type="submit" className="btn btn-primary">submit</button>
	        		</ValidatorForm>
        		</div>
            </div>
        )
    }
}

export default Register;

TextIput.js

import React from 'react';
import { ValidatorComponent } from 'react-form-validator-core';

class TextInput extends ValidatorComponent {

    render() {
        const { errorMessages, validators, requiredError, validatorListener, ...rest } = this.props;

        return (
            <div className="form-group">
                <input
                    {...rest}
                    ref={(r) => { this.input = r; }}
                />
                {this.errorText()}
            </div>
        );
    }

    errorText() {
        const { isValid } = this.state;

        if (isValid) {
            return null;
        }

        return (
            <div style={{ color: 'red' }}>
                {this.getErrorMessage()}
            </div>
        );
    }
}

export default TextInput;

As you see above i have refactored the main Register component and made a lot of modifications. I created a TextInput component which extends from ValidatorComponent. The ValidatorComponent internally extends from the main React.Component class.

Next i replaced the form element with <ValidatorForm /> component. Then i replaced each input element with <TextInput /> passing in some props. The validators prop contain the validation rules. The errorMessages prop contain the error messages according to the validation rules.

In the TextInput.js we extracted some props like:

  • errorMessages: Represents an array of error messages supplied as a prop in Register component.
  • Validators: Represents the validation rules like required, isEmail, etc. look at react-form-validator-core for the available validation rules.
  • ValidatorListener: Triggered after each validation.

Then we displayed an input element like this:

<div className="form-group">
                <input
                    {...rest}
                    ref={(r) => { this.input = r; }}
                />
                {this.errorText()}
            </div>

The {…rest} expression automatically destructs props coming from the register component. so the input becomes:

<input type="text" name="name" className="form-control" onChange={} />

In the errorText() function we called isValid which is provided from ValidatorComponent and returns the validation state. If the validation state is true then the form submit successfully, otherwise we show the error messages with getErrorMessage():

const { isValid } = this.state;

        if (isValid) {
            return null;
        }

        return (
            <div style={{ color: 'red' }}>
                {this.getErrorMessage()}
            </div>
        );

Now if you run the form and click submit the errors will appear at the bottom of each element.

 

Instant Validations

To allow for instant validations which appear when the user starts to type in the input field you have to use the instanteValidate prop in the ValidatorForm like shown:

....

    <ValidatorForm
	            		ref="form"
	           			 onSubmit={this.handleSubmit}
	           			 instantValidate={true}
	        		>

.....

 

Custom Validation Rules

You can add custom validation rules using ValidatorForm.addValidationRule() function: The function takes two arguments, the first is the rule name and the second is a callback function which returns a boolean value indicating that the validation succeed of failed.

ValidatorForm.addValidationRule('rule name', (value) => {
    if (failure) {
        return false;
    }
    return true;
});

 

 

0 0 votes
Article Rating

What's your reaction?

Excited
0
Happy
0
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments