Simple jQuery/ColdFusion form example

This post is more than 2 years old.

Last week I blogged a very simple example of jQuery to ColdFusion communication. At the request of a reader I created the simplest example I could come up with that demonstrated the basic concepts. Today I have a slightly more advanced example, one that specifically makes use of a form and a post operation.

My example is a very simple authentication system. The form has a username and password field. We want to integrate with a ColdFusion Component that will handle responding to the post from jQuery. Let's begin with the front end template.

<html>

<head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> $(document).ready(function() { //grab the submit action $("#loginForm").submit(function(e) {

	//stop the form submission
	e.preventDefault()

	//get my values
	var uval = $("#username").val()
	var pval = $("#password").val()

	//basic validation
	if(uval == '' || pval == '') return

	//disable the button
	$("#loginButton").attr("disabled",true)

	//Let the user know we are doing something		
	$("#result").html("Logging in...")
	
	//Send them to the CFC
	$.post("test.cfc?method=authenticate&returnformat=json", 
			{username:uval, password:pval},
			function(res) {
				//Handle the result
				if(res == "true") {
					$("#result").html("Your login worked.")
					//Do more here.
				} else {
					$("#result").html("Your login failed.")
					$("#loginButton").removeAttr("disabled")
				}
			})

})

}) </script> </head>

<body>

<form id="loginForm"> username: <input type="text" name="username" id="username"><br/> password: <input type="password" name="password" id="password"><br/> <input type="submit" value="Login" id="loginButton"> </form>

<div id="result"></div>

</body> </html>

Ok, we've got a few things to cover here. I'll begin with the HTML at the bottom. You can see my simple form (2 text fields and a submit button). Also notice the little "result" div at the bottom. I'll be using that later to provide feedback to the user.

Ok, now scroll up to the JavaScript. The meat of this template is all within one main event handler defined here:

$("#loginForm").submit(function(e) {

This is going to "take over" the normal form submission and let me do something else with it. Notice too that the very first command within the handler is: e.preventDefault(). This will ensure that my form never does actually submit (if the user has JavaScript enabled of course). Moving down, I grab the value from my two fields. I do this manually but jQuery does provide a few ways of serializing a form all at once. Once I've got that, I do some very simple validation. If either field is blank we leave the function.

Next up I disable the submit button. Remember that we're going to be doing an Ajax post, a network operation, and that isn't instantaneous. Disabling the submit button is an easy way to prevent a user from going click happy. We also add a status message so that the user knows something is going on.

The portion that actually performs the Ajax based request begins with $.post. We provide the URL first. Remember that you must pass the method to execute within the CFC. That's the method=authenticate part. You can - and normally should - provide a returnFormat argument as well to tell ColdFusion how to format the response. The second argument is a structure of data. These will be sent as POST fields to the CFC. Lastly we have a response handler. This is going to execute when the CFC returns a result to us. For our simple example we are assuming a string result of "true" or "false". Obviously there may be more complex results. In a longer form, you may have a set of error messages. In the result we either provide a "good" message or a "bad" message. As you can see in the comments, you would probably do a bit more on a good result. You may want to hide the form for example. Or you may actually push the user to another URL.

Now let's take a look at the CFC:

component {

remote boolean function authenticate(string username, string password) {
	sleep(1400);
	if(arguments.username == "paris" && arguments.password == "hilton") return true;
	return false;
}

}

Yeah, I love me some script-based CFCs. So as you can imagine, this would probably be replaced with a query call or perhaps LDAP. But that doesn't really matter here. I added a sleep command in there to help simulate a slow network. To see this yourself, click the big new fancy Demo button below.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Simon posted on 5/9/2010 at 1:57 PM

Thanks Ray another great example. As a beginner with jQuery it's so helpfull to see working examples with jQuery and coldfusion.

Comment 2 by Gary F posted on 5/9/2010 at 3:12 PM

Where's the link to the demo? (Kidding!!!)

Comment 3 by Vladimir posted on 5/10/2010 at 11:52 AM

Waiting for more examples! This is a very good jump start!

Comment 4 by LifeBane posted on 5/11/2010 at 1:43 AM

You could possibly clean it up a bit by moving everything from the get to the post:
[code]
$.post("test.cfc",
{'method':'authenticate','returnformat':'returnformat','username':uval, 'password':pval},
function(res) {
//Handle the result
if(res == "true") {
$("#result").html("Your login worked.")
//Do more here.
} else {
$("#result").html("Your login failed.")
$("#loginButton").removeAttr("disabled")
}
})
[/code]
Also I'd recommend putting quotes aroung username and password in the json object for clarity, as they look exavtly like variables without them.

Comment 5 by Raymond Camden posted on 5/11/2010 at 5:42 AM

I prefer the 'meta' stuff to be in the url, namely the method and returnformat. I _can_ say it has bugged me for sometime now the way my objects "looked" - I didn't know I could do:

"key":value

That's much better. Thanks!

Comment 6 by LifeBane posted on 5/11/2010 at 9:46 AM

One of the reasons to use 'post' instead of 'get' is that it acts as a deterrent against XSS (Cross Site Scripting) attacks. It's not a fail-safe however.

Comment 7 by Raymond Camden posted on 5/11/2010 at 1:42 PM

I've never heard that POST helps prevent XSS. Do you have a URL to back that up? I do know it allows you to send more data though.

Comment 8 by LifeBane posted on 5/11/2010 at 7:53 PM
Comment 9 by Raymond Camden posted on 5/12/2010 at 6:53 AM

Interesting. Their argument is that it is harder to hack forms. I disagree with this. Well, it _is_ harder, much like it is harder for me to take candy from a 4 year old versus a 2 year old, but I'm not sure I'd even recommend this as it may give people a false sense of security. It is _trivial_ to hack a form. Is it as trivial as a URL hack? No. But it will take an attacker all of 2-3 more minutes. Even less with the right Firefox extension.

Comment 10 by Raymond Camden posted on 5/12/2010 at 6:54 AM

I should add - I'm no security expert. So take the previous comment as my opinion only. :)

Comment 11 by LifeBane posted on 5/12/2010 at 7:28 AM

Ya, it wouldn't do anything to deter the kind of hackers you would need to worry about. I'm definitely not claiming to be a security expert either :) I guess just a tidbit to think about.

One possible advantage to having the metadata in the get portion of the url would be for bookmarking, however that's irrelevant when referring to ajax requests of course.

I've also read that using get instead of post, the data in the url gets logged, such as Apache logs, etc. I guess that could be an advantage or disadvantage depending on what you want, and the situation.

Comment 12 by Raymond Camden posted on 5/12/2010 at 2:44 PM

One more disadvantage of POST - the network traffic is higher. This was mentioned in the Client Side performance session at cfObjective.

Then again, POST is the _only_ safe way to send a lot of data. So if you are posting a form with a textarea, you pretty much _have_ to use POST.

Comment 13 by Maertsch posted on 5/14/2010 at 5:56 PM

Very handy with a onKeyUp expression. The user just typed the last char of his password and whom. logged in. without pressing a submit button or something else :)

