JavaScript: Form Validation using Ajax
This article follows on from Web Services using XMLHttpRequest (Ajax) and demonstrates the usage of our AjaxRequestXML.js class for validating online forms.
Real-time Form Validation using Ajax
This example uses the JavaScript XMLHttpRequest object and PHP server-side scripting to check that the Email address entered is valid (at least that it matches a particular regular expression) and that the Age lies between 16 and 100. As the form is completed, the values are passed immediately to the server as POST variables, the server calculates a result, passing back an XML file which is then parsed to trigger various actions on the page as you will see.
If you enter an invalid Email address, or a value for Age outside the specified range, a red warning message will appear and form will not be able to be submitted. Similarly, when you enter a valid value the message will be green. When all fields have been validated the form will be able to be submitted.
Samples of the XML files returned in each case can be found below. These are generated by PHP, but another server-side scripting language would also work.
The onsubmit handler for the form requires also that a value be entered in all fields before the form can be submitted.
The Email field input is tested using Ajax when the onchange event is triggered (when the input value changes and the focus moves to another element). We could have also used onblur but that's more resource-intensive as it's called even when the value hasn't been modified.
The Age field is checked whenever it's onkeyup event is triggered - every time a key is pressed and released while the focus is on that element.
Generally onchange is the best option when validating forms, or onkeyup/Down if you want to control the input character by character.
Markup of the HTML Form and JavaScript
The markup for the HTML form used in the example is as follows:
<form id="form_ajax_validate" method="POST" action="form handler" accept-charset="UTF-8">
<fieldset>
<legend>Ajax Form Validation Demo</legend>
<p>Name: <input type="text" size="32" name="name">
<input type="checkbox" disabled name="valid_name"></p>
<p>Email: <input type="text" size="32" id="email" name="email">
<input id="valid_email" type="checkbox" disabled name="valid_email"></p>
<div id="rsp_email"><!-- --></div>
<p>Age: <input type="text" size="4" id="age" name="age" <small>(between 16 and 100)</small>
<input id="valid_age" type="checkbox" disabled name="valid_age"></p>
<div id="rsp_age"><!-- --></div>
<p><input type="submit"></p>
</fieldset>
</form>
<script>
var formAjaxValidate = document.getElementById("form_ajax_validate");
var checkForm = function(e) {
var form = e.target;
if(this.name.value == "") {
alert("Please enter your Name in the form");
this.name.focus();
e.preventDefault();
return;
}
if(this.email.value == "" || !this.valid_email.checked) {
alert("Please enter a valid Email address");
this.email.focus();
e.preventDefault();
return;
}
if(this.age.value == "" || !this.valid_age.checked) {
alert("Please enter an Age between 16 and 100");
this.age.focus();
e.preventDefault();
return;
}
alert("Success! The form has been completed, validated and is ready to be submitted...");
e.preventDefault();
}
formAjaxValidate.addEventListener("submit", checkForm, false);
formAjaxValidate.name.addEventListener("change", function(e) {
this.value = this.value.replace(/^\s+|\s+$/g, "");
this.form.valid_name.checked = this.value;
}, false);
formAjaxValidate.email.addEventListener("change", function(e) {
if(this.value != "") {
callAjax("checkEmail", this.value, this.id);
}
}, false);
formAjaxValidate.age.addEventListener("keyup", function(e) {
if(this.value != "") {
callAjax("checkAge", this.value, this.id);
}
}, false);
</script>
Within this code you can see that the Email and Age input field have onchange event handlers which make an Ajax request to the web server when a value has been entered or updated.
For this to work we assign an id to the input box ('email'), to the associated checkbox ('valid_email) and to the DIV where the feedback text is to appear ('rsp_email'). These elements can then be referenced by the Ajax XML response.
The 'empty comment" in the DIV is just a place-holder - required in some older browsers when a DIV is initially empty but needs later to be referenced by a script.
When we invoke the callAjax() function we pass three parameters: the method (in this case 'checkEmail' or 'checkAge') to use for testing, the value to test, and the id of the input field (target). The target value is also used to work out the id of the relevant checkbox and the DIV that will display feedback.
<script src="/scripts/AjaxRequestXML.js"></script>
<script>
var callAjax = function(method, value, target) {
var params = {
method: method,
value: value,
target: target,
};
return (new AjaxRequestXML()).post("/scripts/ajax-validate.xml.php", params);
};
</script>
Sample Responses
The PHP script that does the processing in this case, /scripts/validate.xml.php accepts the three variables (method, value, target) in POST format and uses them to generate an appropriate response in XML format. We won't go into the details of how the script actually does this as that's been covered elsewhere (see links below).
Example 1
For an Age input value of 12 the validation script returns the following XML document:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response><command method="setcontent"><target>rsp_age</target><content>Sorry, 12 is too young</content></command><command method="setstyle"><target>rsp_age</target><property>color</property><value>red</value></command><command method="setproperty"><target>valid_age</target><property>checked</property><value>false</value></command><command method="focus"><target>age</target></command></response>
The commands executed then in this case are as follows:
- Set content of the div rsp_age to "Sorry, 12 is too young";
- Set color of the div rsp_age to "red";
- Set the checked property of the checkbox for the age to false;
- Set the focus back to the age input.
Example 2
For an Age input value of 30 (or any number between 16 and 100) the XML returned is similar, but displays a positive message in green and marks the age input as valid using the checkbox.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response><command method="setcontent"><target>rsp_age</target><content>30 is just right!</content></command><command method="setstyle"><target>rsp_age</target><property>color</property><value>green</value></command><command method="setproperty"><target>valid_age</target><property>checked</property><value>true</value></command></response>
The commands executed are as follows:
- Set content of the div rsp_age to "30 is just right!";
- Set color of the div rsp_age to "green";
- Set the checked property of the checkbox for age to true.
As discussed previously, all target values need to match ids of elements in the HTML document. See the article Web Services using XMLHttpRequest (Ajax) for details on all avaiable commands and their parameters.
For assistance in generating a valid XML response using PHP, read the article Generating an XML Response for Ajax Applications where you'll find a PHP class that complements the preceding JavaScript functions.
The ajax-validate.xml.php script
Several people have already asked for a copy of the ajax-validate.xml.php script referred to in these examples.
My feeling is that this article already describes how to generate the XMLHttpRequest (Ajax) request, passing GET or POST variables to a server-side script using our JavaScript class, and the related article referred to above provides a complementary PHP class for generating XML responses, so really all that's left is basic programming to process the incoming variables and generate the relevant XML response.
For those having trouble getting started, here's a walk-through:
1) check that the three $_POST variables exist;
2) if $method == 'checkAge' check that $value falls between 16 and 100;
3) if $method == 'checkEmail' check that $value is a valid email format;
4) generate an XML response to set the response text/style and checkbox state.
And here's some of the code that generates the XML response:
<?PHP
// check that all POST variables have been set
if(!isset($_POST['method']) || !$method = $_POST['method']) exit;
if(!isset($_POST['value']) || !$value = $_POST['value']) exit;
if(!isset($_POST['target']) || !$target = $_POST['target']) exit;
$passed = FALSE;
$retval = "";
switch($method)
{
case 'checkAge':
// ...
// set the $retval message, and the $passed variable to TRUE or FALSE
// ...
break;
case 'checkEmail':
// ...
// set the $retval message, and the $passed variable to TRUE or FALSE
// ...
break;
default:
exit;
}
include "class.xmlresponse.php";
$xml = new xmlResponse();
$xml->start();
// set the response text
$xml->command('setcontent', [
'target' => "rsp_{$target}",
'content' => htmlentities($retval)
]);
if($passed) {
// set the message colour to green and the checkbox to checked
$xml->command('setstyle', [
'target' => "rsp_{$target}",
'property' => 'color',
'value' => 'green'
]);
$xml->command('setproperty', [
'target' => "valid_{$target}",
'property' => 'checked',
'value' => 'true'
]);
} else {
// set the message colour to red, the checkbox to unchecked and focus back on the field
$xml->command('setstyle', [
'target' => "rsp_{$target}",
'property' => 'color',
'value' => 'red'
]);
$xml->command('setproperty', [
'target' => "valid_{$target}",
'property' => 'checked',
'value' => 'false',
]);
$xml->command('focus', [
'target' => $target
]);
}
$xml->end();
exit;
Hopefully that solves the problems some people have had implementing the code.
Putting it all together
A few people have commented that this is all a bit confusing when it comes to implementing it on your own website. That's hardly surprising given the mix of technologies so I've created a graphic (below) showing how the different files fit together and what goes where:
You need to create two files. The first is an HTML file containing the FORM which needs to be validated, and some JavaScript which can be called from different fields in the form using event handlers (e.g. 'onclick', 'onchange', ...).
The JavaScript code then passes data to the second file which is your validation script. In this case it'ss a PHP file, but another server-side scripting language would work just as well. The validation script returns XML data which is then processed and applied to the form to provide feedback to the user.
The other two files (represented in the graphic in green) can be downloaded or copied from this site and included from your files as indicated.
Pros and Cons of using Ajax?
In this particular example, and with form validation in general, the advantage over other techniques (JavaScript and/or server-side validation) is that we can make use of server-side technologies to perform more complex validation and present real-time feedback to the user without reloading the page.
The drawback is that Ajax works only in the most recent browsers, and requires that JavaScript (and sometimes ActiveX as well) be enabled. Another problem is that unless you put a lot of effort into building a complex framework you could end up with three sets of code: one for client-side validation, one for Ajax validation and one for server-side validation which is always necessary in any case.
If you want to do a calculation that can only be done server-side (eg. checking that a username is unique in your database) or you want to update the DOM with data from another script or site then Ajax is the perfect tool. But you still have to cater for (or choose to exclude) non-compatible browsers.
Related Articles - Ajax
- JavaScript Making an asynchronous request before following an href
- JavaScript Form Validation using Ajax
- JavaScript Using a Promise to make sequential Ajax requests
- JavaScript Avoiding the Race Condition with Ajax
- JavaScript Using XMLHttpRequest to log JavaScript errors
- JavaScript Making sure form values are unique using Ajax
- JavaScript Making a HEAD request via an Ajax script
- JavaScript Recording Outbound Links using Ajax
- PHP Generating an XML Response for Ajax Applications
- PHP Ajax script for making cURL HEAD requests
- JavaScript Web Services using XMLHttpRequest (Ajax)
Alex 1 August, 2017
On the page "JavaScript: Form Validation using Ajax", section 5 ("Putting it all together"), the last paragraph states that "The other two files (represented in the graphic in green) can be downloaded or copied from this site and included from your files as indicated.".
I have searched the site but can't find a link to a download page. Could you point me in the right direction please?
Thanks.
class.xmlresponse.php:
www.the-art-of-web.com/php/ajax/
ajaxrequest.js:
www.the-art-of-web.com/ajaxrequest.js
Kossi Kpetigo 31 March, 2012
Hello.. I have looked all over the web to find a great script already made to download- but your tutorial is very close to what is have been looking for- Thanks for taking the time to explain- I see that you are using it also for your comment/feedback box.. The rollover top navigation is nice too- Never saw anything like that before- almost like flash- well i am going to try to replicate your code- add more fields to it- I am more interested in date validation-if i have a problem- i will come back here !!
ettubrutus 5 August, 2011
I have been working on a webmail form that uses php. there are radio buttons and check buttons on the site as well as fields that must be completed. It work well in chrome and IE but for some reason Firefox still sends the emails even though the php prompts the user to complete all required fields. I am wanting to use ajax as a real time solution to making sure all fields are entered. Could you give me a tip on how to check whether radio buttons and checkboxes are clicked?
You can find some useful functions for form elements in this article on form validation.
rob donnellan 29 January, 2011
I was able to reproduce a problem I'm having with your code. Enter a valid email. enter a valid age, go back and edit the email to be incorrect and click the submit button while your cursor is still in the email field. Result was a message saying good to go.
I have 2 issues with Ajax. First is it always seems to be keyed to activity in one field at a time. Second is that it doesn't always play well with submit button clicks.
Any validation scheme relying entirely on JavaScript (or Ajax) can be easily circumvented by just disabling JavaScript. That's why we also need server-side validation.
Tim Sweeney 8 July, 2010
By far the most intriguing part is the way the XML is being parsed by the library. That hasn't been covered by this article at all - because it wasn't part of it. It should be noted that there is so much potential in having a generic javascript library that can be driven by the server via the XML response.
I think it comes down to preferences, but this design does allow to do a lot (if not everything) on the server side!
The aim was to create an Ajax class for non-JavaScript-savvy programmers. Barring the 'trigger' all the events are controlled by the server-side script - in this case PHP. The library is explained in more detail in this article.
vincent vollebergh 9 February, 2010
Here I am again...
I've just tried "alert('steadystate= ' + req.readyState + ' req.status= ' + req.status);"
And figured out that I might have made somekind of stupid mistake, since req.status stays at 404 (which would mean 'page not found')
Aschwin Versteegden 16 April, 2009
Although i am not using PHP but JSP instead this page helped me a great deal. The Javascript you use is very nice. Thanx a lot!
Michael Christopher 24 December, 2008
Thanks for not supplying all the code. I learned today using your example.
Ratha 15 February, 2008
You should packed the file for download. The code is so confusing.
There are plenty of sites you can go to to 'download' code. This isn't one of them. If you're having trouble, ask a question and I'll try to explain what's going on. I've added a new section now, "Putting it all together", with a diagram which might also help.
Eddie Chin 9 July, 2007
What would happen if you entered valid data in every input field other than the email address, then lastly input an invalid email address and hit the submit button immediately afterwards. Won't you have a race condition between the ajax call and the form submit?
That's correct, using Ajax is not a substitute for properly validating the data after the form is submitted. The reason for using Ajax is to provide real-time feedback to the user, making them less likely to have problems when they do submit the form.