AJAX Username Validation

Posted by Mike Lopez under Javascript/AJAX
Mar 2008
17
09:13pm

Form input validation is sometimes an annoying part in web development but it’s something that we web developers can’t avoid. In order to make sure that the data being entered by our users are valid, we simply have to validate. Another good use of validation is to provide feedback to the user on whether what they are typing is acceptable or not.

One such case is in user registration forms wherein we ask the user to enter a username. It will be nice if we can provide them immediate feedback on whether the username they are choosing is of the correct length, contains invalid characters and of course if it’s still available. For this purpose, I wrote a 156 line AJAX file that shows how to do it.

It’s divided into three sections…

  1. The PHP section - which runs on the server to check if the username is available
  2. The Javascript section - which contains are AJAX stuff and does some client-side validation as well
  3. And the HTML Form - this is where the user enters the username

I simplified the form to contain only the username field - after all, this is just an example / tutorial.

The PHP Part

// sample code for testing purposes only
 // existing usernames
 $usernames = array ("administrator", "peterpiper", "peterpan", "superman");
 if ($_GET["u"] != "") {
  if (in_array ($_GET["u"], $usernames)) {
   // if username is in our array then output the string "0"
   echo "0";
  } else {
   // if username is not in our array then output the string "1"
   echo "1";
  }
  exit;
 }
 

For the purpose of providing an example, I simply entered a list of “existing” usernames into an array. In the real world, you will be checking the value of $_GET["u"] against a database.

The Javascript Part

function ajax_call (url, callback_function, error_function) {
 var xmlHttp = null;
 try {
  // for standard browsers
  xmlHttp = new XMLHttpRequest ();
 } catch (e) {
  // for internet explorer
  try {
   xmlHttp = new ActiveXObject ("Msxml2.XMLHTTP");
     } catch (e) {
   xmlHttp = new ActiveXObject ("Microsoft.XMLHTTP");
     }
 }
 xmlHttp.onreadystatechange = function () {
  if (xmlHttp.readyState == 4)
   try {
    if (xmlHttp.status == 200) {
     // we got the data, let"s call the callback function
     callback_function (xmlHttp.responseText);
    }
   } catch (e) {
    // oops we have an error, call the error function
    error_function (e.description);
   }
  }
  // open the url
  xmlHttp.open ("GET", url);
  // and send the data
  xmlHttp.send (null);
 }
 
 /*
  * this function is called for every keypress on our input field
  * it accepts one parameter - i - which is the object referencing
  * our input field
  */

 function usercheck_init (i) {
 var obj = document.getElementById("ajax_output");
 obj.innerHTML = ""; // <- clear the status field
 
 if (i.value.length < 1) return;
 
  var err = new Array ();
 // pre-ajax checks… let"s check everything that we can check before calling ajax
 // usernames can only contain letters, numbers and underscores
 if (i.value.match (/[^a-z0-9_]/)) err[err.length] = "Username can only contain letters, numbers and underscores";
 // usernames must be at least 8 characters long
  if (i.value.length < 8) err[err.length] = "Username too short";

 // if we have a pre-ajax error, then show the error
  if (err != "") {
   obj.style.color = "#ff0000";
   obj.innerHTML = err.join ("<br />");
   return;
  }
 
  // all pre-ajax checks passed?  good, now let"s do our ajax check
  ajax_call ("usercheck.php?u=" + i.value, usercheck_callback, usercheck_error);
 }
 
 /*
  * this is our callback function
  * all it does is check the data returned by the server
  * and decide on whether we show an error or not
  */

 function usercheck_callback (data) {
  var response = (data == "1");

  var obj = document.getElementById("ajax_output");
  obj.style.color = (response) ? "#008800" : "#ff0000";
  obj.innerHTML = (response == "1") ? "Username OK" : "Username already taken";
 }
 /*
  * this is our error function
  * all it does is pop an alert box showing the error
  */

 function usercheck_error (err) {
  alert ("Error: " + err);
 }

It’s pretty self-explanatory but if you’re a bit confused then read the AJAX Introduction I wrote previously so you can grasp the idea of what’s being done in the Javascript code above.

The HTML Form

<form method="post" onsubmit="return false">
 <dl>
  <dt>Username</dt>
  <dd>
   <input type="text" name="username" value="" onkeyup="usercheck_init (this)" />
   <div id="ajax_output"></div>
  </dd>
 </dl>
</form>

A few things worth mentioning about our HTML form. First, I placed onsubmit="return false" in the form tag - you can take that out. I just don’t want the form to be submitted when someone presses the enter key on the username field. Second is the onkeyup="usercheck_init (this)" part. That’s what hooks our input field to our ajax call every time the user types a character in our username field.

