AJAX Username Availability Checker Using MooTools 1.2

By  on  

This post has been updated: Using jQuery or MooTools For Drag, Drop, Sort, Save. The code on this page is no longer best practice.

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.

Recent Features

Incredible Demos

  • By
    MooTools HTML Police: dwMarkupMarine

    We've all inherited rubbish websites from webmasters that couldn't master valid HTML. You know the horrid markup: paragraph tags with align attributes and body tags with background attributes. It's almost a sin what they do. That's where dwMarkupMarine comes in.

  • By
    MooTools dwCheckboxes Plugin

    Update / Fix: The checkboxes will no longer toggle when the "mouseup" event doesn't occur on a checkbox. Every morning I wake up to a bunch of emails in my Gmail inbox that I delete without reading. I end up clicking so many damn checkboxes...

Discussion

  1. John

    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

  2. Rexxars

    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 :-)

  3. Garrick

    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)
    
  4. @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!

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

  6. manik

    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)

  7. 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.

  8. Titan

    Excellent David. Thank you.

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

  10. Craig Walker

    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.

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

  12. Craig Walker

    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”.

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

  14. Craig Walker

    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.

  15. Craig Walker

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

  16. manik

    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?

  17. Craig Walker

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

  18. manik

    @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 (usually you connect in the main page and include the others…but this request is sent just to this page) or if it isn’t blocked by htaccess etc. (same reason)

  19. manik

    @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 establish mysql connection in this file and to check if it isn’t blocked via .htaccess or anything…best is to check it in the browser if it really returns 1 or 0.

  20. Stig

    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

  21. manik

    @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…

  22. Stig

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

  23. manik

    @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

  24. Naren

    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

  25. mezo

    man how can i use it if i am using CreateUserWizard

  26. John

    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!

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

  28. Hugo

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

  29. peter

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

  30. Newman

    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.

  31. 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

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

  33. 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

  34. Alfons

    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

  35. softboy

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

    thanks for this

  36. marien

    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!

  37. geekasylum

    A small correction to Garrick’s patch:

    onComplete: function(){
    

    should read

    onComplete: function(response){
    

    Thanks for a great class David, and especially thanks for the awesome tutorials.

  38. Alex

    corrected function, so that the images didn’t stack on each other!

    injectImage: function(image) {
    if ($('imago')) { $('imago').src=image} else {
    		//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);
    		img.id='imago';
    	} }
    
  39. hollywood

    please can anyone give a coldfusion version of “ajax-username-check.php”. i just do not know anything about php or mysql. they both sound ridiculous to me. i do not even know how to set up the connection. please any help will be highly appreciated. thanks to you all in advance.

  40. @Garrick: you sure about this? o.o’

  41. I made some changes to the original code to be able to scan in various fields, here is

    validate: function() {
    		this.options.element.addEvent(this.options.trigger,function() {
    			if(this.options.element.value.length >= this.options.minLength) {
    				var othis = this;
    				new Request({
    
    					url: othis.options.url,
    					method: 'post',
    					data: {
    						conteudo: othis.options.element.value
    					},
    					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,othis.options.element.id);
    					}
    				}).send();
    			}
    		}.bind(this));
    	},
    	
    	//adds the image
    	injectImage: function(image,id) {
                if ($('img'+id)) { $('img'+id).src=image} else {
                    //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);                
                    img.id = 'img'+id;
                }
            }
    
  42. Just want to say awesome tutorial. I have implemented this as a “forgotten password feature” where it checks for the email address in the DB before the user submits the form. One question I have is: is there anyway of injecting some text with the image so the user gets a message saying “sorry your email address isn’t in the DB” or something similar. thanks again. Great site.

    • Sure, you could probably make the image a DIV containing the image, then add any text you’d like.

  43. When entering an available user id it displays the checkmark and turns green like expected
    but when backspacing and removing characters it fails to check the required number of characters required and stays green with a checkmark even when there are no characters
    at all…..

    It does this on your demo as well.

    Any ideas how to fix??

  44. Hi,

    I am using Joomla and I have a component TPJOBS and I want to Integrate your code. Please do let me know how to do? Also can you group this with PHP file? Here is my question

    http://forum.joomla.org/viewtopic.php?p=2717281

    I have tried with your codes but not working.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!