Ajax Username Availability Checker Using MooTools 1.2

Written by David Walsh on Wednesday, September 24, 2008


This article may feature code that is no longer best practice in MooTools.
Click here to learn what has changed to make your code framework-compatible.

There a many examples of egregious usages of Ajax out there but every once in a while you find a great usage of Ajax. One great usage is the username availability checker. Why make the user submit their form if you can just use Ajax to let them know if it’s available right away? Here’s how you can implement a username available checker using MooTools 1.2.

The MooTools 1.2 Javascript

var dwAvailabilityChecker = new Class({
	
	//implements
	Implements: [Options],

	//options
	options: {
		trigger: 'keyup',
		offset: { x:0, y:0 },
		element: '',
		minLength: 5,
		availableClass: 'available',
		takenClass: 'taken',
		availableImage: '',
		takenImage: '',
		url: 'ajax-username-check.php'
	},
	
	//initialization
	initialize: function(options) {
		//set options
		this.setOptions(options);
		
		//validate it
		this.validate();
	},
	
	//a method that does whatever you want
	validate: function() {
		this.options.element.addEvent(this.options.trigger,function() {
			if(this.options.element.value.length >= this.options.minLength) {
				var othis = this;
				var request = new Request({
					url: othis.options.url,
					method: 'get',
					data: {
						username: othis.options.element.value,
						ajax: 1
					},
					onRequest: function() {
						//remove existing classes
						othis.options.element.removeClass(othis.options.availableClass).removeClass(othis.options.takenClass);
					},
					onComplete: function(response) {
						//add class
						othis.options.element.addClass(response == 1 ? othis.options.availableClass : othis.options.takenClass);
						othis.injectImage(response == 1 ? othis.options.availableImage : othis.options.takenImage);
					}
				}).send();
			}
		}.bind(this));
	},
	
	//adds the image
	injectImage: function(image) {
		
		//figure out its position
		var pos = this.options.element.getCoordinates();
		
		var img = new Element('img',{
			src: image,
			styles: {
				'z-index': 100000,
				'position': 'absolute',
				'top': pos.top + this.options.offset.y,
				'left': pos.left + pos.width + this.options.offset.x
			}
		}).inject(document.body);
		
		
	}
	
});

Getting down to business, the validate function gets called as soon as the class is instantiated. Once the username gets to its designated minimum length, an Ajax request is sent on every keyup event. If the target script returns a positive response, the username is available and we should show the available CSS class and image. If the target script returns 0, the username is taken and the taken CSS class and image are displayed.

I’ll assume that you know PHP/MySQL enough to scrub the input and validate the given username before making the query to the database.

The Usage

window.addEvent('domready', function() {
	var validator = new dwAvailabilityChecker({
		trigger: 'keyup',
		element: $('username'),
		availableImage: 'checkmark.jpg',
		takenImage: 'warning.jpg',
		offset: { x: 4, y: 4 },
		minLength: 4,
		url: 'ajax-username-check.php'
	});
});

When instantiating the class, you get to apply any styles and configuration you’d like.

As always, here’s the example. You can also download the class.

I love using Ajax for this purpose. This little request could save a user multiple page refreshes (due to form submission) if a username is already taken.


Follow via RSS Epic Discussion

Commenter Avatar September 24 / #
John says:

You should write a custom control and submit it to the AJAX.NET community that would be a great tool to have provided with the AjaxToolKit

You can find information here: AjaxToolKit Community

Commenter Avatar September 24 / #
Rexxars says:

I always wonder when I see lines like this one:

if(this.options.element.value.length >= this.options.minLength)

Why not just escape right away, and save yourself some indenting? I think it also makes the code easier to read.. So I’d just write

if(this.options.element.value.length <= this.options.minLength) return false;

Nice class though, and a good use of ajax indeed :-)

Commenter Avatar September 24 / #
Garrick says:

Nice and simple class.

Instead of creating a new othis var at line 32, you can bind your onRequest and onComplete to pass in this.

onRequest: function(){
this.options.element.removeClass(this.options.availableClass).removeClass(this.options.takenClass);
}.bind(this),
onComplete: function(){
this.options.element.addClass(response == 1 ? this.options.availableClass : this.options.takenClass);
this.injectImage(response == 1 ? this.options.availableImage : this.options.takenImage);
}.bind(this)

