Create simple forms with validation in React.js



Introduction

This is the 4th article of the series "React.js with asp.net MVC application".
In the previous post, I have shown you Server-side paging and sorting in React JS Today I am going to show you, how to create simple forms with validation and save data to the database using React.js, ASP.NET MVC and entity framework.

In this series, we have already seen 3 article and all about create react component for show data from a database. Now we will see how to create a form with validation for save data to the database. As this is our first article about creating a form for save data, we will start with a very simple contact us form with 3 input fields (Full Name, Email and Message).


Just follow the following steps in order to create simple forms with validation in React.js

Here In this article, I have used Visual Studio 2013

Step - 1: Create New Project.

Go to File > New > Project > ASP.NET  Web Application (under web) > Entry Application Name > Click OK > Select Empty template > Checked MVC (under "Add folders and core references for" option) > OK

Step-2: Add a Database.

Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.

Step-3: Create a table for store data.

Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.

In this example, I have used a table as below


ContactsData Table 


Step-4: Add Entity Data Model.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.

Step-5: Add a javascript file for creating React components.

Here I have added a javascript file (ContactForm.js) in the "Scripts" folder for creating reusable react components.

Right click on your "Scripts" folder > Add > New Item > select "javascript" file > Enter name (here "ContactForm.js")> Ok.
Write following code
// Here we will create react component for generate form with validation

//React component for input component
var MyInput = React.createClass({
    //onchange event
    handleChange: function (e) {
        this.props.onChange(e.target.value);
        var isValidField = this.isValid(e.target);
    },
    //validation function
    isValid: function (input) {
        //check required field
        if (input.getAttribute('required') != null && input.value ==="") {
            input.classList.add('error'); //add class error
            input.nextSibling.textContent = this.props.messageRequired; // show error message
            return false;
        }
        else {
            input.classList.remove('error'); 
            input.nextSibling.textContent = ""; 
        }
        //check data type // here I will show you email validation // we can add more and will later
        if (input.getAttribute('type') == "email" && input.value != "") {
            if (!this.validateEmail(input.value)) {
                input.classList.add('error');
                input.nextSibling.textContent = this.props.messageEmail;
                return false;
            }
            else {
                input.classList.remove('error');
                input.nextSibling.textContent = "";
            }
        }
        return true;
    },
    //email validation function
    validateEmail: function (value) {
        var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(value);
    },
    componentDidMount: function () {
        if (this.props.onComponentMounted) {
            this.props.onComponentMounted(this); //register this input in the form
        }
    },    
    //render
    render: function () {
        var inputField;
        if (this.props.type == 'textarea') {
            inputField = <textarea value={this.props.value} ref={this.props.name} name={this.props.name}
                className='form-control' required={this.props.isrequired} onChange={this.handleChange} />
        }
        else {
            inputField = <input type={this.props.type} value={this.props.value} ref={this.props.name} name={this.props.name}
            className='form-control' required={this.props.isrequired} onChange={this.handleChange} />
            }
        return (
                <div className="form-group">
                    <label htmlFor={this.props.htmlFor}>{this.props.label}:</label>
                    {inputField}
                    <span className="error"></span>
                </div>
            );
    }
});
//React component for generate form

