Forms Validation in ReactJS


Create new folder named LearnReactJSWithRealApps and select to this folder in
Visual Studio Code

Open Terminal windows in Visual Studio Code and type:

npm install -g babel
npm install -g babel-cli
npm install webpack --save
npm install webpack-dev-server --save
npm install react --save
npm install react-dom --save
npm install --save-dev style-loader
npm install --save-dev css-loader




In root folder of project, create new folder src\components. In this folder, create new file named demo.component.jsx as below:

import React from 'react';

class DemoComponent extends React.Component {

    constructor() {
        super();
        this.state = {
            fields: {},
            errors: {}
        }
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleValidation() {
        let fields = this.state.fields;
        let errors = {};
        let formIsValid = true;

        // Username
        if (!fields["username"]) {
            formIsValid = false;
            errors["username"] = "This field is required.";
        }

        if (typeof fields["username"] !== "undefined") {
            var length = fields["username"].length;
            if (length < 3 || length > 10) {
                formIsValid = false;
                errors["username"] = "Please enter a value between 3 and 10 characters long.";
            }
        }

        // Password
        if (!fields["password"]) {
            formIsValid = false;
            errors["password"] = "This field is required.";
        }
        if (typeof fields["password"] !== "undefined") {
            var length = fields["password"].length;
            if (length < 3 || length > 10) {
                formIsValid = false;
                errors["password"] = "Please enter a value between 3 and 10 characters long.";
            } else {
                var passwordValid = fields["password"].match(/^((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})$/i);
                if (!passwordValid) {
                    formIsValid = false;
                    errors["password"] = "Your password does not meet complexity requirements.";
                }
            }
        }

        // Age
        if (!fields["age"]) {
            formIsValid = false;
            errors["age"] = "This field is required.";
        }
        if (typeof fields["age"] !== "undefined") {
            var ageValid = fields["age"].match(/^\d+$/);
            if (!ageValid) {
                formIsValid = false;
                errors["age"] = "Please enter a valid number.";
            } else {
                var age = parseInt(fields["age"]);
                if (age < 18 || age > 120) {
                    formIsValid = false;
                    errors["age"] = "Please enter a value between 18 and 120.";
                }
            }
        }

        // Email
        if (!fields["email"]) {
            formIsValid = false;
            errors["email"] = "This field is required.";
        }
        if (typeof fields["email"] !== "undefined") {
            var emailValid = fields["email"].match(/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/);
            if (!emailValid) {
                formIsValid = false;
                errors["email"] = "Please enter a valid email address.";
            }
        }

        // Website
        if (typeof fields["website"] !== "undefined") {
            var websiteValid = fields["website"].match(/(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))/);
            if (!websiteValid) {
                formIsValid = false;
                errors["website"] = "Please enter a valid URL.";
            }
        }

        this.setState({ errors: errors });
        return formIsValid;
    }

    handleChange(event) {
        let fields = this.state.fields;
        let field = event.target.name;
        fields[field] = event.target.value;
        this.setState({ fields });
    }

    handleSubmit(event) {
        event.preventDefault();
        if (this.handleValidation()) {
            alert("Form submitted");
        } else {
            alert("Form has errors.")
        }
    }

    render() {
        return (
            <div>
                <form onSubmit={this.handleSubmit.bind(this)}>
                    <table cellPadding="2" cellSpacing="2">
                        <tr>
                            <td>Username</td>
                            <td>
                                <input name="username" type="text" onChange={this.handleChange} value={this.state.fields["username"]} />
                            </td>
                            <td>
                                <span style={{ color: "red" }}>{this.state.errors["username"]}</span>
                            </td>
                        </tr>
                        <tr>
                            <td>Password</td>
                            <td>
                                <input name="password" type="password" onChange={this.handleChange} value={this.state.fields["password"]} />
                            </td>
                            <td>
                                <span style={{ color: "red" }}>{this.state.errors["password"]}</span>
                            </td>
                        </tr>
                        <tr>
                            <td>Age</td>
                            <td>
                                <input name="age" type="text" onChange={this.handleChange} value={this.state.fields["age"]} />
                            </td>
                            <td>
                                <span style={{ color: "red" }}>{this.state.errors["age"]}</span>
                            </td>
                        </tr>
                        <tr>
                            <td>Email</td>
                            <td>
                                <input name="email" type="text" onChange={this.handleChange} value={this.state.fields["email"]} />
                            </td>
                            <td>
                                <span style={{ color: "red" }}>{this.state.errors["email"]}</span>
                            </td>
                        </tr>
                        <tr>
                            <td>Website</td>
                            <td>
                                <input name="website" type="text" onChange={this.handleChange} value={this.state.fields["website"]} />
                            </td>
                            <td>
                                <span style={{ color: "red" }}>{this.state.errors["website"]}</span>
                            </td>
                        </tr>
                        <tr>
                            <td>&nbsp;</td>
                            <td><input type="submit" value="Save" /></td>
                        </tr>
                    </table>
                </form>
                <div ref="result"></div>
            </div>
        );
    }

}

export default DemoComponent;




In root folder of project, create new file named main.js as below:

import React from 'react';
import ReactDOM from 'react-dom';

import DemoComponent from './src/components/demo.component.jsx';

ReactDOM.render(<DemoComponent />, document.getElementById('app'));

In root folder of project, create new file named webpack.config.js as below:

var config = {
    entry: './main.js',

    output: {
        path: __dirname,
        filename: 'index.js',
    },

    devServer: {
        inline: true,
        port: 8081 // server port
    },

    module: {
        loaders: [
            {
                test: /\.css$/,
                loader: 'style-loader'
            },
            {
                test: /\.css$/,
                loader: 'css-loader',
                query: {
                    modules: true,
                    localIdentName: '[name]__[local]___[hash:base64:5]'
                }
            },
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                query: {
                    presets: ['es2015', 'react']
                }
            }
        ]
    }
}

module.exports = config;

In root folder of project, create new file named index.html as below:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Learn ReactJS With Real Apps</title>
</head>
<body>

    <div id="app"></div>
    <script src="index.js"></script>

</body>
</html>

In root folder of project, create new file named package.json as below:

{
  "name": "learnreactjswithrealapps",
  "version": "1.0.0",
  "description": "Learn ReactJS With Real Apps",
  "main": "main.js",
  "dependencies": {
    "babel-core": "^6.24.0",
    "babel-loader": "^6.4.1",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "webpack": "^2.3.2",
    "webpack-dev-server": "^2.4.2"
  },
  "devDependencies": {
    "css-loader": "^0.28.11",
    "style-loader": "^0.21.0"
  },
  "scripts": {
    "start": "webpack-dev-server"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/reactjs/react-tutorial.git"
  },
  "keywords": [
    "react"
  ],
  "author": "PMK Lab",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/reactjs/react-tutorial/issues"
  },
  "homepage": "https://github.com/reactjs/react-tutorial#readme"
}




In Terminal windows in Visual Studio Code and type: npm start,
program will open url http://localhost:8081/ on browser