Playing with jQuery - ColdFusionBloggers.org Update

This post is more than 2 years old.

A while ago I built and released ColdFusionBloggers.org as a way to demonstrate and learn about new ColdFusion 8 Ajax technologies. Since then I've wanted to come back to the site and rebuild it using Spry or JQuery. Not because I wasn't happy with the CF8 Ajax stuff, but because a) it's fun to totally rebuild your own sites and b) I wanted to learn more about jQuery.

I also know that the site had a big footprint. YSlow was reporting around 600k of stuff which is a bit much. I was curious to see what a change to jQuery would be like.

I had looked at jQuery a few weeks back. I sat in a good presentation on jQuery (one that focused on the UI stuff) and it seemed like something that wouldn't be too hard to play with.

I began by working on the main guts of the site - the content div. This is the list of blog entries with pagination. Previously this was done with cfdiv. In general this was a super simple implementation outside of the support I had to do for restoring a page based on URL.

This was mainly done using ColdFusion.navigate. In jQuery there is a similar function - load. So I replaced:

ColdFusion.navigate(someurl,somediv)

with

$("#content").load(baseurl);

Simple enough - but not really too much different from the ColdFusion 8 method.

The next issue I ran into was the contact form. This created two problems for me. First off - it seems as if jQuery's built in UI stuff is still in development. While there are ten billion jQuery plugins, as a new user this is actually more of a bad thing then a good thing. I mean as a new user I had no idea what to use. Scott Stroz pointed me to jqModal, which worked easily enough, although my contact form now is a bit uglier compared to what it used to be.

The second problem was how to handle submitting the form. Once again - ColdFusion had a simple way of doing this - ColdFusion.Ajax.submitForm(formid,url,etc). In jQuery I converted this to $.post("url", { data and callback here}). I was a bit surprised that I had to specify the form values. I'm not sure I really need to. The docs say it's optional. But they don't say if it will send the entire form to the URL. I assumed it wouldn't and typed it all out:

$.post("sendcontact.cfm",{dname:$("#dname").val(),demail:$("#demail").val(),comments:$("#comments").val()},formDone);

If I'm right and it is required that you specify the data, then ColdFusion definitely wins here.

Other changes I made were to remove the autosuggest and make the stats pod stop reloading. That was a bit silly in retrospect.

I'm pretty impressed with jQuery. It's not quite as friendly as Spry, but it does seem pretty darn powerful. I hope the UI project continues to evolve as I think it makes sense for jQuery to provide a "best of breed" UI selection for it's users.

Oh - and does size matter? Well, my unscientific testing seems to show the new site reacting just as quickly as it used to. YSlow says the size is now down to 200k or so, which is incredible, but I didn't get the "wow" I thought I would with the switch.

A few quick final notes. The entire site has not been converted to jQuery. The feeds for example still use CF8 UI stuff. The code zip you can download is also out of date now obviously.

Any comments on my use of jQuery are appreciated, but be gentle as I have a grand total of 2-3 hours experience with it!

p.s. I'd especially appreciate a suggestion on how to handle the "loading" status that I lost when I left cfdiv. Right now it's not immediately apparent that you've begun an AJAX request to load new data.

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 John Whish posted on 5/13/2008 at 10:43 PM

Hi Raymond,
As a jQuery fan, it's great to see someone with your standing in the CF community using it because I've been considering working more with Spry and EXT2 instead as they now ship with CF8 and I didn't want to get stuck in the "familiarity" trap of sticking with jQuery when the rest of the CF community has moved on :)

Comment 2 by Jim Priest posted on 5/13/2008 at 10:50 PM

Since Rey Bengo is busy with new a new baby - I'll say it for him - "Go jQuery!"

If you aren't already on the jQuery mailing list - I'd hop on - it's a bit heavy traffic wise but there are lots of CF folks on there as well as lots of people willing to offer advice.

You may want to try the 'min' version instead of the packed version of jQuery. I know there have been discussions on the list about which is better/faster (also depends how your server is setup).

Comment 3 by Raymond Camden posted on 5/13/2008 at 10:57 PM

When I tried the first link on the jquery site, which is labeled as minified and 15kb, the link led to a file that was 50ish k, not 15. That's why I switched to the packed one. If you can tell me what I did wrong, I'll replace it.

Comment 4 by Scott P posted on 5/13/2008 at 11:00 PM

