Here is a simple, quick way to validate required form fields using AJAX, PHP and MySQL.

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. Lets Get Started We⼌re going to start by making the form and adding names, id⼌s and actions to the fields. In my example, there will be six form fields, four of them being required (three being regular fields, one being a dropdown box). And next to each required field, we⼌ll have an empty space that will be used to display a specific error message returned through AJAX. A simple check will be carried out against the database and an error message will be displayed if the field is already present. We also have an empty div to display either the error message or submit button for the form. You can add your fancy data checking later. *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')" /> </tr> <tr> <td>What color <div id="emailfield_container"></div></td> is your shirt?: </td> <td><input type="text" name="textfield" onfocus="hiliteRequired('color',2)" /> </td> </tr> <tr> <td><input type="text" name="test" <td>required (but not defined): </td> id="testfield" onfocus="hiliteRequired('testfield')" /></td> </tr> <tr> <td>required drop down: </td> <td> <select name="testoption" id="testoption" <option value=""></option> onfocus="hiliteRequired('testoption')"> </select> </td> </tr> <tr> <option value="test">test</option> <td>not required: </td> <td><input type="text" name="test" </tr> id=â¼ testfield2â¼ onfocus="hiliteRequired('testfield2',5)" /></td> <tr> <td> </td> </tr> </table> </form> <td><div id="submitholder"></div></td>

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). Adding Some Style 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: <!--HIGHLIGHT EMPTY FIELDS THAT ARE REQUIRED--> function hiliteRequired(startValFROM,place){ <!--DEFINE THE ID'S OF THE REQUIRED FIELDS--> var requiredFields = new Array() requiredFields[0] = "userfield" requiredFields[1] = "emailfield" requiredFields[2] = "testfield" requiredFields[3] = "testoption"

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: < input type="text" name="test" id=â¼ testfield2â¼ onfocus="hiliteRequired('testfield2',5)" />

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: var pos = requiredFields.length; for(var i = 0; i < requiredFields.length; i++){ if(requiredFields[i] == startValFROM){ pos = i; }else{ if (pos > place){ pos = place; }else{ pos = pos; } } } 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:

<!--HIGHLIGHT EMPTY FIELDS--> for(var x = 0; x < pos; x++){ if(trimString(document.getElementById(requiredFields[x]).value) == ""){ document.getElementById(requiredFields[x]).className = 'skipped'; dispSubmit(requiredFields[x],'add'); }else if(document.getElementById(requiredFields[x]).className != "error"){ document.getElementById(requiredFields[x]).className = 'noclass'; dispSubmit(requiredFields[x],'remove'); } } 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: <!--FIX FOR IF THE USER WERE TO NAVIGATE THE FORM IN REVERSE--> for(var y = 0; y < requiredFields.length; y++){ if(trimString (document.getElementById(requiredFields[y]).value) != "" && document.getElementById(requiredFields[y]).className != "error"){ document.getElementById(requiredFields[y]).className = 'noclass'; dispSubmit(requiredFields[y],'remove'); } } }//end function 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: <!--TRIM ALL LEADING AND FOLLOWING WHITESPACE IN A STRING--> function trimString (str) { return str.replace(/^s+/g, '').replace(/s+$/g, ''); }

Another function will display a submit button or error message. 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: var problemArray = new Array(); 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:

if(action == "add" && place < 0){ problemArray.splice(problemArray.length,0,field); }else if(action == "remove" && place >= 0){ problemArray.splice(place,1); } We⼌ll now use a simple if statement to UPDATE the ⼠submitholder⼠error message or the form⼌s submit button. Example: <!--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" />'; } }//end of function 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.⼠Here are the three functions in full. Example: var problemArray = new Array(); 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; } } div with either an

}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" />'; } }

<!--TRIM ALL LEADING AND FOLLOWING WHITESPACE IN A STRING--> function trimString (str) { return str.replace(/^s+/g, '').replace(/s+$/g, ''); } <!--HIGHLIGHT EMPTY FIELDS THAT ARE REQUIRED--> function hiliteRequired(startValFROM,place){ <!--DEFINE THE ID'S OF THE REQUIRED FIELDS--> var requiredFields = new Array() requiredFields[0] = "userfield" requiredFields[1] = "emailfield" requiredFields[2] = "testfield" requiredFields[3] = "testoption" var pos = requiredFields.length; for(var i = 0; i < requiredFields.length; i++){ if(requiredFields[i] == startValFROM){ pos = i; }else{ if (pos > place){ pos = place;

}else{ pos = pos; } } } <!--HIGHLIGHT EMPTY FIELDS--> for(var x = 0; x < pos; x++){ if(trimString(document.getElementById(requiredFields[x]).value) == ""){ document.getElementById(requiredFields[x]).className = 'skipped'; dispSubmit(requiredFields[x],'add'); }else if(document.getElementById(requiredFields[x]).className != "error"){ document.getElementById(requiredFields[x]).className = 'noclass'; dispSubmit(requiredFields[x],'remove'); } } <!--FIX FOR IF THE USER WERE TO NAVIGATE THE FORM IN REVERSE--> for(var y = 0; y < requiredFields.length; y++){ if(trimString (document.getElementById(requiredFields[y]).value) != "" && document.getElementById(requiredFields[y]).className != "error"){ document.getElementById(requiredFields[y]).className = 'noclass'; dispSubmit(requiredFields[y],'remove'); } } } 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; } var http = createRequestObject(); 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: var url = 'validate_sql.php?field='; var url2; var username = document.getElementById('userfield').value; var email = document.getElementById('emailfield').value;

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; } var http = createRequestObject(); 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; }

url += url2; http.open('get', url); http.onreadystatechange = handleResponse; http.send(null); } 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⼠the validateForm() function. simply because that⼌s what we called it in

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; ?> The complete code: 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.

Sign up to vote on this title
UsefulNot useful