Comment 14 by Chris posted on 6/21/2010 at 5:23 PM

How might you clear the username and password fields after successful logon?

Comment 15 by Raymond Camden posted on 6/21/2010 at 5:24 PM

Give u/p fields with IDs of "username" and "password":

$("#username").val("")
$("#password").val("")

Comment 16 by Chris posted on 6/21/2010 at 6:21 PM

And that would go after

$("#result").html("Your login worked.")

Correct?

Comment 17 by Chris posted on 6/21/2010 at 6:57 PM

Doesn't seem to be working, any ideas?

Comment 18 by Raymond Camden posted on 6/21/2010 at 6:59 PM

Did you use a username field with an ID value of username? Ditto for password? Is it online where we can see?

Comment 19 by Chris posted on 6/21/2010 at 7:02 PM

Ahhh, doesn't work in Chrome, but does in FF.

Comment 20 by Raymond Camden posted on 6/21/2010 at 7:03 PM

Can you share the URL?

Comment 21 by Chris posted on 6/21/2010 at 7:04 PM

No, it's not online and I did use the id's correctly. It's just an issue with Chrome. Works in both IE and FF.

Comment 22 by Raymond Camden posted on 6/21/2010 at 7:05 PM

Well, in general, Chrome is darn good - so I'm sure it can work. Can you share the source perhaps? (Don't paste here - use pastebin.)

Comment 23 by Chris posted on 6/21/2010 at 7:17 PM

Honestly, it's your exact code with my 2 additions for clearing the form. I agree with you about Chrome.

Comment 24 by Raymond Camden posted on 6/21/2010 at 7:19 PM

boggle - then you got me. :) I've got no idea why it would work fine in IE/FF but not Chrome. Normally it's "Works fine in FF/CHrome and not IE". I use Chrome 100% of the time now and don't see this.

Comment 25 by Raymond Camden posted on 6/21/2010 at 7:21 PM

Just tested in Windows/Chrome/5.X and it worked fine. Maybe open up the dev tools in Chrome and see if you see an error?

Comment 26 by Chris posted on 6/21/2010 at 7:26 PM

Sorry Ray, Chrome was caching something. Must be Monday morning. :)

Comment 27 by Ofeargall posted on 7/13/2010 at 11:56 PM

So I used this with a regular ol' component in my cfc, not a script based like you have and the return wouldn't work properly. I posted a question on stack overflow and someone said to use output="false" on the entire cfc to remove the white space in my return from the component. It worked like a charm.

I sort of narrowed it down by alerting the response and saw it had a wild amount of white space. My initial fix was to use res.trim() == ... and that worked.

My question is, if I set my entire cfc to output="false" to accommodate this particular function what else will that screw up? I've got all my queries and other logic in the cfc and I'm wanting to avoid any ghost errors.

Comment 28 by Raymond Camden posted on 7/13/2010 at 11:58 PM

Nothing at all else will screw up - unless you actually try to output from the CFC itself, which most folks never actually do.

So short answer - don't worry about it. I _always_ use output=false on my cfcomponent and cffunction tags. (Well, "always" being before I switched to ColdFusion 9.)

Comment 29 by Bill R posted on 7/1/2012 at 12:59 AM

Raymond,

Your CF blog is the best. Most understandable, most applicable, and easiest to follow. Thanks for this post.

Bill

Comment 30 by Raymond Camden posted on 7/1/2012 at 7:00 PM

Wow, very nice words. Thanks Bill.