jQuery rulez.

Comment 5 by todd sharp posted on 5/13/2008 at 11:02 PM

I'd set a 'loading' message when the load is initiated (before the call to .load) and then hide it in a callback function. Looks like the third argument for .load is a callback handler (http://docs.jquery.com/Ajax....

Comment 6 by Jim Priest posted on 5/13/2008 at 11:05 PM

The 'min' version is a bit bigger - BUT - if your web server doesn't have to spend time unpacking it it's a bit faster, esp. since it gets cached on the browser after the first load.

http://groups.google.com/gr...

Comment 7 by Raymond Camden posted on 5/13/2008 at 11:11 PM

So if I get the min version, save it over my JS, it willb e quicker. Magically? (I guess I should read the link.)

@ToddS - would you mind doing a quick demo? :)

Comment 8 by Raymond Camden posted on 5/13/2008 at 11:13 PM

@JP - So I don't get it. Do I just get the min version or do I have to get it and zip it?

Comment 9 by Jim Priest posted on 5/13/2008 at 11:17 PM

Grab the jquery.min.js version and just replace the .pack. version you have now...

/js/jquery.min.js

It may be slower on the first load but subsequent loads should be faster as the server won't have to unpack it each time... (read the link) :)

Comment 10 by Dan G. Switzer, II posted on 5/13/2008 at 11:18 PM

@Raymond:

You want the "Form Plug-in"--that plug-in will allow you to automatically post a form via AJAX (it'll serialize the entire form for you automatically.)

The Form Plug-in will also handle file uploads--which I don't think CF currently does (but I could be wrong.)

Comment 11 by Andrea posted on 5/13/2008 at 11:22 PM

Ray,

I am glad you are trying Jquery.
For forms ajax submit try this plugin:

http://www.malsup.com/jquer...

I have a custom tag that can be interested for you on my website for ajax forms using jquery.

Andrea

Comment 12 by Raymond Camden posted on 5/13/2008 at 11:24 PM

@DS - I did read it, but didn't quite get it. But it is done. Using the min version now.

@Andrea - trying to avoid plugins for now. So if it isn't built in, I'll stick with my code as is.

Comment 13 by todd sharp posted on 5/13/2008 at 11:24 PM

Well here is some pseudo code:

Imagine a div where you want to display your 'loading message':

<div id="loadMsg" style="display:none;">Loading...</div>

In your script you'd have:

//i don't know jquery...so use jquery to get the element:
document.getElementById('loadMsg').style.display = 'normal';
$("#content").load(baseurl, "", cbFunc);

cbFunc = function(){
document.getElementById('loadMsg').style.display = 'none';
}

You get the idea (I hope).

But as I said, I'm not a jQuery expert (or even a regular user)...so anyone can feel free to propose a different (better) way.

Comment 14 by Brian Swartzfager posted on 5/13/2008 at 11:39 PM

jQuery has a hide() function built-in, so where Todd used:

document.getElementById("loadMsg").style.display= 'none';

...you could do...

$("#loadMsg").hide();

Personally, I tend to create a CSS class called "hideElement" with the "display:none" style setting, then add or remove that class as needed:

$("#loadMsg").addClass("hideElement");

Comment 15 by todd sharp posted on 5/13/2008 at 11:43 PM

Nice Brian! Thanks. As a side note for the accessibility crowd - Sandra Clark told me at cf.objective that display:none is not 'accessible' - I forget why (hey I had a few beers at that point) - but I suppose that is a discussion for another day.

Comment 16 by Mike Hodgson posted on 5/13/2008 at 11:44 PM

Further to Todd's example (which is the way I would do it), you can show and hide the loadMsg div using:

$("#loadMsg").hide();
$("#loadMsg").show();

We just finished a simple e-commerce site using ColdFusion and jQuery for one of our clients: http://www.smallworldbaby.com

Comment 17 by Mike Hodgson posted on 5/13/2008 at 11:45 PM

Aaaaand... Brian beat me to it :)

Comment 18 by Raymond Camden posted on 5/13/2008 at 11:48 PM

I'm going to give this a try. I'll steal a graphic from that ajax-load site and see if I can make this work.

As we all know - it isn't a Web 2.0 site w/o the loading indicator.

Also - I don't think I've seen anyone comment - is the site faster for you guys?

