Some of the new, cool, hip sites out there have done something rather neat with their login system. If you take a look at Technorati, notice that when you click the Sign In link, a modal window pops up. This lets you login no matter where you in the site. No need to go to another page (thank goodness, since Technorati is slow) and be sent back (hopefully) when done. Can ColdFusion 8 do this? Of course! Let's look at an example.

First off - imagine we have an existing site. One that uses a custom tag for layout (details may be found here). All of our pages use the custom tag. For example:

<cf_layout>

<p> Welcome to our Web 2.0 site. </p>

</cf_layout>

(As just a quick warning, I'll be sharing the complete code for all of this at the end of the blog entry, and via a download link.) Our layout custom tag creates a simple navigation table on top:

<a href="index.cfm">Home</a> / <a href="about.cfm">About Us</a> / <a href="buy.cfm">Buy Us</a>

The first thing I want to do is add a Login link to the menu:

/ <a href="javaScript:doLogin()">Login</a>

The link above runs the JavaScript function, doLogin, so let's go there next.

function doLogin() { ColdFusion.Window.create('loginwindow','Login','login.cfm',{center:true,modal:true}); }

This function simply uses the ColdFusion/Ajax API to create a window. I named it loginwindow, gave it a title, pointed it to a login.cfm page, and passed a few attributes. I could have styled it as well, made it a specific size, etc. But you get the idea. Now let's look at login.cfm:

<form action="login.cfm" onSubmit="handleLogin();return false;" id="loginform"> <table> <tr> <td>Username:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password"></td> </tr> <tr> <td> </td> <td><input type="submit" name="login" value="Login"></td> </tr> </table> </form>

This is a fairly simple form - but note that I specifically block the form submission. I call yet another JavaScript function, handleLogin. So let's take a look at that:

function handleLogin() { ColdFusion.Ajax.submitForm('loginform','processlogin.cfm',handleResponse); }

Once again we have a use of the ColdFusion/Ajax API. The submitForm function will do exactly as it sounds - send an entire form block to a page. My last argument, handleResponse, is the function that will be called with the result. Let's look at processlogin.cfm first:

<cfsetting enablecfoutputonly="true"> <cfparam name="form.username" default=""> <cfparam name="form.password" default="">

<cfif structKeyExists(form, "login")> <cfif form.username is "paris" and form.password is "hilton"> <cfset session.loggedin = true> <cfoutput>good</cfoutput> <cfelse> <cfoutput>bad</cfoutput> </cfif> </cfif>

Nothing too complex here. Normally you would call a CFC to handle the authentication. I've never used a hard coded username and password in production. Really. Now notice that I output two strings: good and bad. Remember how I submitForm named a function to run with the result? Let's look at that now:

function handleResponse(s) { if(s == "good") { //first hide the window ColdFusion.Window.hide('loginwindow'); //rewrite out login var loginspan = document.getElementById('loginstatus'); var newcontent = "<a href='index.cfm?logout=1'>Logout</a>"; loginspan.innerHTML = newcontent; } else { alert('Your login didn\'t work. Try paris/hilton'); } }

The function was passed the response, so all I need to do is check the value. If it is good, I hide the window (again, using the ColdFusion/Ajax API. Now I do something fancy. It wouldn't make sense to keep the login link on the page. I wrapped my login link in a span:

<span id="loginstatus"><a href="javaScript:doLogin()">Login</a></span>

This lets me get the span and change the HTML inside. Pretty simple, right?

To see an online demo of this, go here: http://www.coldfusionjedi.com/demos/login/index.cfm

Obviously someone could do this a lot prettier then I did - but notice how nice it works. You can login from any page, and when done, you are still on the page you were looking at. (I do something like this for the contact form at CFBloggers.org.) Also note how little JavaScript was involved. The most complex bit was handling the result of the login, and even that was just about 10 lines of code.

Enjoy. I've attached the code to this blog entry.

Download attached file.