David Walsh September 24 / #
david says:

@Garrick: Great work. I cringed with the “othis” variable. I wasn’t sure where to use bind(). I followed programmer rule #1: Make it work. Great addition though, and thanks for reading!

Commenter Avatar September 26 / #
Daniel says:

That’s pretty slick, David. Thanks for sharing!

Commenter Avatar September 28 / #
manik says:

Hi, I love this usage, but it is the very first thing i want to use AJAX for…i want to make my web more dynamic…and this is a great first step I think…

I had no problem aplying the JS class, but I dont know how to return the result of the check in axaj-username-check.php. It always returns “taken” status now…

(MySQL, PHP is no problem for me, just the mehcanism of returning the value)

Commenter Avatar October 06 / #
Pierre says:

Nice class (nice blog too),

By the way you could also do the Request object creation in the “initialize” function.
The request object will not be constructed at every keypress.

Commenter Avatar October 17 / #
Titan says:

Excellent David. Thank you.

Commenter Avatar October 17 / #
Moksha says:

thanks, i have done it using asp.net plus ajax.net
will use this tutorial, it give more control over the code

Commenter Avatar October 21 / #
Craig Walker says:

Excellent script David.

I have implemented it fone, but I am having the same issue as manik.

I am using my own script for checking handleChecker.php and i’m using a different field.

What do I need my handleChecker.php to return?

Thanks for your script and your help.

P.S. Tried posting code from handleChecker.php for you to view, but kept getting WP Error.

Commenter Avatar October 21 / #
Garrick says:

Craig, you might want to consider Paste Bin or some other Paste site to have others check out your code..

Commenter Avatar October 22 / #
Craig Walker says:

I never thought of Paste Bin Garrick, thanks for the shout.

http://pastebin.com/m31a32059

As you can see I echo a “1″ and a “0″.

David Walsh October 22 / #
david says:

@Craig: That’s some really, really unsecured code. Also, I recommend changing “0″ to “unavailable” and “1″ to available.

Commenter Avatar October 22 / #
Craig Walker says:

I keep getting a message about my message being spammy so I’ll make it short.
Still not working. Updated pastebin. Links to follow hopefully.

Commenter Avatar October 22 / #
Craig Walker says:

I think it’s when posting 2 links.
http://pastebin.com/m62b9c921

Commenter Avatar October 22 / #
Craig Walker says:

AND http://pastebin.com/m5c81e0e

Commenter Avatar October 23 / #
manik says:

Uff, I finally solved the problem…the only thing was to add aposthropes to the output of 1 and 0 :D

But I have another issue…the script seems to add an image after each validation, but it doesnt remove any of the previous…i am using transparent images, so you can see last image overlaying the previous… :(

Do you know how to fix it please?

Commenter Avatar October 23 / #
Craig Walker says:

manik can you paste your code for your ‘axaj-username-check.php’ please.

Commenter Avatar October 23 / #
manik says:

@Craig:

if($_GET['ajax']==1 &&
$_GET['username']){
$nick = sql_quote($_GET['username']);
$count = mysql_fetch_array(mysql_query(“SELECT
COUNT(nick) AS num FROM members WHERE
nick=’$nick’”));
echo ($count['num']>0) ? “0″ : “1″;
exit;
}

That’s no big deal. Other things which you should check is if your mysql connection is set up (ussualy you connect in the main page and include the others…but this request is sent just to this page) or if it isnt blocked by htaccess etc. (same reason)

Commenter Avatar October 23 / #
manik says:

@Craig:

if($_GET['ajax']==1 && $_GET['username']){
$nick = sql_quote($_GET['username']);
$count = mysql_fetch_array(mysql_query(“SELECT COUNT(nick) AS num FROM members WHERE nick=’$nick’”));
echo ($count['num']>0) ? “0″ : “1″;
exit;
}

Dont forget to estabilish mysql connection in this file and to check if it isnt blocked via .htaccess or anything…best is to check it in the browser if it really returns 1 or 0.

Commenter Avatar October 23 / #
Stig says:

Hello,

First of all thank you for your script. I’ve been able to integrate it with my usersystem and database. However could you show me how to disable the submit button when the username is already in use, because that would be a huge addition, since new members could still push the submit button allthough the username form is shown in red.

This would be a great help for me.

Thank you in advance,
Stig

Commenter Avatar October 23 / #
manik says:

@Stig you’ll have to check it in the server-side script anyway (its very easy to turn off javascript) so it isnt that helpfull, is it? I think you tell the user by this script that it is taken…

Commenter Avatar October 23 / #
Stig says:

Manik, thank you for your fast reply. I didn’t think about the fact that javascript could be turned off.

Commenter Avatar October 24 / #
manik says:

@Craig I posted it alreday yesterday, but I cant see my posts even now here…maybe its awaiting moderation because it contained source code…i think the code you posted is ok.

But you should check if you have estabilished connection to mysql (the one u use in the page dooesnt count, this is another request) and if it isnt blocked by .htaccess etc.

I recommend to display your axaj-username-check.php with ?username=’foo’ and check if it throws some errors…if it writes 1 or 0, then its ok

Commenter Avatar November 04 / #
Naren says:

Hello,

First of all thank you for your script. I’ve been able to integrate it with my usersystem and database. However could you show me how to disable the submit button when the username is already in use, because that would be a huge addition, since new members could still push the submit button allthough the username form is shown in red.

This would be a great help for me.

Thank you in advance,

NAREN

Commenter Avatar November 04 / #
mezo says:

man how can i use it if i am using CreateUserWizard

Commenter Avatar November 07 / #
John says:

I may be missing something here, but Im assuming this script checks for the taken usernames from a database. How do I implement this to check usernames in a database table?

Thanks for a great script!

David Walsh November 07 / #
david says:

@John: It’s basically just a quick query using some PHP.

Commenter Avatar November 09 / #
Hugo says:

David, can you post a ZIP of this script with the PHP and MySQL table?

Commenter Avatar November 21 / #
peter says:

Hi David,
could you please post the phpl file too.
Thanks in advance

Commenter Avatar March 12 / #
Newman says:

Hi, all. I’m totally a newbie to Ajax, but I’d like to integrate this function with my usersystem and mysql database. But I don’t even know how and when it links to mysql database. Could any tell me how to do it step by step? Thanks in ahead.
Sorry for my poor English.

Commenter Avatar March 24 / #
Thomas says:

Same problem as Newman …

Can you please guide me in adding php to this script please? I have no problem using php and mysql – my only problem is “WHERE” should I write the code.

Thanks,
Thomas

David Walsh March 24 / #

The PHP goes in the “header” of your login page, before any HTML output.

Commenter Avatar March 24 / #
Thomas says:

Thank you David for your message.

Can you please provide a very simple example please? Since my question then is how am I going to ‘attach’ the script with the php.

Thanks
Thomas

Commenter Avatar April 23 / #
Alfons says:

Hello David,

You know that your script are super ?
So I do not have to tell you this.

How can I get serveral events on one single function ? (mootools, ajax)
Do I have to do the instantiation for every single event (change, blur)
or is it possible to give to on instantiation several event that are all do the same
when the trigger is fired ?

Thank you for anwsering to this possible silliy question.

I need it, because with the event “change” the browser Firefox triggers on both,
when leaving the field per mouse or tab and when clicking on Enter.
But IE6 fires not when clicking on Enter.
So I need an event for both browser and had the idea to do the same with two
different events.

Best regards
Alfons

Commenter Avatar July 22 / #
softboy says:

Hi David, is it possible to add php file too ?

thanks for this

Commenter Avatar December 15 / #
marien says:

Hi David (and others)l,

I have the same problem as Manik before.
The script seems to pile up the images.

This way, you get an ugly stack of (png) images. How should / could I disable the image which was generated before the current one?

cheers and thnx for this otherwise great script!

Be Heard!

I want to hear what you have to say! Share your comments and questions below.

Name*:
Email*:
Website:  


© David Walsh 2007-2010. Contact David Walsh. Powered by the remarkable MooTools javascript framework.