var ContactForm = React.createClass({
    //get initial state enent
    getInitialState : function(){
        return {
            Fullname : '',
            Email:'',
            Message : '',
            Fields : [],
            ServerMessage : ''
        }
    },
    // submit function
    handleSubmit : function(e){
        e.preventDefault();
        //Validate entire form here
        var validForm = true;
        this.state.Fields.forEach(function(field){
            if (typeof field.isValid === "function") {
                var validField = field.isValid(field.refs[field.props.name]);
                validForm = validForm && validField;
            }
        });
        //after validation complete post to server 
        if (validForm) {
            var d = {
                Fullname: this.state.Fullname,
                Email : this.state.Email,
                Message : this.state.Message
            }

            $.ajax({
                type:"POST",
                url : this.props.urlPost,
                data : d,
                success: function(data){
                    //Will clear form here
                    this.setState({
                        Fullname : '',
                        Email  : '',
                        Message : '',
                        ServerMessage: data.message
                    });
                }.bind(this),                
                error : function(e){
                    console.log(e);
                    alert('Error! Please try again');
                }
            });
        }
    },
    //handle change full name
    onChangeFullname : function(value){
        this.setState({
            Fullname : value
        });
    },
    //handle chnage email
    onChangeEmail : function(value){
        this.setState({
            Email : value
        });
    },
    //handle change message 
    onChangeMessage : function(value){
        this.setState({
            Message : value
        });
    },
    //register input controls
    register : function(field){
        var s = this.state.Fields;
        s.push(field);
        this.setState({
            Fields : s
        })
    },
    //render
    render : function(){
        //Render form 
        return(
            <form name="contactForm" noValidate onSubmit={this.handleSubmit}>
                <MyInput type={'text'} value={this.state.Fullname} label={'Full Name'} name={'Fullname'} htmlFor={'Fullname'} isrequired={true}
                    onChange={this.onChangeFullname} onComponentMounted={this.register} messageRequired={'FullName required'} />
                <MyInput type={'email'} value={this.state.Email} label={'Email'} name={'Email'} htmlFor={'Email'} isrequired={false}
                    onChange={this.onChangeEmail} onComponentMounted={this.register} messageRequired={'Invalid Email'} />
                <MyInput type={'textarea'} value={this.state.Message} label={'Message'} name={'Message'} htmlFor={'Message'} isrequired={true}
                    onChange={this.onChangeMessage} onComponentMounted={this.register} messageRequired={'Message required'} />
                <button type="submit" className="btn btn-default">Submit</button> 
                <p className="servermessage">{this.state.ServerMessage}</p>
            </form>
        );
    }
});

//Render react component into the page
        ReactDOM.render(<ContactForm urlPost="/home/SaveContactData" />, document.getElementById('contactFormArea'));
If you see, here I have created two React components named MyInput (for generating input type form components with validation function), and ContactForm (for generating form element).

Step-6: Create an MVC Controller.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.

Here I have created a controller named "HomeController"

Step-7: Add new action into your controller for getting the view, where we will show our ContactForm component (react). 

Here I have added "Index" Action into "Home" Controller. Please write this following code
public ActionResult Index()
{
    return View();
}

Step-8: Add view for your Action and design.

Right Click on Action Method (here right click on Index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add.
HTML Code
@{
    ViewBag.Title = "Create simple form with validation in React.js";
}

<div class="container">
    <h2>Create simple form with validation in React.js</h2>
    <div id="contactFormArea">

    </div>
</div>

@* Load css and js library *@

@* Bootstrap css *@
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
@* jquery library *@
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
@* React library *@
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
@* our react component  *@
<script src="~/Scripts/ContactForm.js" type="text/babel"></script>

<style type="text/css">
    .form-control.error{
        border-color:red;
        background-color:#FFF6F6;
    }
    span.error{
        color:red;
    }
    .servermessage{
        font-size:32px;
        margin-top:20px;
    }
</style>

Step-9: Add another action to your controller for save  data to the database.

Here I have created "SaveContactData" Action for saving data. Please write this following code
[HttpPost]
public JsonResult SaveContactData(ContactsData contact)
{
    bool status = false;
    string message = "";
    if (ModelState.IsValid)
    {
        using (MyDatabaseEntities dc = new MyDatabaseEntities())
        {
            dc.ContactsDatas.Add(contact);
            dc.SaveChanges();
            status = true;
            message = "Thank you for submit your query";
        }
    }
    else
    {
        message = "Failed! Please try again";
    }
    return new JsonResult { Data = new { status = status, message = message } };
}

Step-10: Run Application.

Create simple forms with validation in React.js

Hello ! My name is Sourav Mondal. I am a software developer working in Microsoft .NET technologies since 2010.

I like to share my working experience, research and knowledge through my site.

I love developing applications in Microsoft Technologies including Asp.Net webforms, mvc, winforms, c#.net, sql server, entity framework, Ajax, Jquery, web api, web service and more.