Ajax Form Validation
Ajax Form Validation
What we âre going to do is display an error message to the right of the required field, and if there
are errors, restrict the submit button. And if a user were to skip a required field, or leave it blank,
we will highlight it along with removing the submit button.
I feel this is useful because it validates on the fly using PHP methods that we may already have
in place – there is no need to learn the “Javascript way†to do something that you’ve
been doing for a while. I make a few assumptions in this tutorial. The first is that you have a
basic understanding of PHP and how to connect to a MySQL database and retrieve records.
Along with that, for this tutorial, you’ll need a table setup with usernames and email
addresses stored in it; my table will be called “users.†The second is that you have some
understanding of how AJAX works. Third is that you have an understanding of CSS and how to
define classes and id’s. You could figure these things about by going through this tutorial,
but it would be a lot easier on you if you do understand what I laid out.
*In this example I will only check against the first two FROM fields; username and email
address.
The field id is the most important element in this script. So we’ll be using a simple naming
convention to keep the code clean and hopefully simple; *field* name=â€xxxâ€
id=â€xxxfield†and the error container will have an id of xxxfield_container.
Code Example:
<form action="" method="get"> <table width="776" border="0" cellspacing="3"
cellpadding="3">
<tr> <td width="258">Username: *req* </td>
<td width="497"><input type="text" name="user" id="userfield"
onblur="validateForm('userfield');" onfocus="hiliteRequired('userfield')" />
<div id="userfield_container"></div></td> </tr> <tr> <td>Email: *req*
</td>
<td><input type="text" name="email" id="emailfield" onblur="
validateForm('emailfield');" onfocus="hiliteRequired('emailfield')" />
<div id="emailfield_container"></div></td> </tr> <tr> <td>What color
is your shirt?: </td>
<td><input type="text" name="textfield" onfocus="hiliteRequired('color',2)" />
</td>
</tr>
<tr>
<td>required (but not defined): </td> <td><input type="text" name="test"
id="testfield" onfocus="hiliteRequired('testfield')" /></td>
</tr>
<tr>
<td>required drop down: </td> <td>
<select name="testoption" id="testoption"
onfocus="hiliteRequired('testoption')"> <option value=""></option>
<option value="test">test</option> </select> </td> </tr> <tr>
<td>not required: </td> <td><input type="text" name="test"
id=â€testfield2†onfocus="hiliteRequired('testfield2',5)" /></td> </tr>
<tr> <td> </td>
<td><div id="submitholder"></div></td> </tr> </table> </form>
As you can see each field has some action(s) attached to it, the actions are calling their specific
function. The required fields have two actions associated with them; an onblur - calling the
actual AJAX and an onfocus - calling a function that highlights all empty required fields before
the current field (this is left off for the first required field because there are no required fields
before it).
We will be using some basic CSS to define and change the style of form fields. In order to have
this code validate, we need to define every id and class, even if it’s empty. You can add your
desired styling.
Example:
<style type="text/css">
#userfield, #emailfield{
color: #000000;
float:left;
}
#user_container, #email_container{
float:left;
}
.error{
border: 2px solid #FF0000;
background-color:#FEDADB;
}
.skipped{
border: 2px solid #FF0000;
background-color:#00CCFF;
}
.noclass{
color: #000000;
}
#submitholder{
color: #000000;
}
</style>
Javascript Functions
This function was an afterthought and it just made sense for me to add it. What is the point of
highlighting errors in required fields if the ones that the user skipped aren’t highlighted?
Well that’s what this function is for – it will evaluate all of the required fields before it and
if they’re empty, we’ll change its class and add it’s name to the error array restricting
the form’s submit button.
The first thing we have to do is create the function and define our required fields.
Example:
startValFROM is used to set which field the function is being called FROM, place is used if the
field calling the function isn’t a required one.
Example when calling this function on a non-required field:
Example:
You pass the id of the field and its position, starting FROM zero. So in this example, it is the
sixth one down (5).
The next part of this function loops through the required array and if it finds a match with
startValFROM, then it sets pos to the match’s key. If not, pos is set to the length of the array.
pos is set so that in the next loop, which highlights the fields, knows which ones to highlight.
Example:
Now we’re going to loop through the array again, this time we’ll actually do something
to the form on the screen. This loop will stop at pos and if requiredFields[x] is empty, it will
change the class to “skipped.†If it isn’t empty and the class isn’t set to
“errorâ€(set by the AJAX code later on), the class will be changed to “noclass.â€
Each case, if empty or not, calls on another function that adds or removes the field id FROM an
error array allowing for the submit button or an error message to be displayed. If it is empty, add,
if not remove.
Example:
The code above could finish out the function and it would work fine, but it only works if the user
is going from top to bottom. So I added this piece of code that says if the user were to skip all, or
some of the required fields, and they started making changes FROM the bottom up, then we need
to un-highlight the fields that are no longer empty. It checks to see if the element is empty and
makes sure the class isn’t set to “error.†If those things check out, set the class to
“noclass.â€
Example:
One of the functions called by the highlite function is trimString(). It trims the white space from
the start and end portions of a string. Here’s the code:
Example:
First we will declare the problemArray array outside of the function and then we define the
dispSubmit function. field corresponds to the required field’s id that will be evaluated; while
action says what action to take on that filed; add or remove it from the array.
Example:
function dispSubmit(field,action){
Next we will define the place variable, it will be used when it is time to add or remove from the
problemArray. So what we’ll do is loop through the array, if the array length is not more than
zero, place is equal to an arbitrary negative number. If the array is more than zero, we’ll see
if problemArray[i] is equal to the id that we are evaluating, with a for loop. If found; place equals
i. If not, again, place is equal to an arbitrary negative number (I have chosen -12 and -50 for
testing purposes).
Example:
if(problemArray.length != 0){
for(var i = 0; i < problemArray.length; i++){
if(problemArray[i] == field){
place = i;
break;
}else{
place = -12;
}
}
}else{
place = -50;
}
Now we’ll go ahead and add some actions to the function. If action is set to add and place is
a negative number, we’ll use array splice to add the field id that is being evaluated to the
array. If remove and place is zero or greater we’ll remove it from the array.
Example:
We’ll now use a simple if statement to UPDATE the “submitholder†div with either an
error message or the form’s submit button.
Example:
You could make improvements with this by having a switch case that would UPDATE the
“submitholder†div with specific errors such as “you left x, y and z fields blank.â€
Example:
function dispSubmit(field,action){
if(problemArray.length != 0){
for(var i = 0; i < problemArray.length; i++){
if(problemArray[i] == field){
place = i;
break;
}else{
place = -12;
}
}
}else{
place = -50;
}
if(action == "add" && place < 0){
problemArray.splice(problemArray.length,0,field);
}else if(action == "remove" && place >= 0){
problemArray.splice(place,1);
}
<!--DISPLAY ERROR OR SUBMIT BUTTION-->
if(problemArray.length != 0){
document.getElementById('submitholder').innerHTML = "There seems to be a problem
with one or more of your fields";
}else{
document.getElementById('submitholder').innerHTML = '<input type="submit"
name="Submit" value="Submit" />';
}
}
Ajax
Each required field, has an onblur action attached to them that calls our validateForm() AJAX
function, the only thing that needs to be passed is the field’s id.
Example:
<!--AJAX-->
function createRequestObject() {
var ro;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer"){
ro = new ActiveXObject("Microsoft.XMLHTTP");
}else{
ro = new XMLHttpRequest();
}
return ro;
}
function validateForm(txtfield){
Inside this function we will use a simple if statement to build the url that will be passed to the
PHP/MySQL query page.
The first thing have to do is define the start of the url which includes the page being called and
the word action. Then we want to grab each required field’s value, in this example it’s
only the username and email.
Example:
Now we build the rest of the url depending on which field called the function.
Example:
if (txtfield == "userfield"){
url2 = txtfield+unescape("%26userfield=")+username;
}else if(txtfield == "emailfield"){
url2 = txtfield+unescape("%26emailfield=")+email;
}
Finish the function off by joining the two url pieces and also with the required AJAX send
commands.
Example:
url += url2;
http.open('get', url);
http.onreadystatechange = handleResponse;
http.send(null);
}
The next function will check the ready state of the http call, print our errors to screen, change the
classes of the errant or ok fields and UPDATE our dispSubmit() array.
*In this example we’re splitting our data with the pipe “|†key, if your data may contain
some of those, you may want to split by something that you know your data wont contain,
something like “%|*†or even “asldkfjaos,†just remember what you’re splitting
with.
Example:
function handleResponse() {
if(http.readyState == 4){
var response = http.responseText;
var UPDATE = new Array();
<!--LOOP THROUGH THE RESPONSES-->
if(response.indexOf('|' != -1)) {
UPDATE = response.split('|');
If UPDATE[1] does not equal no error (!error), we set the field to error, UPDATE the div that
displays the error and add the field to our problemArray. If it equals no error and the field’s
class isn’t set to “skipped†by our hiliteRequied function, we set it to “noclass,â€
UPDATE the display div to empty and if its value isn’t equal to blank “â€, we remove it
FROM the problemArray.
Example:
if(UPDATE[1] != '!error'){
document.getElementById(UPDATE[0]).className = 'error';
document.getElementById(UPDATE[0]+'_container').innerHTML = UPDATE[1];
dispSubmit(UPDATE[0],'add');
}else if(UPDATE[1] == '!error'){
if(document.getElementById(UPDATE[0]).className != 'skipped'){
document.getElementById(UPDATE[0]).className = 'noclass';
}
document.getElementById(UPDATE[0]+'_container').innerHTML = "";
if(trimString(document.getElementById(UPDATE[0]+'_container').value) != ""){
dispSubmit(UPDATE[0],'remove');
}
}
}
}
}//end function
[
Code with all three functions:
Example:
<!--AJAX-->
function createRequestObject() {
var ro;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer"){
ro = new ActiveXObject("Microsoft.XMLHTTP");
}else{
ro = new XMLHttpRequest();
}
return ro;
}
function validateForm(txtfield){
var url = 'validate_sql.php?field=';
var url2;
var username = document.getElementById('userfield').value;
var email = document.getElementById('emailfield').value;
if (txtfield == "userfield"){
url2 = txtfield+unescape("%26userfield=")+username;
}else if(txtfield == "emailfield"){
url2 = txtfield+unescape("%26emailfield=")+email;
}
function handleResponse() {
if(http.readyState == 4){
var response = http.responseText;
var UPDATE = new Array();
<!--LOOP THROUGH THE RESPONSES-->
if(response.indexOf('|' != -1)) {
UPDATE = response.split('|');
if(UPDATE[1] != '!error'){
document.getElementById(UPDATE[0]).className = 'error';
document.getElementById(UPDATE[0]+'_container').innerHTML = UPDATE[1];
dispSubmit(UPDATE[0],'add');
}else if(UPDATE[1] == '!error'){
if(document.getElementById(UPDATE[0]).className != 'skipped'){
document.getElementById(UPDATE[0]).className = 'noclass';
}
document.getElementById(UPDATE[0]+'_container').innerHTML = "";
if(trimString(document.getElementById(UPDATE[0]+'_container').value) != ""){
dispSubmit(UPDATE[0],'remove');
}
}
}
}
}
<!--END AJAX-->
Next up is the PHP page (validate_sql.php) where we connect to an MySQL database and check
the records against what the user put in and return an error or an a okay.
We’ll name this page “validate_sql.php†simply because that’s what we called it in
the validateForm() function.
The first thing we want to do is connect to our MySQL database. I have a page called db.php that
I like to include which handles that part for me.
Example:
<?
//database connection
$server = “http://www.yourserver.comâ€;
$username = “fooâ€;
$password = “booâ€;
$databasename = “are we done yet?â€;
$db = mysql_connect($server,$username,$password) or die("Problem connecting
-".mysql_error());
mysql_select_db($databasename) or die("Problem selecting database - ".mysql_error());
Next we want to define our variables. They are all passed through the url, so you might want to
do some prevention from MySQL attacks. We will $_REQUEST each variable from the url and
trim the white space from them. Again, you can do other things such as remove tags, slashes etc.
Example:
//define variables
$field = trim($_REQUEST['field']);
$userfield = trim($_REQUEST['userfield']);
$emailfield = trim($_REQUEST['emailfield']);
$output = "";
Now the rest is fairly simple and straightforward. We will use simple if statements, to define
what action our script will take. In each set, we’ll check to see if the variable is in the
database and return the correct output.
If the number of rows returned is not equal to zero, then the output will be the field id, pipe, and
the error message. If it is zero, it will be the field id, pipe, !error (no error).
Example:
if($field == "userfield"){
$query = "SELECT * FROM phpfreaks.users WHERE user = '".$userfield."'";
$result = mysql_query($query) or die ("<h2>Could not select user</h2>".mysql_error());
$num = mysql_num_rows($result);
if($num !=0){
$output = "userfield|That username is taken, try another.";
}else{
$output = "userfield|!error";
}
}
We can repeat the above code for the email and echo the output.
Example:
elseif($field == "emailfield"){
$query = "SELECT * FROM phpfreaks.users WHERE email = '".$emailfield."'";
$result = mysql_query($query) or die ("<h2>Could not select email
address</h2>".mysql_error());
$num = mysql_num_rows($result);
if($num !=0){
$output = "emailfield|That email address is taken, try another.";
}else{
$output = "emailfield|!error";
}
}
echo $output;
?>
Example:
<?
//database connection
$server = “http://www.yourserver.comâ€;
$username = “fooâ€;
$password = “booâ€;
$databasename = “are we done yet?â€;
$db = mysql_connect($server,$username,$password) or die("Problem connecting
-".mysql_error());
mysql_select_db($databasename) or die("Problem selecting database - ".mysql_error());
//define variables
$field = trim($_REQUEST['field']);
$userfield = trim($_REQUEST['userfield']);
$emailfield = trim($_REQUEST['emailfield']);
$output = "";
if($field == "userfield"){
$query = "SELECT * FROM phpfreaks.users WHERE user = '".$userfield."'";
$result = mysql_query($query) or die ("<h2>Could not select user</h2>".mysql_error());
$num = mysql_num_rows($result);
if($num !=0){
$output = "userfield|That username is taken, try another.";
}else{
$output = "userfield|!error";
}
}elseif($field == "emailfield"){
$query = "SELECT * FROM phpfreaks.users WHERE email = '".$emailfield."'";
$result = mysql_query($query) or die ("<h2>Could not select email
address</h2>".mysql_error());
$num = mysql_num_rows($result);
if($num !=0){
$output = "emailfield|That email address is taken, try another.";
}else{
$output = "emailfield|!error";
}
}
echo $output;
?>
Conclusion
That’s it. It’s pretty simple and straightforward. If you understand AJAX and how to
return something to the browser, then you can have that data manipulate the html in pretty much
any way your heart desires.