Learning jQuery: Day 2
Today, we're going to do some sorting using jQuery's complementary library, jQuery UI. We'll also learn a bit about a terrific tool for jQuery UI: ThemeRoller.
Let's start by heading over to the jQuery UI site: http://jqueryui.com/download. jQuery UI comes with a number of widgets and interactions and integrated themes for all of these. We'll begin by choosing a theme.
On the right side of the page, you'll see a drop-down box for selecting pre-built themes. (You can also roll your own.) I'll accept the default "Smoothness" theme, but feel free to experiment with one you find more exciting.
You're given a choice of components you wish to download. For simplicity's sake, I'll accept the default choice of all. Clicking the "Download" button is next. Unzip the downloaded file and place the folder at your web root.
Now, to use the jQuery UI sorting capabilities. Suppose your child comes to you one day with a note from his/her teacher that reads "Your child is having trouble alphabetizing things. If you don't do something quick, they'll end up as either a politician or a televangelist or, if they're quite fortunate, a used car salesperson."
Well, that was enough to get your attention! You decide to use your mad programming skilz to help your little one. But what to do, exactly?
Luckily, you happen to come upon a blog post entitled "Learning jQuery: Day 2" and found that your situation exactly matches that described. With baited breath, you read on...
Let's start by using one of the tags new to ColdFusion 8: CFAJAXPROXY. This tag provides a JavaScript proxy to a CFC. The CFC looks like this:
<cfset variables.instance.composers = ["Bach","Beethoven","Britten","Ives","Mozart","Shastakovich"]>
<cffunction name="randomComposers" access="remote" output="false">
<cfset var myComposers = "">
<cfsavecontent variable="myComposers">
<li class="ui-state-default" id="Britten">Britten</li>
<li class="ui-state-default" id="Shastakovich">Shastakovich</li>
<li class="ui-state-default" id="Bach">Bach</li>
<li class="ui-state-default" id="Mozart">Mozart</li>
<li class="ui-state-default" id="Ives">Ives</li>
<li class="ui-state-default" id="Beethoven">Beethoven</li>
</cfsavecontent>
<cfreturn myComposers>
</cffunction>
<cffunction name="check" access="remote" output="false">
<cfargument name="sortedComposers" required="true" type="array">
<cfset var correct = ArrayToList(variables.instance.composers)>
<cfset var attempt = ArrayToList(sortedComposers)>
<cfreturn correct EQ attempt>
</cffunction>
</cfcomponent>
Now, we'll create the page that uses both the proxied CFC and some jQuery:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>jQuery Alphabetization Page</title>
<link type="text/css" href="/jquery-ui-1.7.1.custom/css/smoothness/jquery-ui-1.7.1.custom.css" rel="stylesheet" />
<script type="text/javascript" src="/jquery-ui-1.7.1.custom/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/jquery-ui-1.7.1.custom/js/jquery-ui-1.7.1.custom.min.js"></script>
<style type="text/css">
#sortable { list-style-type: none; margin: 0; padding: 0;}
#sortable li { margin: 0 5px 5px 5px; padding: 5px; width: 150px;}
.ui-state-highlight {color : green;}
</style>
<script type="text/javascript">
var sorter = new Sorter();
sorter.setCallbackHandler(function(response){
if (response == true){
alert(response);
} else if (response == false){
} else{
$('#sortable').html(response);
}
});
$(document).ready(function() {
$("#sortable").sortable({
placeholder: 'ui-state-highlight',
axis: 'y',
containment: 'parent',
cursor: 'pointer',
opacity: 0.6,
update: function(event, ui){
var order = $('#sortable').sortable('toArray');
sorter.check(order);
}
});
sorter.randomComposers();
});
</script>
</head>
<body>
<ul id="sortable">
</ul>
</body>
</html>
What's going on? The first line sets up the CFAJAXPROXY, telling ColdFusion that we're going to use a CFC in the current directory and that we'll give it a JavaScript name of "Sorter" (it could be anything we like).
In the "head" section, we link to the css file provided by the jQuery UI and include the jQuery base library and the newly-downloaded jQuery UI library.
Inside a "script" tag, the call to "var sorter = new Sorter();" give us a handle on the JavaScript proxy object. Then a function is provided that will be called whenever our proxied CFC returns a value. If the response is "true", we'll alert the user. (To get things started, I've included a bit of jQuery code to take the initial response (the unsorted composer list) and place it on the page.*)
The next bit of code requires more explanation.
Beginning with "$(document).ready(function(){", we are in jQuery land. The beginning line can be read thus: "Once the document is ready to be worked with, run the code in this anonymous function."
Inside the anonymous function (meaning that the function is unnamed), is an instruction to take the DOM element with an id of "sortable" and call the "sortable" method. (We get this method from the jQuery UI JavaScript previously included.)
Several options are passed into this method. All are optional and I'll leave it to you to read about these (and others available) on the jQuery UI documentation. The only one really important to us the "update" option. This tells the jQuery UI that when the user drags and drops an element specified in the jQuery selector ("#sortable" in our example), another anonymous function should be run.
This anonymous function asks jQuery UI to provide an array of the sortable elements' "id" attributes and to place it into the variable, "order". Then, we use our JavaScript proxy object, calling the Sorter CFC's "check" method.
The last statement in our $(document).ready function gets us started by a proxy call to the "randomComposers" method, which will return HTML code that will be placed as children in the DOM element with the id of "sortable" -- the very element we told jQuery UI we wanted to be able to sort.
Yes, there's a lot going on, but if you work through the code, I think you'll see that you'll be able to employ this technique to save your child from a life of abandon.
No, no -- don't thank me; I just can't bear the possibility of another televangelist.
Demo: http://dev.citymind.com:8500/test/blog_jquery/day2/sorting.cfm
*Note: Some of the code here (especially within the anonymous callback function is a little sketchy. I simplified things for the sake of keeping this tutorial as brief as possible.