Comment 19 by todd sharp posted on 5/13/2008 at 11:50 PM

Define 'faster' - no, don't do that...I'm kidding.

It never seemed 'slow' to me...

Comment 20 by Rey Bango posted on 5/13/2008 at 11:53 PM

OMG!!!! Camden is using jQuery! Hell has frozen over!!!! Everyone, take a screencap of this blog post. It's like a bigfoot sighting! ;)

Welcome to jQuery Ray. Let me know if you need some help. Be sure to sign up to the list as well as @jquery & @jqueryui Twitter accounts.

@Jim: Thx for stepping in while I was tending to my new addition :)

Comment 21 by Josh Nathanson posted on 5/13/2008 at 11:54 PM

Hi Ray,

If/when you get around to using plugins, you'll like the Form plugin that others have mentioned. It's the de facto standard for doing ajax form submits.

It's cool because it's totally unobtrusive. All you have to do is this:
$("#myformid").ajaxForm({ success: callbackfunction });

This binds the ajax submit to the form, picks up the action attribute of the form as the submission url, packs up the form data for you, and returns whatever your server response is to the callback function.

Welcome to jQuery!!!

Comment 22 by Josh Nathanson posted on 5/14/2008 at 12:00 AM

Oh yeah, also in regards to the "loading" message, there is another plugin called "BlockUI" that handles that sort of thing very nicely - it's by the same author as the Form plugin.

To block a certain element you might do:
$("#mydivtoblock").block();

Then in your callback:
$("#mydivtoblock").unblock();

Comment 23 by Raymond Camden posted on 5/14/2008 at 12:03 AM

Guys - reload and comment.

I don't like how the loader is place. But the code was rather simple to do.

Any suggestions on how to place my loader?

Comment 24 by Brian Swartzfager posted on 5/14/2008 at 12:18 AM

@Todd: I believe "display:none;" causes accessibility problems because screen readers will never load any content affected by the style, even when you do display it. I tend to put most of my DHTML in the administrative/internal pages of my applications where accessibility isn't really an issue, but I probably should find a better alternative.

Comment 25 by Andy Matthews posted on 5/14/2008 at 12:29 AM

@ Mike Hodgson

Easier to use toggle(), rather than show() and hide().

That way you let jQuery maintain the state of the object for you.

Comment 26 by Brian Swartzfager posted on 5/14/2008 at 12:31 AM

Regarding the loader...maybe you could make it bigger and make it appear in the left side of the banner div (under the Home and Feeds tabs) with a "float:left;" That might look cool.

Comment 27 by Brian Swartzfager posted on 5/14/2008 at 12:35 AM

@Andy: Isn't the toggle() function designed primarily for user-generated events like mouse clicks? I'm not sure it would be appropriate in this case.

I've used it in some of my apps, but there are certain situations you can get into where the current state of the toggle gets out of sync with the state of the object manipulated by the toggle.

Comment 28 by Rey Bango posted on 5/14/2008 at 1:02 AM

@Brian: You can use toggle() to change the display status at anytime, not just user-generated events. In fact, it's best practice to do that since it minimizes the amount of code you write and it actually keeps an internal cache of the last status of the specific element you're toggling

Comment 29 by Raymond Camden posted on 5/14/2008 at 1:08 AM

@BS - I made it bigger - and used the float.

Comment 30 by Hatem Jaber posted on 5/14/2008 at 1:10 AM

If you want to do client side validation try the validation plugin by bassistance, it's the best out there IMO.

Comment 31 by Nathan Strutz posted on 5/14/2008 at 1:17 AM

Something I didn't see here yet - you can serialize a form without the jQuery form plug-in. Just do this:

$.ajax(url, $("#myForm").serialize(), callback);

Check my favorite reference, visual jQuery: http://visualjquery.com/ - It's under Ajax functions.

Comment 32 by Rey Bango posted on 5/14/2008 at 1:29 AM

@Nathan: Nice code.

@everyone: Please use the API docs on the jQuery site or here (http://remysharp.com/jquery... as they're current.

Comment 33 by John Farrar posted on 5/14/2008 at 3:35 AM

Shameless Promotional Spot for CFUnited...

http://cfunited.com/go/topi...

That is the session but if you guys want a full load I suggest arriving a day early and attending Hal Helms class.

http://teratech.com/go/trai...

:) Hope to meet other jQuery enthusiasts there also.

