Instant username availability validation is a feature
a lot of my clients have been requesting lately. Basically it is a function that checks to see if a username or email address is available instantly, as it is being typed.
My internet life matured in a time when JavaScript was the
devil. I
have avoided using it in development for as long as I remember. I
still
heavily avoid it because of how fickle some of the browsers
handle it, and because elegance is time consuming. Most sites
that reconfigure themselves with AJAX fail to execute properly -- if
you are going
to use JavaScript, take the time and do it right. However, I am also
aware of how well some of the frameworks out there have overcome the
weaknesses of cross browser compatibility.
My favorite is jQuery, it is very easy to learn and simple to use. To start we are going to need three elements:
- the text box to
validate
- the JavaScript to call the validation
- the requested file
where the server side validation will take place
First the file we are going to make a request to (I am going to use a
generic (.ashx) handler):
Start by creating a new Generic Handler and
name it EmailCheck.ashx. Visual Studio will generate some default
code, we can kill the Response.Write("Hello World") as we are going to
use our logic here to check if the passed username or email address
already exists in our system. We are left with
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
public class Handler :
IHttpHandler {
public void ProcessRequest (
HttpContext context)
{
context.Response.ContentType =
"text/plain";
}
public bool IsReusable
{
get {
return false; }
}
}
I
have a method defined in my Members object to determine if the email
is available or not, which I can simply reference with
ABC.Members.IsEmailAvailable(email). I will write up a quick inline
function as an example. This function simply takes in an email address
(or username, or
whatever else you need to validate) and returns true if it is not in
use and false if it is.
private bool IsEmailAvailable(
string email)
{
OleDbDataReader reader;
OleDbCommand cmd = new
OleDbCommand(
"SELECT TOP 1 ID FROM Members WHERE Email = ?", Globals.DBConnectionString );
cmd.Paramaters.AddWithValue( "Email",email );
bool isAvailable = false;
try
{
cmd.Open();
reader = cmd.ExecuteReader();
if (!reader.Read())
isAvailable =
true;
reader.Close();
}
catch (
Exception ex)
{
ErrorHandler( ex );
return false;
}
finally
{
cmd.Close();
}
return isAvailable;
}
That
will be good enough for our purposes. It can be adapted to better suit
your application, using your DB provider or what have you.
Next
we just need to add the logic to the ProcessRequest function. We need
to check the query string to see if we got an email address, if we did
indeed get one then we can query the database and make the required
response.
public void ProcessRequest (
HttpContext context)
{
context.Response.ContentType =
"text/plain";
if (context.Request.QueryString[
"Email"] == null)
return;
string email = context.Request.QueryString[
"Email"].ToString();
if (!IsEmailAvailable(email))
{
context.Response.Write(
"Sorry, your email address is already in use.");
return;
}
}
That
is all there is to this side of the request. You can test it out by
referencing the handler directly.
http://localhost:xxxx/
[email protected]. If the
email address is not in use, you will see nothing on the response and
if it is in use you will see a plain text message of "Sorry, your email
address is already in use."
For this next part you are going to need to download
jQuery. I am currently using version 1.3.2 which you can download directly
here.
However, you may want to check the main site for more recent versions.
The first time that I worked with jQuery I had an extremely unorganized
site with multiple unorganized developers. We had MooTools and
Prototype and had some conflict issues. I found a no conflict feature
of jQuery that I have used every since. I just add to the last line of
the jQuery file
var $j = jQuery.noConflict();
What this means that in my code you will see $j("jquery").something; instead of the standard $("jquery").something;.
On the new form page we need to create two things:
- the CheckEmail(email) JavaScript function
- a container for the error message
I
created a div with the ID of "emailinusebox". The function is pretty
simple: we need to validate the email address. If we don't have a
valid email address, there is no reason to waste time or resources with
a database request. I admit, I kept it simple and lazy. I just check
to see if the string contains an @ and a . (dot). If it meets those
requirements, we can go ahead and check the database. I use the jQuery.load function which will perform a GET to the ashx handler we created above.
function CheckEmail(email)
{
$j("#emailinusebox").html("");
if(email.toString().indexOf("@") == -1)
return;
if(email.toString().indexOf(".") == -1)
return;
$j("#emailinusebox").load("EmailCheck.ashx?Email=" + email);
}
You can use CSS to style the error box however you like. I simply have
#emailinusebox {font-weight:700;color:#f00}
Now for the final step, the easy part. We need our text box,
<asp:TextBox MaxLength="100" runat="server" ID="tEmail"></asp:TextBox>
And
we need to apply the onkeyup function to it in order to call our
validation function. I apply it in the .cs file by adding an attribute
to it.
this.tEmail.Attributes.Add("onkeyup", "javascript:checkemailcode(this.value);");
There
are other (likely better) ways to do this. I believe the best practice
is to assign it using jQuery's (document).ready function, but I prefer
this way. I find it easier for me to manage, mainly because I don't
trust designers to maintain the integrity of my .aspx files. When all
is said and done, we have a very simple looking error message. You can
add flashy bells and whistles and icons, but here is how it looks in
its current form: