10 min read

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 >
      <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="json2.js"></script>
      <script type="text/javascript" src="xhr.js"></script>
      <script type="text/javascript" src="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 >
      <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);
      }
    ?>

LEAVE A REPLY

Please enter your comment!
Please enter your name here