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 2013Step - 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) > OKStep-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.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.
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 codepublic 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 } }; }