Comment 34 by Brian Swartzfager posted on 5/14/2008 at 4:20 AM

@Rey: So how do you invoke the toggle() event without a mouse click? Via the trigger() or triggerHandler() function?

Comment 35 by Azadi Saryev posted on 5/14/2008 at 6:21 AM

First, it's awesome to see people like you using jQuery, but then many have said that already.

Now, I think you can do better on the 'loading' indicator for the home page - it is still not as 'pretty' as it can be...

I tend to do something like this for ajax links:
$(".mylink").click(function() {
$("#contentdiv").html("<img src='images/ajax-loader.gif' class='loadergif' alt='Loading content...' /> Loading content. Please wait...");
$.get(url, function(data) {
$("#contentdiv").html(data);
}
}

This way you can show the 'loading' image with any text you want. But that is just my way of doing it...

The Feeds page is rather slow, but I think it is not jQuery-based yet, is it? Or maybe it is my Internet connection - it is not really exceptionally fast here in Laos...

As for 'popup' windows - have a look at Thickbox and Impromptu plug-ins. I know you said 'no plugins', but then you did use jqModal...

One other thing is: the site is rather useless with js turned off... Sure, it is a Web 2.0 site, but... still better if it works no matter what the user setting are... At least a 'js turned off!' warning can be helpful.
I know, not many users have js disabled, but nonetheless - even a web2.0 site should be friendly to users who are not quiet web2.0'd yet...

But a great site overall and extremely useful! It has replaced pretty much all the other feeds I used to peruse. Have kept your cfjedi separate, though - I like to get full feed from it, not just 3 first lines :)

Comment 36 by Raymond Camden posted on 5/14/2008 at 6:52 AM

@Azadi - I'll try your code out. That's what I wanted really - to make the main div show the loading, and _then_ the real content.

Yes - the feeds page is still cfdiv, but it's more slow due to some bad SQL I haven't gotten around to optimizing yet.

Comment 37 by John Whish posted on 5/14/2008 at 12:12 PM

I tend to hide my elements using the jQuery hide method instead of using an inline display:none or setting it in the stylesheet, so that screen readers etc (which don't have js) will read all elements - this should make it accessible.

Comment 38 by Sukhminder Singh posted on 5/14/2008 at 1:38 PM

Good to know that you are exploring JQuery. I am developing stuff using CF for many many years now, but will not opt for CF8 Ajax; just look at the JS includes and JS code you will get.

And why to use JModal (save a http request) you will have flash problems - looking through your form - as you see in your contact form; you can very easily hide the main content and in a seperate div show the form and once submitted display the main content back again.

www.ranglapunjab.net - I have developed it entirely in CF and jQuery

Comment 39 by Nate Chapman posted on 5/14/2008 at 8:50 PM

I was really stoked about the cf8 ajax features until I used Firebug and saw all the extra files that were being loaded. That immediately made me changed directions. Right now I'm saving around 300k by going with jQuery/Thickbox instead of cfwindow.

It would be awesome if ajax ui features in future coldfusion releases were more lightweight.

Comment 40 by Tariq Ahmed posted on 5/14/2008 at 11:59 PM

Thanks for posting that Ray. I've been reading up on JavaScript Toolkits/Frameworks for awhile now. I've been highly interested to see someone give Spry & jQuery a thorough usage.

I've dabbled with Spry, and read up on jQuery.

One area that matters a lot to me is documentation. I've found is Spry's documentation is simple, straightforward, and answers what I'm trying to do quickly.

jQuery - I just did a double check... looks like they've come a ways in this area. When I first looked at it, the documentation was just a collection of disparate blog postings. Nice to see the improvements. And they have at least 2 books on the subject available.

In playing around with Spry I found it CRAZY EASY to get into, and like how they support data binding - which I don't think is a feature jQuery supports...?

Comment 41 by Raymond Camden posted on 5/15/2008 at 12:52 AM

@Tariq - Agreed. I think the way Spry handles getting and displaying structured data is the best. Period. Afaik, in Jquery, you would need to do some looping and string parsing yourself. Not that it would be impossible of course.

Comment 42 by Timothy Farrar posted on 5/15/2008 at 1:23 AM

Ray,
Will this mean there will be a new sect of Jedi?

JQJedi's?