AJAX Form Validation: Part 2

Exclusive offer: get 50% off this eBook here
AJAX and PHP: Building Modern Web Applications 2nd Edition

AJAX and PHP: Building Modern Web Applications 2nd Edition — Save 50%

Build user friendly Web 2.0 Applications with JavaScript and PHP

$23.99    $12.00
by Audra Hendrix | February 2010 | AJAX MySQL PHP Web Development

Read Part One of AJAX Form Validation here.

How to implement AJAX form validation

In this article, we redesigned the code for making AJAX requests when creating the XmlHttp class. The AJAX form validation application makes use of these techniques. The application contains three pages:

  • One page renders the form to be validated
  • Another page validates the input
  • The third page is displayed if the validation is successful

The application will have a standard structure, composed of these files:

  • index.php: It is the file loaded initially by the user. It contains references to the necessary JavaScript files and makes asynchronous requests for validation to validate.php.
  • index_top.php: It is a helper file loaded by index.php and contains several objects for rendering the HTML form.
  • validate.css: It is the file containing the CSS styles for the application.
  • json2.js: It is the JavaScript file used for handling JSON objects.
  • xhr.js: It is the JavaScript file that contains our XmlHttp object used for making AJAX requests.
  • validate.js: It is the JavaScript file loaded together with index.php on the client side. It makes asynchronous requests to a PHP script called validate.php to perform the AJAX validation.
  • validate.php: It is a PHP script residing on the same server as index.php, and it offers the server-side functionality requested asynchronously by the JavaScript code in index.php.
  • validate.class.php: It is a PHP script that contains a class called Validate, which contains the business logic and database operations to support the functionality of validate.php.
  • config.php: It will be used to store global configuration options for your application, such as database connection data, and so on.
  • error_handler.php: It contains the error-handling mechanism that changes the text of an error message into a human-readable format.
  • allok.php: It is the page to be displayed if the validation is successful.

