There’s two types of validation:
- Simple, server-independent validation, i.e. checking email address are the right format, password and confirm password matches, etc.
- Server-based validation, with can be delivered with a page refresh, or live (as this tutorial will explain), i.e. for checking whether a username is taken.
What can we do?
- Live username checking
- Password confirmation and strength
- Checking if an email address is already registered
- URL validation, i.e. Basecamp’s site address checks if the URL is available (pretty much the same as username validation)
So why do it?
- It makes the user’s experience quicker, or arguably better
- It’s not much extra work to put in place (explained below)
Examples in the wild
- Twitter signup / username validation
- Pownce signup / username validation (though you have to click ‘check’)
- Digg signup / username
- Basecamp / URL validation
- del.icio.us / tagging
Howto
As with all these tutorials, I expect that you have built your solution to the point where it works, but now we want to add our splash of JavaScript magic.
In our baseline example, my requirements are:
- Username validation kept in separate function
- Server side does the it’s normal job
- I can detect an Ajax request and return something different
Username validation
Our PHP function to validate the username reads:
function check_username($username) {
$username = trim($username); // strip any white space
$response = array(); // our response
// if the username is blank
if (!$username) {
$response = array(
'ok' => false,
'msg' => "Please specify a username");
// if the username does not match a-z or '.', '-', '_' then it's not valid
} else if (!preg_match('/^[a-z0-9\.\-_]+$/', $username)) {
$response = array(
'ok' => false,
'msg' => "Your username can only contain alphanumerics and period, dash and underscore (.-_)");
// this would live in an external library just to check if the username is taken
} else if (username_taken($username)) {
$response = array(
'ok' => false,
'msg' => "The selected username is not available");
// it's all good
} else {
$response = array(
'ok' => true,
'msg' => "This username is free");
}
return $response;
}
This format for a response is good, because we are using it to display error messages on the page, but we can also convert it to JSON and use it in our Ajax response later on.
Markup
Again, it’s assumed your markup is already designed to show error messages.
For this example the following markup is being used within a fieldset:
<div>
<label for="username">Username, valid: a-z.-_</label>
<input type="text" name="username" value="<?=@$_REQUEST['username']?>" id="username" />
<span id="validateUsername"><?php if ($error) { echo $error['msg']; } ?></span>
</div>
jQuery
Our client side check will perform the following:
- Only if the value has changed run the check, i.e. ignore meta keys
- Use a nice ajax spinner to indicate activity
- Make an Ajax request and show the response
$(document).ready(function () {
var validateUsername = $('#validateUsername');
$('#username').keyup(function () {
var t = this;
if (this.value != this.lastValue) {
if (this.timer) clearTimeout(this.timer);
validateUsername.removeClass('error').html('<img src="images/ajax-loader.gif" height="16" width="16" /> checking availability...');
this.timer = setTimeout(function () {
$.ajax({
url: 'ajax-validation.php',
data: 'action=check_username&username=' + t.value,
dataType: 'json',
type: 'post',
success: function (j) {
validateUsername.html(j.msg);
}
});
}, 200);
this.lastValue = this.value;
}
});
});
The code breaks down as follows:
$(document).ready(function () {
Run the JavaScript in this (anonymous) function when the document has loaded.
var validateUsername = $('#validateUsername');
Create a cached copy of the validateUsername span because it will help a little with optimisation (it’s a good practise to have).
$('#username').keyup(function () {
Run the JavaScript in this (anonymous) function on key up.
var t = this;
Cache the ‘this’ instance as we need access to it within a setTimeout, where ‘this’ is set to ‘window’, which can cause all manners of confusion.
if (this.value != this.lastValue) {
Only run the check if the username has actually changed - also means we skip meta keys.
if (this.timer) clearTimeout(this.timer);
The timeout logic means the ajax doesn’t fire with every key press, i.e. if the user holds down a particular key, it will only fire when the release the key.
validateUsername.removeClass('error').html('<img src="images/ajax-loader.gif" height="16" width="16" /> checking availability...');
Show our holding text in the validation message space.
this.timer = setTimeout(function () {
Fire an ajax request in 1/5 of a second.
$.ajax({
url: 'ajax-validation.php',
data: 'action=check_username&username=' + t.value,
dataType: 'json',
type: 'post',
success: function (j) {
validateUsername.html(j.msg);
}
});
The actual Ajax request. If the script ajax-validation.php returns any response, convert it to JSON and put the ‘msg’ field in to the validation message.
The fields are set in the PHP server response. You can see this working in the demo, and view the source, in particular look at the $resp array from check_username.
this.lastValue = this.value;
Finally, put the current value in to a cache, to make sure we ignore meta keys (from above).
Server response
Now all I have to add to the PHP code, that already handles normal username validation is:
if (@$_REQUEST['action'] == 'check_username' && isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
echo json_encode(check_username($_REQUEST['username']));
exit; // only print out the json version of the response
}
So long as this is high enough in the logic, it will just check the username is valid, using our existing function and convert the response to a JSON object (you may need to add JSON support for PHP, otherwise it’s bundled with PHP 5.2.0).
Example & taking it further
In the example I’ve provided, I’ve also shown how we can add JavaScript to a normally coded page to also validate the user providing an avatar URL.
- Full example of username and avatar validation
- Same example with JavaScript removed
- Source code to example
Related posts
Demo
If you find this demo doesn't work as expected, it's possibly due to the demo running from within an iframe. Try running the demo in it's own window.
Source Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>jQuery for Designers - Ajax Form Validation Example</title>
<style type="text/css" media="screen">
<!--
BODY { margin: 10px; padding: 0; font: 1em "Trebuchet MS", verdana, arial, sans-serif; font-size: 100%; }
H1 { margin-bottom: 2px; font-family: Garamond, "Times New Roman", Times, Serif;}
TEXTAREA { width: 80%;}
FIELDSET { border: 1px solid #ccc; padding: 1em; margin: 0; }
LEGEND { color: #ccc; font-size: 120%; }
INPUT, TEXTAREA { font-family: Arial, verdana; font-size: 125%; padding: 7px; }
LABEL { display: block; margin-top: 10px; }
IMG { margin: 5px; }
#message {
border: 1px solid #ccc;
background-color: #ffa;
padding: 5px;
}
DIV.submit {
background: #eee;
border: 1px solid #ccc;
border-top: 0;
padding: 1em;
text-align: right;
margin-bottom: 20px;
}
IMG.avatar {
vertical-align: top;
}
-->
</style>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
$(document).ready(function () {
// Username validation logic
var validateUsername = $('#validateUsername');
$('#username').keyup(function () {
// cache the 'this' instance as we need access to it within a setTimeout, where 'this' is set to 'window'
var t = this;
// only run the check if the username has actually changed - also means we skip meta keys
if (this.value != this.lastValue) {
// the timeout logic means the ajax doesn't fire with *every* key press, i.e. if the user holds down
// a particular key, it will only fire when the release the key.
if (this.timer) clearTimeout(this.timer);
// show our holding text in the validation message space
validateUsername.removeClass('error').html('<img src="images/ajax-loader.gif" height="16" width="16" /> checking availability...');
// fire an ajax request in 1/5 of a second
this.timer = setTimeout(function () {
$.ajax({
url: 'ajax-validation.php',
data: 'action=check_username&username=' + t.value,
dataType: 'json',
type: 'post',
success: function (j) {
// put the 'msg' field from the $resp array from check_username (php code) in to the validation message
validateUsername.html(j.msg);
}
});
}, 200);
// copy the latest value to avoid sending requests when we don't need to
this.lastValue = this.value;
}
});
// avatar validation
// we use keyup *and* change because
$('#avatar').keyup(function () {
var t = this;
clearTimeout(this.timer);
this.timer = setTimeout(function () {
if (t.value == t.current) {
return true;
}
var preview = $('#validateAvatar').html('<img src="images/ajax-loader.gif" height="16" width="16" /> trying to load avatar...');
var i = new Image();
clearTimeout(t.timeout);
if (t.value == '') {
preview.html('');
} else {
i.src = t.value;
i.height = 32;
i.width = 32;
i.className = 'avatar';
// set a timeout of x seconds to load the image, otherwise, show the fail message
t.timeout = setTimeout(function () {
preview.html('Image could not be loaded.');
i = null;
}, 3000);
// if the dummy image holder loads, we'll show the image in the validation space,
// but importantly, we clear the timer set above
i.onload = function () {
clearTimeout(t.timeout);
preview.empty().append(i);
i = null;
};
}
t.current = t.value;
}, 250);
}).change(function () {
$(this).keyup(); // call the keyup function
});
});
//-->
</script>
</head>
<body>
<div>
<h1>jQuery for Designers - Ajax Form Validation Example</h1>
<p>This shows two examples of client side validation in a form using JavaScript (with jQuery). The username will check with the server whether the chosen name is a) valid and b) available. The avatar example tries to load the URL in to a hidden image, if it fails, it shows the appropriate message.</p>
<p><a href="http://jqueryfordesigners.com/using-ajax-to-validate-forms/">Read the article this demonstration relates to</a></p>
<p><a href="?action=register&username=remy&avatar=http://tbn0.google.com/images?q=tbn:gLMWxXGcr71JVM">Example of failing username and successful avatar</a></p>
<p><a href="?nojs">See the non-JavaScript version</a></p>
<form action="" method="post">
<fieldset>
<legend>Register</legend>
<div>
<label for="username">Username, valid: a-z.-_</label>
<input type="text" name="username" value="" id="username" />
<span id="validateUsername"></span>
</div>
<div>
<label for="avatar">Avatar URL</label>
<input type="text" name="avatar" size="50" value="" id="avatar" />
<span id="validateAvatar"></span>
</div>
</fieldset>
<input type="hidden" name="action" value="register" />
<div class="submit"><input type="submit" name="register" value="Register" id="register" /></div>
</form>
<p>Note that the following usernames are permanently unavailable for the purpose of this demo: remy, julie, andrew, andy, simon, chris, nick</p>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1656750-8";
urchinTracker();
</script>
</body>
</html>

Winten On 28th January 2009 at 15:01
i replaced
with my } else if ($username == get(username, $username, NULL)) {
and it says ‘checking availability…’ forever, how can i obtain users from sql then?
Azam On 6th April 2009 at 04:04
can we use this script in classic asp?
Harini On 1st July 2009 at 11:07
This is what i was searching for. But how do i use this to check the username availability in the Database?