A list of jQuery plugins I use

As part of his blog post today, Ray Camden and a number of the folks who posted comments pointed out that while it was great that there are a lot of plugins available for jQuery, the downside is that it's hard to know which plugins are any good.

I'm not a heavy plugin user, but I'd thought I'd list the few plugins and jQuery UI libraries that I've found to be very useful:

  • jQuery Form Plugin: this plugin appears in every project I've done since I started using jQuery. It makes it dead simple to submit forms via AJAX.

    (Oooh, it looks like the author's added some new features since the last time I download it...I'll have to check that out).

  • Tablesorter: this plugin was actually incorporated into version 1.0 of the jQuery UI library, but I don't see it listed in the current version of the UI library. This plugin lets you sort a table in ascending or descending order based on a selected column.

  • Sortables UI library: this part of the jQuery UI library lets you rearrange items on the page using drag-and-drop (something I've mentioned a number of times here on my blog).

  • TableDnD (Table Drag-and-Drop): the Sortables UI library I just mentioned does not work on table rows (tables are just "different," apparently), but this plugin lets you grab a row and move it up or down within the table.

  • curvyCorners: after trying a few different plugins aimed at letting you create curved corners for certain HTML elements (like <div>s), this plugin, although not perfect, seemed to work best.

    I must say that I couldn't get it to work right in IE, but that might have been because of the way I was using it. And it looks like the author has released a few updates since I last downloaded it, so that may not be an issue anymore.


Anyone else have any jQuery plugins they'd recommended using? Or recommend avoiding? :)

Creating a hyperlink that works with or without AJAX

The current project I'm working on includes a display page where users can see a list of messages generated for them by the system. Each message consists of an <li> element containing the text of the message followed by a hyperlink labeled "Delete".

I wanted to make it such that you could delete each message without refreshing the page, but still accommodate users who had JavaScript turned off, and without a lot of extra work.

How did I do it? Like so:

<!---Include the jQuery core file--->
<script type="text/javascript" src="/views/JavaScript/jquery-1.2.2.js"></script>

<script language="javascript">
//Set the typical jQuery ready event handler to fire when the document is ready for manipulation
$(document).ready(function () {

//Assign a click event handler for all of the 'delete' hyperlinks (which all have a CSS class of 'deleteLink')
$(".deleteLink").click(function () {

var linkObj= $(this);
//Take the existing URL in the 'href' value and append an additional URL variable
var ajaxURL= linkObj.attr("href") + "&js=1";

//Remove the li list element (the parent) the link belongs to
linkObj.parent().remove();

//Make the Ajax call
$.ajax({
type: "POST",
url: ajaxURL
}); //end of .ajax function

//This statement will prevent the browser from actually navigating to the address in the link
return false;

}); //end of .deleteLink click function
}); //end of document.ready function
</script>


<h2>Your Messages</h2>

<ul>

<cfoutput query="qryMessages">

<li id="#messageId#">

#message#<br />
<a class="deleteLink" href="index.cfm?fuseaction=#xfa.deleteMsg#&msgId=#messageId#">Delete</a>

</li>

</cfoutput>

</ul>

...The only other thing you need to do is put a conditional statement in the page/event that is called by the hyperlink that looks for the presence of the additional URL variable ("js" in this case).

If JavaScript is turned off, that additional variable will not be defined and the page/event will redirect the action back to the calling page once it's done deleting the message data from the database.

If JavaScript is turned on, the page/event will simply delete the message data (no action redirect), and the user simply sees that message item disappear from the list.

Some updates on reordering items with jQuery

If you follow my blog at all, you know I have a keen interest in being able to reorder items in a list and then record that change in order in a database using JavaScript, specifically with the jQuery UI Sortables component. Here's some things I've learned recently regarding the topic:

Reordering Nested Lists

In my last project, I created a tool that allowed my clients to rearrange nested lists of articles and article categories using the jQuery UI Sortables component and the techniques I demonstrated in an earlier blog post.

My clients were very excited about the tool when they saw it in the prototype, but they ran into some difficulty when they tried to use it themselves during the final testing. They found it hard to place an item at either end of a list block because there were no visual cues outlining the borders of the list.

It was also nearly impossible for them to move an item around in the top-most list: if they tried to place it in between sibling items or at the end of the list, the item would almost always get dropped at the end of whatever sublist came at the end of the sibling item above.

Finally, the scrollable <div> element containing the nested lists would not scroll to match the drag movement of the cursor, so if they needed to move an item from one end of the nested lists to the other, the item would have to moved in steps.

I solved all of these problems by abandoning the drag-and-drop technique and replacing it with a version of my "click-to-click move" technique. So now when they need to move an item, they click on an icon associated with each item (hidden until needed), and target <div>s are created above and below each item:

Image of move targets in my last project

They then just click on the target for the place they want the item moved to, and the item is "moved" and the targets are removed (technically, the item is cloned, the clone is put in the new position, and the original item is deleted).

They like the "click-to-click move" version a lot better, so perhaps that's a better means of reordering items when using nested lists. But I recently discovered jTree, a brand-new jQuery plugin someone wrote specifically for sorting nested lists using drag-and-drop. I tried out the demo for it, and it has visual cues to help you position items in the right list, but it does flicker a bit at times. Still, I might play with it the next time I have to deal with nested lists again.

Reordering Table Rows

Lists are nice, but they don't cut it when each item is really a collection of separate items: that's when you need a table. In my current project, I needed a way to reorder the rows in my table as a means of letting the user reorder the data records. The jQuery UI Sortables component, however, does not work on table rows.

I tried to create a pseudo-table by using <div>s within each <li> item to evenly space the data fields in each row. I got it working and looking slightly less than ugly in FireFox, but it didn't fare so well in IE.

I then went browsing through the jQuery UI discussion board on Google Groups and found a post that mentioned a plugin for sorting/rearranging table rows.

It's called TableDnD, and it's a slightly different approach to the challenge. When you click on a row and drag it, there is no drag outline and no gradual movement: if you move up far enough, the content of the row you're dragging and the row above it quickly switch places, and vice-versa if you move downward. It highlights the moving row as you move it so you can keep track of what's happening. The movement is very smooth and you can go as fast as you like.

The only drawbacks I'm aware of so far is that the dragging action will not trigger the scroll bar if you're trying to drag the row beyond the visual limit of the window or scrollable container (much like my original nested list tool), and someone pointed out to me that if you fill all of the cells in a row with other DOM elements such that you cannot click on any of the cells themselves, you won't be able to grab the row and move it. That's not a problem your table cells just contain text, but it's something to keep in mind if you plan on formatting the text with <span> tags or providing input boxes for the user to edtit the cell data.

Problem: No Drag-and-Drop On The iPhone/iPod Touch. Solution: Click-To-Click Move

As I mentioned in an earlier blog post, the drag-and-drop functions provided by various JavaScript libraries (jQuery, YUI, etc.) won't work in the iPhone/iPod Touch Safari web browser because the dragging gesture is used for scrolling around the web page.

That's a big problem for those of us who use drag-and-drop in our web applications to allow our users to reorder the items in a list, but I've come up with an alternative method for rearranging items using the jQuery JavaScript library that works on the iPhone/iPod browser as well as regular browsers. I call it the "Click-to-Click Move" method (CTCM).

[More]

ColdFusion 8's Image Functions + jQuery= A UI For Adding Text and Color Blocks Into An Image file

One of the new features in ColdFusion 8 is the ability to manipulate images using ColdFusion tags and functions. For example, the code below (all server-side code) will take an image file on the server, overlay it with text, and create a brand new image file in temp space and display it to the browser:

<!---Assign the image file to the carImage variable--->
<cfimage name = "carImage" action="read" source="ferrari.gif"/>
<!---Add the text "Fast car!" to the image and place it 10 pixels from the left and 15 from the top--->
<cfset ImageDrawText(carImage, "Fast car!, 10, 15)>
<!---Display the new image--->
<cfimage source="#carImage#" action="writeToBrowser">

A week ago, an idea popped into my head: "What if you could create a UI tool that would let a user decide what text should appear on the image and where it should appear?"

I decided to try and answer that question. The result: a working proof-of-concept that lets you add text and blocks of color anywhere on a selected image using a UI tool powered by jQuery JavaScript functions. When you're done manipulating the image, you submit the data defining your changes to ColdFusion via an AJAX call, and ColdFusion creates a new image in temp space based on that data and displays it. You can save the new image down to your computer or store the data you submitted in the database so the image you made can be reproduced without permanently storing a new image file.

The fact that it only took me a week to do this (no more than 25 hours) is a testament to both the power and simplicity of ColdFusion and jQuery.

You can try out the proof-of-concept at: http://www.swartzfager.org/captionator

Update: I updated the title as I realized that describing this as an "image captioning program" might be interpreted as simply storing captions to associate with an image, not adding the text onto/into the image.

Changing Individual CSS Styles with jQuery

Back when I was writing my own custom JavaScript functions, I learned that there wasn't a single, simple way to change the individual style settings (like "font-weight:bold") for an HTML element that worked on every browser. My solution was to change the CSS classes assigned to the element instead: I wrote a library function that would allow me to add, remove, or replace any class assigned to an HTML element and simply created as many class definitions as I needed in order to accommodate the style changes. It was actually a pretty effective workaround because it let me effectively change multiple styles with one function call.

When I started using jQuery, I quickly learned about the "addClass" and "removeClass" core functions, which I could use instead of my library function:

$("#missionStatement").addClass("importantTextClass");
$("#userProfile").removeClass("hideTextClass");

...So I continued with my routine of changing styles by changing classes, even though sometimes I only needed to change or remove a single style setting. No harm, no foul.

But changing classes wouldn't work for the wacky little project I've been working on recently: I needed to be able to change several styles for an HTML element individually, and writing a class to handle every permutation of the possible style combinations was impractical.

So I went to the jQuery web site, hopeful that the brilliant folks at jQuery had something that could help me out.

And they did: the "css" core function allows you to read or set any individual style or styles:

if ($("#missionStatement").css("font-weight")== "400" || $("#missionStatement").css("font-weight")== "normal")
{
$("#userProfile").css("display","none");
$("#missionStatement").css({ fontSize:"24px", fontWeight:"bold" });
}

Have I mentioned that I love jQuery? :)

Alpha Releases Out of Updated jQuery UI and Brand-New jQuery Enchant Libraries

As demonstrated from some of my previous posts, I'm a big fan of jQuery, so this news caught my attention.

The new jQuery Enchant library is a library of visual effects: bouncing, shaking, fading, folding, exploding (didn't know what to expect with that one), etc.

Here's the link to the announcement on Google Groups:

Get it while it's hot: jQuery UI 1.5a and jQuery Enchant 1.0a!

In the thread, you'll find the links to the alpha demo pages.

Apparently, there will also be an update to the jQuery core file in order to support these alpha releases (also mentioned in the thread linked above).

Sorting a Nested List Using jQuery And Saving the Changes

A screenshot of the sorting demoA reader asked me if it was possible to sort/rearrange items in nested lists (lists within a main list) using the jQuery UI Sortables code. I told him that it was, and I had actually created a tool for a client recently that made use of that feature.

He wanted to know more about how to do it, so I went ahead and created a downloadable working demo of how to do it.

[More]

Techniques For Providing Instructions Within A Web Application

Some of the processes you find in web applications are fairly standard. Most folks can fill out a contact form, or fill out a survey, or make a calendar entry without the need for too much explanation. But what do you do when the form involves business rules that the user may or may not know, or presents the user with a number of options?

[More]

How to Use the Same Server-Side Code to Validate Form Data With or Without AJAX Using jQuery

In any web application, if the user submits information to be stored in a database using a form, you always want to validate that information before it's stored in the database. The majority of users have JavaScript enabled in their web browser, allowing you to use JavaScript functions to validate the data on the client-side before the submission is allowed to proceed. However, there are those rare individuals who have JavaScript turned off, so a conscientious developer will also validate the submitted data on the server side as well as a backup.

The problem with this is that you end up having to maintain two sets of validation functions, which means twice the work if you have to make a change to the submission form or the validation rules themselves. In addition, if you're not experienced with JavaScript, you may find it harder to write the JavaScript validation code than similar code in your server-side programming language of choice.

In an earlier blog post, I wrote about how the latest version of ColdFusion, ColdFusion 8, provides a new tag called <cfajaxproxy> that allows you to make JavaScript calls to functions contained in ColdFusion Component (CFC) files on the server, enabling you to write your validation code within CFC functions and call them for either client-side or server-side validation.

But what if you're not running ColdFusion 8 yet, or you're using another web programming language (like PHP)?

Here's a technique I came up with using the jQuery JavaScript library and the jQuery Form plugin that lets you write your validation and database-update code on the server-side in such a way that you can either call it via AJAX if JavaScript is enabled or run it server-side if JavaScript isn't available:

[More]

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.1.004.