Now, we put them all together into one nice HTML/PHP file and give it a try.

<?php
/*
 * Username Validation using AJAX
 *
 * Author: Mike Lopez
 * Author URI: http://mikelopez.info , http://coderscult.com
 *
 * Description:
 *  This AJAX example consists of three parts
 *  namely: PHP, Javascript, and HTML FORM
 *  - The PHP part handles the server side checking of the username
 *  - The Javascript part contacts the server (the PHP part)
 *  - The HTML FORM displays the username input field which is
 *    hooked to Javascript via the onkeyup attribute
 */

// *** THE PHP PART ***
// sample code for testing purposes only
 // existing usernames
 $usernames = array ("administrator", "peterpiper", "peterpan", "superman");
 if ($_GET["u"] != "") {
  if (in_array ($_GET["u"], $usernames)) {
   // if username is in our array then output the string "0"
   echo "0";
  } else {
   // if username is not in our array then output the string "1"
   echo "1";
  }
  exit;
 }
 
/*
 * Note: In a more realistic scenario, you will be checking
 * usernames against a database instead of just a predefined
 * array as in our example
 */

// *** END OF PHP PART ***
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Check if User Exists</title>

<!– *** THE JAVASCRIPT PART *** –>
<script type="text/javascript">
<!– // Javascript –>

/*
 * ajax_call function - this does the hard work
 * accepts three parameters:
 *  url - the url of the server side script to call
 *  callback_function - the function to call when data is retrieved from the server
 *  error_function - the function to call when an error occurs
 */

function ajax_call (url, callback_function, error_function) {
 var xmlHttp = null;
 try {
  // for standard browsers
  xmlHttp = new XMLHttpRequest ();
 } catch (e) {
  // for internet explorer
  try {
   xmlHttp = new ActiveXObject ("Msxml2.XMLHTTP");
     } catch (e) {
   xmlHttp = new ActiveXObject ("Microsoft.XMLHTTP");
     }
 }
 xmlHttp.onreadystatechange = function () {
  if (xmlHttp.readyState == 4)
   try {
    if (xmlHttp.status == 200) {
     // we got the data, let"s call the callback function
     callback_function (xmlHttp.responseText);
    }
   } catch (e) {
    // oops we have an error, call the error function
    error_function (e.description);
   }
  }
  // open the url
  xmlHttp.open ("GET", url);
  // and send the data
  xmlHttp.send (null);
 }
 
 /*
  * this function is called for every keypress on our input field
  * it accepts one parameter - i - which is the object referencing
  * our input field
  */

 function usercheck_init (i) {
 var obj = document.getElementById("ajax_output");
 obj.innerHTML = ""; // <- clear the status field
 
 if (i.value.length < 1) return;
 
  var err = new Array ();
 // pre-ajax checks… let"s check everything that we can check before calling ajax
 // usernames can only contain letters, numbers and underscores
 if (i.value.match (/[^a-z0-9_]/)) err[err.length] = "Username can only contain letters, numbers and underscores";
 // usernames must be at least 8 characters long
  if (i.value.length < 8) err[err.length] = "Username too short";

 // if we have a pre-ajax error, then show the error
  if (err != "") {
   obj.style.color = "#ff0000";
   obj.innerHTML = err.join ("<br />");
   return;
  }
 
  // all pre-ajax checks passed?  good, now let"s do our ajax check
  ajax_call ("usercheck.php?u=" + i.value, usercheck_callback, usercheck_error);
 }
 
 /*
  * this is our callback function
  * all it does is check the data returned by the server
  * and decide on whether we show an error or not
  */

 function usercheck_callback (data) {
  var response = (data == "1");

  var obj = document.getElementById("ajax_output");
  obj.style.color = (response) ? "#008800" : "#ff0000";
  obj.innerHTML = (response == "1") ? "Username OK" : "Username already taken";
 }
 /*
  * this is our error function
  * all it does is pop an alert box showing the error
  */

 function usercheck_error (err) {
  alert ("Error: " + err);
 }
</script>
<!– END OF THE JAVASCRIPT PART –>

</head>
<body>

<!– THE FORM –>
<form method="post" onsubmit="return false">
 <dl>
  <dt>Username</dt>
  <dd>
   <input type="text" name="username" value="" onkeyup="usercheck_init (this)" />
   <div id="ajax_output"></div>
  </dd>
 </dl>
</form>
<!– END OF THE FORM –>

</body>
</html>

Here’s how it works:

Existing users are: administrator, peterpiper, peterpan, and superman.

Download usercheck.zip - AJAX Username Validation


Share this Post through Social Bookmarking These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • StumbleUpon
  • Technorati
  • YahooMyWeb

Read other posts in this website

Leave a Reply