Time for action – AJAX form validation

  1. Connect to the ajax database and create a table named users with the following code:
    CREATE TABLE users
    (
    user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    user_name VARCHAR(32) NOT NULL,
    PRIMARY KEY (user_id)
    );
  2. Execute the following INSERT commands to populate your users table with some sample data:
    INSERT INTO users (user_name) VALUES ('bogdan');
    INSERT INTO users (user_name) VALUES ('audra');
    INSERT INTO users (user_name) VALUES ('cristian');
  3. Let's start writing the code with the presentation tier. We'll define the styles for our form by creating a file named validate.css, and adding the following code to it:
    body
    {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 0.8em;
    color: #000000;
    }
    label
    {
    float: left;
    width: 150px;
    font-weight: bold;
    }
    input, select
    {
    margin-bottom: 3px;
    }
    .button
    {
    font-size: 2em;
    }
    .left
    {
    margin-left: 150px;
    }
    .txtFormLegend
    {
    color: #777777;
    font-weight: bold;
    font-size: large;
    }
    .txtSmall
    {
    color: #999999;
    font-size: smaller;
    }
    .hidden
    {
    display: none;
    }
    .error
    {
    display: block;
    margin-left: 150px;
    color: #ff0000;
    }
  4. Now create a new file named index_top.php, and add the following code to it. This script will be loaded from the main page index.php.
    <?php
    // enable PHP session
    session_start();
    // Build HTML <option> tags
    function buildOptions($options, $selectedOption)
    {
    foreach ($options as $value => $text)
    {
    if ($value == $selectedOption)
    {
    echo '<option value="' . $value .
    '" selected="selected">' . $text . '</option>';
    }
    else
    {
    echo '<option value="' . $value . '">' . $text .
    '</option>';
    }
    }
    }
    // initialize gender options array
    $genderOptions = array("0" => "[Select]",
    "1" => "Male",
    "2" => "Female");
    // initialize month options array
    $monthOptions = array("0" => "[Select]",
    "1" => "January",
    "2" => "February",
    "3" => "March",
    "4" => "April",
    "5" => "May",
    "6" => "June",
    "7" => "July",
    "8" => "August",
    "9" => "September",
    "10" => "October",
    "11" => "November",
    "12" => "December");
    // initialize some session variables to prevent PHP throwing
    // Notices
    if (!isset($_SESSION['values']))
    {
    $_SESSION['values']['txtUsername'] = '';
    $_SESSION['values']['txtName'] = '';
    $_SESSION['values']['selGender'] = '';
    $_SESSION['values']['selBthMonth'] = '';
    $_SESSION['values']['txtBthDay'] = '';
    $_SESSION['values']['txtBthYear'] = '';
    $_SESSION['values']['txtEmail'] = '';
    $_SESSION['values']['txtPhone'] = '';
    $_SESSION['values']['chkReadTerms'] = '';
    }
    if (!isset($_SESSION['errors']))
    {
    $_SESSION['errors']['txtUsername'] = 'hidden';
    $_SESSION['errors']['txtName'] = 'hidden';
    $_SESSION['errors']['selGender'] = 'hidden';
    $_SESSION['errors']['selBthMonth'] = 'hidden';
    $_SESSION['errors']['txtBthDay'] = 'hidden';
    $_SESSION['errors']['txtBthYear'] = 'hidden';
    $_SESSION['errors']['txtEmail'] = 'hidden';
    $_SESSION['errors']['txtPhone'] = 'hidden';
    $_SESSION['errors']['chkReadTerms'] = 'hidden';
    }
    ?>
  5. Now create index.php, and add the following code to it:
    <?php
    require_once ('index_top.php');
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.
    w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Degradable AJAX Form Validation with PHP and
    MySQL</title>
    <meta http-equiv="Content-Type" content="text/html;
    charset=utf-8" />
    <link href="validate.css" rel="stylesheet" type="text/css" />
    </head>
    <body onload="setFocus();">
    <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="json2.js"></script>
    <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="xhr.js"></script>
    <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="validate.js"></script>
    <fieldset>
    <legend class="txtFormLegend">
    New User Registratio Form
    </legend>
    <br />
    <form name="frmRegistration" method="post"
    action="validate.php">
    <input type="hidden" name="validationType" value="php"/>
    <!-- Username -->
    <label for="txtUsername">Desired username:</label>
    <input id="txtUsername" name="txtUsername" type="text"
    onblur="validate(this.value, this.id)"
    value="<?php echo $_SESSION['values']
    ['txtUsername'] ?>" />
    <span id="txtUsernameFailed"
    class="<?php echo $_SESSION['errors']['txtUsername']
    ?>">
    This username is in use, or empty username field.
    </span>
    <br />
    <!-- Name -->
    <label for="txtName">Your name:</label>
    <input id="txtName" name="txtName" type="text"
    onblur="validate(this.value, this.id)"
    value="<?php echo $_SESSION['values']['txtName']
    ?>" />
    <span id="txtNameFailed"
    class="<?php echo $_SESSION['errors']['txtName']?>">
    Please enter your name.
    </span>
    <br />
    <!-- Gender -->
    <label for="selGender">Gender:</label>
    <select name="selGender" id="selGender"
    onblur="validate(this.value, this.id)">
    <?php buildOptions($genderOptions,
    $_SESSION['values']['selGender']); ?>
    </select>
    <span id="selGenderFailed"
    class="<?php echo $_SESSION['errors']['selGender']
    ?>">
    Please select your gender.
    </span>
    <br />
    <!-- Birthday -->
    <label for="selBthMonth">Birthday:</label>
    <!-- Month -->
    <select name="selBthMonth" id="selBthMonth"
    onblur="validate(this.value, this.id)">
    <?php buildOptions($monthOptions,
    $_SESSION['values']['selBthMonth']);
    ?>
    </select>
    &nbsp;-&nbsp;
    <!-- Day -->
    <input type="text" name="txtBthDay" id="txtBthDay"
    maxlength="2" size="2"
    onblur="validate(this.value, this.id)"
    value="<?php echo $_SESSION['values']['txtBthDay']
    ?>" />
    &nbsp;-&nbsp;
    <!-- Year -->
    <input type="text" name="txtBthYear" id="txtBthYear"
    maxlength="4" size="2"
    onblur="validate(document.getElementById
    ('selBthMonth').options[document.getElementById
    ('selBthMonth').selectedIndex].value +
    '#' + document.getElementById('txtBthDay').value +
    '#' + this.value, this.id)"
    value="<?php echo $_SESSION['values']['txtBthYear']
    ?>"
    />
    <!-- Month, Day, Year validation -->
    <span id="selBthMonthFailed"
    class="<?php echo $_SESSION['errors']['selBthMonth']
    ?>">
    Please select your birth month.
    </span>
    <span id="txtBthDayFailed"
    class="<?php echo $_SESSION['errors']['txtBthDay']
    ?>">
    Please enter your birth day.
    </span>
    <span id="txtBthYearFailed"
    class="<?php echo $_SESSION['errors']['txtBthYear']
    ?>">
    Please enter a valid date.
    </span>
    <br />
    <!-- Email -->
    <label for="txtEmail">E-mail:</label>
    <input id="txtEmail" name="txtEmail" type="text"
    onblur="validate(this.value, this.id)"
    value="<?php echo $_SESSION['values']['txtEmail']
    ?>" />
    <span id="txtEmailFailed"
    class="<?php echo $_SESSION['errors']['txtEmail']
    ?>">
    Invalid e-mail address.
    </span>
    <br />
    <!-- Phone number -->
    <label for="txtPhone">Phone number:</label>
    <input id="txtPhone" name="txtPhone" type="text"
    onblur="validate(this.value, this.id)"
    value="<?php echo $_SESSION['values']['txtPhone']
    ?>" />
    <span id="txtPhoneFailed"
    class="<?php echo $_SESSION['errors']['txtPhone']
    ?>">
    Please insert a valid US phone number (xxx-xxx-xxxx).
    </span>
    <br />
    <!-- Read terms checkbox -->
    <input type="checkbox" id="chkReadTerms"
    name="chkReadTerms" class="left"
    onblur="validate(this.checked, this.id)"
    <?php if ($_SESSION['values']['chkReadTerms'] ==
    'on') echo 'checked="checked"' ?> />
    I've read the Terms of Use
    <span id="chkReadTermsFailed"
    class="<?php echo$_SESSION['errors']
    ['chkReadTerms'] ?>">
    Please make sure you read the Terms of Use.
    </span>
    <!-- End of form -->
    <hr />
    <span class="txtSmall">Note: All fields arerequired.
    </span>
    <br /><br />
    <input type="submit" name="submitbutton" value="Register"
    class="left button" />
    </form>
    </fieldset>
    </body>
    </html>
  6. Create a new file named allok.php, and add the following code to it:
    <?php
    // clear any data saved in the session
    session_start();
    session_destroy();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>AJAX Form Validation</title>
    <meta http-equiv="Content-Type" content="text/html;
    charset=utf-8" />
    <link href="validate.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
    Registration Successful!<br />
    <a href="index.php" title="Go back">&lt;&lt; Go back</a>
    </body>
    </html>
  7. Copy json2.js (which you downloaded in a previous exercise from http://json.org/json2.js) to your ajax/validate folder.
  8. Create a file named validate.js. This file performs the client-side functionality, including the AJAX requests:
    // holds the remote server address
    var serverAddress = "validate.php";
    // when set to true, display detailed error messages
    var showErrors = true;
    // the function handles the validation for any form field
    function validate(inputValue, fieldID)
    {
    // the data to be sent to the server through POST
    var data = "validationType=ajax&inputValue=" + inputValue +
    "&fieldID=" + fieldID;
    // build the settings object for the XmlHttp object
    var settings =
    {
    url: serverAddress,
    type: "POST",
    async: true,
    complete: function (xhr, response, status)
    {
    if (xhr.responseText.indexOf("ERRNO") >= 0
    || xhr.responseText.indexOf("error:") >= 0
    || xhr.responseText.length == 0)
    {
    alert(xhr.responseText.length == 0 ?
    "Server error." : response);
    }
    result = response.result;
    fieldID = response.fieldid;
    // find the HTML element that displays the error
    message = document.getElementById(fieldID + "Failed");
    // show the error or hide the error
    message.className = (result == "0") ? "error" : "hidden";
    },
    data: data,
    showErrors: showErrors
    };
    // make a server request to validate the input data
    var xmlHttp = new XmlHttp(settings);
    }
    // sets focus on the first field of the form
    function setFocus()
    {
    document.getElementById("txtUsername").focus();
    }

  9. Now it's time to add the server-side logic. Start by creating config.php, with the following code in it:
    <?php
    // defines database connection data
    define('DB_HOST', 'localhost');
    define('DB_USER', 'ajaxuser');
    define('DB_PASSWORD', 'practical');
    define('DB_DATABASE', 'ajax');
    ?>
  10. Now create the error handler code in a file named error_handler.php:
    <?php
    // set the user error handler method to be error_handler
    set_error_handler('error_handler', E_ALL);
    // error handler function
    function error_handler($errNo, $errStr, $errFile, $errLine)
    {
    // clear any output that has already been generated
    if(ob_get_length()) ob_clean();
    // output the error message
    $error_message = 'ERRNO: ' . $errNo . chr(10) .
    'TEXT: ' . $errStr . chr(10) .
    'LOCATION: ' . $errFile .
    ', line ' . $errLine;
    echo $error_message;
    // prevent processing any more PHP scripts
    exit;
    }
    ?>
  11. The PHP script that handles the client's AJAX calls, and also handles the validation on form submit, is validate.php:
    <?php
    // start PHP session
    session_start();
    // load error handling script and validation class
    require_once ('error_handler.php');
    require_once ('validate.class.php');
    // Create new validator object
    $validator = new Validate();
    // read validation type (PHP or AJAX?)
    $validationType = '';
    if (isset($_POST['validationType']))
    {
    $validationType = $_POST['validationType'];
    }
    // AJAX validation or PHP validation?
    if ($validationType == 'php')
    {
    // PHP validation is performed by the ValidatePHP method,
    //which returns the page the visitor should be redirected to
    //(which is allok.php if all the data is valid, or back to
    //index.php if not)
    header('Location:' . $validator->ValidatePHP());
    }
    else
    {
    // AJAX validation is performed by the ValidateAJAX method.
    //The results are used to form a JSON document that is sent
    //back to the client
    $response = array('result' => $validator->ValidateAJAX
    ($_POST['inputValue'],$_POST['fieldID']),
    'fieldid' => $_POST['fieldID'] );
    // generate the response
    if(ob_get_length()) ob_clean();
    header('Content-Type: application/json');
    echo json_encode($response);
    }
    ?>
AJAX and PHP: Building Modern Web Applications 2nd Edition Build user friendly Web 2.0 Applications with JavaScript and PHP
Published: December 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:
  1. The class that supports the validation functionality is called Validate, and it is hosted in a script file called validate.class.php, which looks like this:
    <?php
    // load error handler and database configuration
    require_once ('config.php');
    // Class supports AJAX and PHP web form validation
    class Validate
    {
    // stored database connection
    private $mMysqli;
    // constructor opens database connection
    function __construct()
    {
    $this->mMysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD,
    DB_DATABASE);
    }
    // destructor closes database connection
    function __destruct()
    {
    $this->mMysqli->close();
    }
    // supports AJAX validation, verifies a single value
    public function ValidateAJAX($inputValue, $fieldID)
    {
    // check which field is being validated and perform
    // validation
    switch($fieldID)
    {
    // Check if the username is valid
    case 'txtUsername':
    return $this->validateUserName($inputValue);
    break;
    // Check if the name is valid
    case 'txtName':
    return $this->validateName($inputValue);
    break;
    // Check if a gender was selected
    case 'selGender':
    return $this->validateGender($inputValue);
    break;
    // Check if birth month is valid
    case 'selBthMonth':
    return $this->validateBirthMonth($inputValue);
    break;
    // Check if birth day is valid
    case 'txtBthDay':
    return $this->validateBirthDay($inputValue);
    break;
    // Check if birth year is valid
    case 'txtBthYear':
    return $this->validateBirthYear($inputValue);
    break;
    // Check if email is valid
    case 'txtEmail':
    return $this->validateEmail($inputValue);
    break;
    // Check if phone is valid
    case 'txtPhone':
    return $this->validatePhone($inputValue);
    break;
    // Check if "I have read the terms" checkbox has been
    // checked
    case 'chkReadTerms':
    return $this->validateReadTerms($inputValue);
    break;
    }
    }
    // validates all form fields on form submit
    public function ValidatePHP()
    {
    // error flag, becomes 1 when errors are found.
    $errorsExist = 0;
    // clears the errors session flag
    if (isset($_SESSION['errors']))
    unset($_SESSION['errors']);
    // By default all fields are considered valid
    $_SESSION['errors']['txtUsername'] = 'hidden';
    $_SESSION['errors']['txtName'] = 'hidden';
    $_SESSION['errors']['selGender'] = 'hidden';
    $_SESSION['errors']['selBthMonth'] = 'hidden';
    $_SESSION['errors']['txtBthDay'] = 'hidden';
    $_SESSION['errors']['txtBthYear'] = 'hidden';
    $_SESSION['errors']['txtEmail'] = 'hidden';
    $_SESSION['errors']['txtPhone'] = 'hidden';
    $_SESSION['errors']['chkReadTerms'] = 'hidden';
    // Validate username
    if (!$this->validateUserName($_POST['txtUsername']))
    {
    $_SESSION['errors']['txtUsername'] = 'error';
    $errorsExist = 1;
    }
    // Validate name
    if (!$this->validateName($_POST['txtName']))
    {
    $_SESSION['errors']['txtName'] = 'error';
    $errorsExist = 1;
    }
    // Validate gender
    if (!$this->validateGender($_POST['selGender']))
    {
    $_SESSION['errors']['selGender'] = 'error';
    $errorsExist = 1;
    }
    // Validate birth month
    if (!$this->validateBirthMonth($_POST['selBthMonth']))
    {
    $_SESSION['errors']['selBthMonth'] = 'error';
    $errorsExist = 1;
    }
    // Validate birth day
    if (!$this->validateBirthDay($_POST['txtBthDay']))
    {
    $_SESSION['errors']['txtBthDay'] = 'error';
    $errorsExist = 1;
    }
    // Validate birth year and date
    if (!$this->validateBirthYear($_POST['selBthMonth'] . '#' .
    $_POST['txtBthDay'] . '#' .
    $_POST['txtBthYear']))
    {
    $_SESSION['errors']['txtBthYear'] = 'error';
    $errorsExist = 1;
    }
    // Validate email
    if (!$this->validateEmail($_POST['txtEmail']))
    {
    $_SESSION['errors']['txtEmail'] = 'error';
    $errorsExist = 1;
    }
    // Validate phone
    if (!$this->validatePhone($_POST['txtPhone']))
    {
    $_SESSION['errors']['txtPhone'] = 'error';
    $errorsExist = 1;
    }
    // Validate read terms
    if (!isset($_POST['chkReadTerms']) ||
    !$this->validateReadTerms($_POST['chkReadTerms']) {
    $_SESSION['errors']['chkReadTerms'] = 'error';
    $_SESSION['values']['chkReadTerms'] = '';
    $errorsExist = 1;
    }
    // If no errors are found, point to a successful validation
    // page
    if ($errorsExist == 0)
    {
    return 'allok.php';
    }
    else
    {
    // If errors are found, save current user input
    foreach ($_POST as $key => $value)
    {
    $_SESSION['values'][$key] = $_POST[$key];
    }
    return 'index.php';
    }
    }
    // validate user name (must be empty, and must not be already
    // registered)
    private function validateUserName($value)
    {
    // trim and escape input value
    $value = $this->mMysqli->real_escape_string(trim($value));
    // empty user name is not valid
    if ($value == null)
    return 0; // not valid
    // check if the username exists in the database
    $query = $this->mMysqli->query('SELECT user_name FROM users'
    'WHERE user_name="' .
    $value . '"');
    if ($this->mMysqli->affected_rows > 0)
    return '0'; // not valid
    else
    return '1'; // valid
    }
    // validate name
    private function validateName($value)
    {
    // trim and escape input value
    $value = trim($value);
    // empty user name is not valid
    if ($value)
    return 1; // valid
    else
    return 0; // not valid
    }
    // validate gender
    private function validateGender($value)
    {
    // user must have a gender
    return ($value == '0') ? 0 : 1;
    }
    // validate birth month
    private function validateBirthMonth($value)
    {
    // month must be non-null, and between 1 and 12
    return ($value == '' || $value > 12 || $value < 1) ? 0 : 1;
    }
    // validate birth day
    private function validateBirthDay($value)
    {
    // day must be non-null, and between 1 and 31
    return ($value == '' || $value > 31 || $value < 1) ? 0 : 1;
    }
    // validate birth year and the whole date
    private function validateBirthYear($value)
    {
    // valid birth year is between 1900 and 2000
    // get whole date (mm#dd#yyyy)
    $date = explode('#', $value);
    // date can't be valid if there is no day, month, or year
    if (!$date[0]) return 0;
    if (!$date[1] || !is_numeric($date[1])) return 0;
    if (!$date[2] || !is_numeric($date[2])) return 0;
    // check the date
    return (checkdate($date[0], $date[1], $date[2])) ? 1 : 0;
    }
    // validate email
    private function validateEmail($value)
    {
    // valid email formats: *@*.*, *@*.*.*, *.*@*.*, *.*@*.*.*)
    return (!preg_match('/^[_a-z0-9-]+(.[_a-z0-9-]+)*@
    [a-z0-9-]+(.[a-z0-9-]+)*
    (.[a-z]{2,3})$/i', $value)) ? 0 : 1;
    }
    // validate phone
    private function validatePhone($value)
    {
    // valid phone format: ###-###-####
    return (!preg_match('/^[0-9]{3}-*[0-9]{3}-*[0-9]{4}$/',
    $value)) ? 0 : 1;
    }
    // check the user has read the terms of use
    private function validateReadTerms($value)
    {
    // valid value is 'true'
    return ($value == 'true' || $value == 'on') ? 1 : 0;
    }
    }
    ?>
  2. Test your script by loading http://localhost/ajax/validate/index.php in a web browser.

What just happened?

The AJAX validation technique allows us to validate form fields and at the same time inform users if there were any validation errors, and the icing on the cake is that we are doing it without interrupting the user's activity!

The client-side validation is combined with a pure server-side PHP validation that takes place when the user clicks on Submit and thereby submits the entire form to the server. Because of two PHP scripts, validate.php and validate.class.php, both validation types are supported at the server.

Let's examine the code, beginning with the script that handles client-side validation, index.php. The client page is not a simple HTML file but, rather, a PHP file; portions of it will be dynamically generated at the server side. In this way, we retain the form field values when the form is submitted and server-side validation fails. Without the server-side PHP code, if the index page is reloaded, all its fields would be empty.

index.php begins by loading a helper script named index_top.php to: start the session by calling session_start(), define some variables and a function that will be used later in index.php, and initialize some session variables ($_SESSION['values'] and $_SESSION['errors']) to avoid PHP sending notices about uninitialized variables.

Note the onload event of the body tag in index.php. It calls the setFocus() function defined in validate.js, which places the input cursor in the first field of the form.

In index.php, you see the following sequence of code. Later on, we will be using this same code with additional small changes:

<!-- Username -->
<label for="txtUsername">Desired username:</label>
<input id="txtUsername" name="txtUsername" type="text"
onblur="validate(this.value, this.id)"
value="<?php echo $_SESSION['values']['txtUsername']
?>" />
<span id="txtUsernameFailed"
class="<?php echo $_SESSION['errors']['txtUsername']
?>">
This username is in use, or empty username field.
</span>
<br />

This is the code that displays a form field with its corresponding label and displays an error message underneath when validation fails.

In this example, we display an error message right under the validated field, but you can customize the position and appearance of these error messages in validate.css by changing the properties of the error CSS class.

The onblur event of the input element that is generated when the user leaves an input element triggers the validate() JavaScript function with two parameters: the field's value and the field's ID (the server script needs to know which field we need to validate and what the input value is). This function will handle AJAX validation, by making an asynchronous HTTP request to the validate.php script.

The value attributes should be empty on the initial page load, but after submitting the form it should hold the input values. We use session variables to save user input on form submit, in case validation fails and the form is re-displayed.

The <span> element that follows contains the error message that gets displayed on failed validation. This span is initially hidden using the hidden CSS class, but we change its CSS class into error, if validation fails.

The validate() function inside validate.js, sends an AJAX request to the server by calling validate.php with three parameters—the field's value, the field's ID, and AJAX as the validation type.

The data to be sent to the server is formatted accordingly.

// the data to be sent to the server through POST
var data = "validationType=ajax&inputValue=" + inputValue +
"&fieldID=" + fieldID;

Before making the AJAX request, we build the JSON settings object to be passed to the XmlHttp constructor function.

// build the settings object for the XmlHttp object
var settings =
{
url: serverAddress,
type: "POST",
async: true,
complete: function (xhr, response, status)
{
if (xhr.responseText.indexOf("ERRNO") >= 0
|| xhr.responseText.indexOf("error:") >= 0
|| xhr.responseText.length == 0)
{
alert(xhr.responseText.length == 0 ?
"Server error." : response);
}
result = response.result;
fieldID = response.fieldid;
// find the HTML element that displays the error
message = document.getElementById(fieldID + "Failed");
// show the error or hide the error
message.className = (result == "0") ? "error" : "hidden";
},
data: data,
showErrors: showErrors
};

As all of the hard work is delegated to XmlHttp, all that's left for our function to do is to correctly interpret the response. This is where the complete callback function is used to check for any PHP errors handled by the error_handler.php module and, when there is an error, to show the error(s) in a popup message. Next, the validation result is retrieved from the JSON object. If the validation was successful, we change the CSS class of the error message to hidden; if the validation failed, it is set to error. You change the element's CSS class using its className property.

The final step is the construction of an AJAX request using the XmlHttp object and passing the JSON settings object.

The PHP script that handles server-side processing is validate.php. It starts by loading the error handling script (error_handler.php) and the Validate class that handles the data validation (validate.class.php). Then, it looks for a POST variable named validationType. This exists both when an asynchronous request is made and when the form is submitted via a hidden input field.

// read validation type (PHP or AJAX?)
$validationType = '';
if (isset($_POST['validationType']))
{
$validationType = $_POST['validationType'];
}

Then, based on the value of $validationType, we perform either AJAX validation or PHP validation.

// AJAX validation or PHP validation?
if ($validationType == 'php')
{
// PHP validation is performed by the ValidatePHP method, which
..// returns the page the visitor should be redirected to (which is
// allok.php if all the data is valid, or back to index.php if not)
header('Location:' . $validator->ValidatePHP());
}
else
{
// AJAX validation is performed by the ValidateAJAX method. The
// results are used to form a JSON object that is sent back to the
// client
$response = array('result' => $validator->ValidateAJAX
($_POST['inputValue'], $_POST['fieldID']),
'fieldid' => $_POST['fieldID'] );
// generate the response
if(ob_get_length()) ob_clean();
header('Content-Type: application/json');
echo json_encode($response);
}
?>

For classic, server-side validation, we call the validatePHP() method, which returns the name of the page the browser should be redirected to (which will be allok.php if the validation was successful, or index.php if not). The validation results for each field are stored in the session and should it be reloaded; index.php will indicate the fields that didn't pass the test.

In the case of AJAX calls, the server composes a response that specifies if the field is valid. The response is a JSON object that looks like this:


{"result":"1","fieldid":"txtUsername"}

If the result is 0, then txtUsername isn't valid and it should be marked accordingly. If the result is 1, the field's value is valid.

Next, let's look into validate.class.php, referenced in validate.php. This is the workhorse of our PHP validation. The class constructor creates a connection to the database and the destructor closes that connection. We then have two public methods: ValidateAJAX() (AJAX validation) and ValidatePHP() (server-side validation).

PHP constructors and destructors

In PHP, the constructor is implemented as a method named __construct(), and is executed automatically when you create new instances of a class. Just as in other programming languages, the constructors are useful when you have code that initializes various class members, because you can rely on it always executing as soon as a new object of the class is created.

At the opposite side of the object life cycle, you have the destructor, which is a method named __destruct(), and is called automatically when the object is destroyed. Destructors are very useful for doing housekeeping work. In most examples, we will close the database connection in the destructor, ensuring that we don't leave any database connections open, consuming unnecessary resources.

AJAX validation requires two parameters, one that holds the value to be validated ($inputValue) and one that holds the form field's ID ($fieldID). A switch block loads specific validation for each form field. This function will return 0 if validation fails or 1 if validation is successful.

The PHP validation function takes no parameters, as it validates the entire form (after form submission). First we initialize the $errorsExist flag to 0. Whenever validation fails for a field, this flag will be set to 1 and we will know validation has failed. Then we need to make sure that older session variables are unset in order to ensure that older errors are cleared.

We then check each form field against a set of custom rules. If validation fails, we raise the flag ($errorsExist = 1) and set the session variable that sets the CSS class for error message to error. If, in the end, the $errorsExist flag is still set to 0, it means that the entire validation was successful and so it returns the name of the success page, thus redirecting the browser to that page.

If errors are found, we save current user input into session variables, which will be used by index.php to fill the form (remember that by default, when loading the page, all fields are empty). This is how we save current user input:


foreach ($_POST as $key => $value)
{
$_SESSION['values'][$key] = $_POST[$key];
}

In other scenarios, you can save these values even if the validation is successful, so that should the user fill in another form on our site, say an order form, they can be reused for him.

$_POST is an array holding the names and values of all form elements, and it can be walked through with foreach. This means that for each element inside the $_POST array, we create a new element inside the $_SESSION['values'] array.

There's nothing special to mention about validate.css. The success page (allok.php) is very simple as well—it just displays a successful submission confirmation belying all the work that's gone on before it!

Summary

We saw how to put into practice everything that we had learned so far in JavaScript by building our own flexible, extensible, reusable object for AJAX requests. We demonstrated the application structure that we specified as well.

Our intention here wasn't to build the perfect validation technique but, rather, a working proof of the concept that takes care of user input and ensures its validity.

This validation technique isn't possible with JavaScript alone, nor would you want to wait for the fields to be validated only on form submit.

[ 1 | 2 ]

If you have read this article you may be interested to view :


AJAX and PHP: Building Modern Web Applications 2nd Edition Build user friendly Web 2.0 Applications with JavaScript and PHP
Published: December 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Audra Hendrix

Audra Hendrix was educated at Northwestern University. She works as a consultant in applied technology and marketing to small and medium-sized businesses. While her client list includes Fortune 500 companies, she prefers the flexibility, agility, and challenges of small to medium-sized businesses. She has consulted both in the United States and France for businesses seeking to better utilize their resources and maximize their gains by reinventing and reapplying back office and Internet applications, data management, cost-effective marketing strategies, staffing requirements, and planning and deployment of new or emerging product lines.

Books From Packt

Drupal 6 Performance Tips
Drupal 6 Performance Tips

Mahara 1.2 E-Portfolios: Beginner's Guide
Mahara 1.2 E-Portfolios: Beginner's Guide

Joomla! 1.5 Multimedia
Joomla! 1.5 Multimedia

jQuery 1.4 Reference Guide
jQuery 1.4 Reference Guide

Backbase 4 RIA Development
Backbase 4 RIA Development

Grok 1.0 Web Development
Grok 1.0 Web Development

Oracle SQL Developer 2.1
Oracle SQL Developer 2.1

PHP 5 E-commerce Development
PHP 5 E-commerce Development

Your rating: None Average: 5 (2 votes)
Hi Audra Excellent code. by
Hi Audra Excellent code. Thanks heaps. I am having one problem when testing the code. In the validate.php file i am getting the following error "ERRNO: 8 TEXT: Undefined index: inputValue LOCATION: "...... in the following code // AJAX validation is performed by the ValidateAJAX method. //The results are used to form a JSON document that is sent //back to the client $response = array('result' => $validator->ValidateAJAX ($_POST['inputValue'],$_POST['fieldID']), 'fieldid' => $_POST['fieldID'] ); Not sure why. Any help would be appreciated. Thanks Ryan

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
y
u
n
V
F
k
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software