jQuery form validation using JSON object and PHP
Share with Others
Tutorial by Leon Revill from Revill Web Design. I work with PHP, jQuery, HTML, CSS and mySQL every day and pass my knolwedge on through my web development blog
jQuery form validation using JSON object and PHP
There are no shortage of examples or tutorials showing you how to validate a form using jQuery and PHP but not many utilize the JSON object the most efficient way. This tutorial will also use Twitter Bootstrap to provide the UI elements and HTML layout for the tutorial.
Bootstrap HTML form
Bootstrap allows us to quickly create a HTML form so we can get to the juicy bits of this tutorial.
<!DOCTYPE html> <head> <script type='text/javascript' src='<a href="http://code.jquery.com/jquery.min.js'></script> ">http://code.jquery.com/jquery.min.js'></script> </a> <script src="../bootstrap/js/bootstrap.min.js"></script> <script src='script.js'></script> <link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen"> <link media="screen" href='style.css' rel="stylesheet" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id='frame'> <h1>Register Form</h1> <div id='response' class='alert alert-success'></div> <form class='form-horizontal' id="form1"> <div class='control-group'> <label class="control-label">Username:</label> <div class='controls'> <input type='text' class='input-large' placeholder='Username' id='username' /> </div> </div> <div class='control-group'> <label class="control-label">Real Name:</label> <div class='controls'> <input type='text' class='input-large' placeholder='Real Name' id='real-name' /> </div> </div> <div class='control-group'> <label class="control-label">E-Mail:</label> <div class='controls'> <input type='text' class='input-large' placeholder='E-Mail' id='email' /> </div> </div> <a href='#' class='btn btn-inverse btn-large pull-right submit-btn'><i class='icon-ok icon-white'></i> Submit</a> </form> </div> </body>
So, this creates us a simple but good looking form so now we can move onto the jQuery. The jQuery needs to collect all the data from the form when the submit button is pressed, send it to the PHP for validation, grab the returned data and check it for any errors.
If there are any errors then the jQuery needs to interpret the JSON objects provided by the PHP, highlight the associated field and provide the correct error message. Let's begin.
$(function(){ $('.submit-btn').click(function(){ var formInputs = new Array(); //Get the form ID var id = $(this).parent().attr('id'); $('#' + id + ' input').each(function(){ //Get the input value var inputValue = $(this).val(); //Get the input id var inputId = $(this).attr('id'); //Add them to the array formInputs[inputId] = inputValue; }); }); });
What this bit of code is doing is catching the button click of the submit-btn in a form, then checking the buttons parent for an id, using that id to then find all the input's within it and then storing the inputs id and value in an array which we can then send to the PHP script we are going to write later.
To actually send the array to the PHP we need to use an ajax call which will do a POST request to the PHP script, this is how it will look:
$(function(){ $('.submit-btn').click(function(){ var formInputs = new Array(); //Get the form ID var id = $(this).parent().attr('id'); $('#' + id + ' input').each(function(){ //Get the input value var inputValue = $(this).val(); //Get the input id var inputId = $(this).attr('id'); //Add them to the array formInputs[inputId] = inputValue; }); $.ajax({ url: 'url/to/script/here.php', type: 'POST', data: { inputs: formInputs }, success: function(data) { } }); }); });
This code will post a variable called "inputs" to the PHP script containing all the data we previously populated it with, lets jump into the PHP script now:
<?php //Create an array to store data that we will send back to the jQuery $data = array( 'success' => false, //Flag whether everything was successful 'errors' => array() //Provide information regarding the error(s) ); //Check to make sure that the inputs variable has been posted if (isset($_POST['inputs'])) { //Store the posted data into an array $inputs = $_POST['inputs']; //Loop through each input field foreach ($inputs as $input) { $id = $input['id']; $value = $input['value']; //Determine what validation we need to be doing switch($id) { //Username and real name need the same validation, so only need one case block here case "username": case "real-name": //Ensure that they are both at least 6 characters long if (strlen($value) < 6) { //To make it more readable, replace the "-"'s with spaces and make the first character upper case $msg = "Your " . str_replace("-", " ", ucfirst($id)) . " must be at least 6 characters in length"; } break; case "email": //Use PHP filter to validate the E-Mail address if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { $msg = "You must provide a valid e-mail address"; } break; default: //If some field has been passed over, we report the error $msg = "Sorry, we don't understand this data, please try again"; break; } //If there is an error, add it to the errors array with the field id if (!empty($msg)) { $data['errors'][] = array( 'msg' => $msg, 'field' => $id ); } } //Validation over, was it successful? if (empty($data['errors'])) { $data['success'] = true; } } else { $data['errors'][] = "Data missing"; } //Set the content type and charset to ensure the browser is expecting the correct data format, also ensure charset is set-to UTF-8 and not utf8 to prevent any IE issues header("Content-Type: application/json; charset=UTF-8"); echo json_encode((object)$data); ?>
The code is very well commented so most aspects should be easily understood, lets go over the main parts now.
if (isset($_POST['inputs'])) { //Store the posted data into an array $inputs = $_POST['inputs']; //Loop through each input field foreach ($inputs as $input) { $id = $input['id']; $value = $input['value'];
Here we check that the inputs were posted correctly and store them in a variable, which will be an array. We then loop through each of the inputs and create two more variables which we will then us to determine how the data needs to be validated.
//Determine what validation we need to be doing switch($id) { //Username and real name need the same validation, so only need one case block here case "username": case "real-name": //Ensure that they are both at least 6 characters long if (strlen($value) < 6) { //To make it more readable, replace the "-"'s with spaces and make the first character upper case $msg = "Your " . str_replace("-", " ", ucfirst($id)) . " must be at least 6 characters in length"; } break; case "email": //Use PHP filter to validate the E-Mail address if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { $msg = "You must provide a valid e-mail address"; } break; default: //If some field has been passed over, we report the error $msg = "Sorry, we don't understand this data, please try again"; break; }
This switch statement looks at the $id variable and decides what type of validation is required, if the $value variable does not pass the validation, we then create a $msg variable which holds the error message for that field.
//Validation over, was it successful? if (empty($data['errors'])) { $data['success'] = true; }
If there is an error message, then we add this and the field id to the main $data array which will be passed back to the jQuery.
//Set the content type and charset to ensure the browser is expecting the correct data format, also ensure charset is set-to UTF-8 and not utf8 to prevent any IE issues header("Content-Type: application/json; charset=UTF-8"); echo json_encode((object)$data);
Once validation is complete, we set the headers as explained in the code comments and then json_encode and cast the array to an object so we can reference the data within jQuery as data.success as opposed to data['success'].
This will then send a response back to the jQuery which will look something like this:
{ "success":false, "errors":[ { "msg":"Your Username must be at least 6 characters in length", "field":"username" }, { "msg":"Your Real name must be at least 6 characters in length", "field":"real-name"}, { "msg":"You must provide a valid e-mail address", "field":"email" } ] }
Now we have a PHP script that takes the data provided, validates it and provides an appropriate response, lets complete the jQuery script.
$(function(){ //Hide the error/success message response on load $('#response').hide(); $('.submit-btn').click(function(){ //Hide the reponse from last time $('#response').hide(); var formInputs = new Array(); //Get the form ID var id = $(this).parent().attr('id'); $('#' + id + ' input').each(function(){ //Remove any previously set errors $(this).removeClass('error'); //Create a temp object that holds the input data var obj = { 'value': $(this).val(), 'id': $(this).attr('id') }; //Add the object to the array formInputs.push(obj); }); $.ajax({ url: 'validate.php', type: 'POST', data: { 'inputs': formInputs }, success: function(data) { //Check to see if the validation was successful if (data.success) { //Turn the response alert into a success alert $('#response').addClass('alert-success'); $('#response').removeClass('alert-error'); //Add the success message text into the alert $('#response').html("<i class='icon-ok'></i> Form validated successfully!").fadeIn(); } else { //There were some errors //Turn the response alert into an error alert $('#response').removeClass('alert-success'); $('#response').addClass('alert-error'); //Create a message and a HTML list to display in the response alert var list = "<p><i class='icon-remove-sign'></i> There following errors occured: </p><ul>"; $.each(data.errors, function(){ $('#' + this.field).addClass('error'); list += "<li>" + this.msg + "</li>"; }); list += "</ul>"; //Add the HTML to the response alert and fade it in $('#response').html(list).fadeIn(); } } }); }); });
Once more the code is well commented to make it as easy to understand as possible. Lets take a look at how this jQuery handles the response from the PHP.
success: function(data) { //Check to see if the validation was successful if (data.success) { //Turn the response alert into a success alert $('#response').addClass('alert-success'); $('#response').removeClass('alert-error'); //Add the success message text into the alert $('#response').html("<i class='icon-ok'></i> Form validated successfully!").fadeIn(); } else { //There were some errors //Turn the response alert into an error alert $('#response').removeClass('alert-success'); $('#response').addClass('alert-error'); //Create a message and a HTML list to display in the response alert var list = "<p><i class='icon-remove-sign'></i> There following errors occurred: </p><ul>"; $.each(data.errors, function(){ $('#' + this.field).addClass('error'); list += "<li>" + this.msg + "</li>"; }); list += "</ul>"; //Add the HTML to the response alert and fade it in $('#response').html(list).fadeIn(); } }
The "data" variable within the success function() will hold the JSON objects that is sent back from the PHP, the first thing we do is check to see if there was a successful validation or not by doing:
if (data.success) {
The PHP will set this to true if there were no error messages created from the validation. If this is set to true then we just add and remove a class from the alert to display a nicely styled success message, thanks to twitter bootstrap.
If success is set to false, then we need to loop through each of the messages and add the .error class to the input elements which will turn them red and then display a list of errors within the alert, using the following code:
//There were some errors //Turn the response alert into an error alert $('#response').removeClass('alert-success'); $('#response').addClass('alert-error'); //Create a message and a HTML list to display in the response alert var list = "<p><i class='icon-remove-sign'></i> There following errors occured: </p><ul>"; //Loop through each error message and add it to the list $.each(data.errors, function(){ $('#' + this.field).addClass('error'); list += "<li>" + this.msg + "</li>"; }); list += "</ul>"; //Add the HTML to the response alert and fade it in $('#response').html(list).fadeIn();
And that's it! All there is to do is add some CSS so it looks very nice! Here you go:
/* Lets use a Google Web Font :) */ @import url(<a href="http://fonts.googleapis.com/css?family=Finger+Paint">http://fonts.googleapis.com/css?family=Finger+Paint</a>); /* Basic CSS for positioning etc */ body { font-family: 'Finger Paint', cursive; background-image: url('bg.jpg'); } #frame { width: 400px; margin: auto; margin-top: 125px; border: solid 1px #CCC; /* SOME CSS3 DIV SHADOW */ -webkit-box-shadow: 0px 0px 10px #CCC; -moz-box-shadow: 0px 0px 10px #CCC; box-shadow: 0px 0px 10px #CCC; /* CSS3 ROUNDED CORNERS */ -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; border-radius: 5px; background-color: #FFF; } #form1 { padding: 20px; min-height: 150px; } #form1 input { width: 100%; } #form1 label { width: 80px; } #form1 .controls { margin-left: 110px; } #frame h1 { padding: 20px; padding-bottom: 0px; } #frame .alert { margin: 10px; } #form1 .error { border: solid 2px red; color: red; }
You can view a demo here or download all the files here. Thank you and I hope this has helped!