Drag and Drop Sorting with CFAjaxProxy and Script.aculo.us
August 25, 2008
I made a video player recently containing a list of videos. My client requested the ability to put them in a custom order. It didn’t take much research to find the functionality in the Script.aculo.us library. The question was, how do I implement it with ColdFusion?
I knew I would need AJAX functionality and, up to this point, I had always used Rob Gonda’s AjaxCFC. With the release of ColdFusion 8, however, Adobe introduced CFAjaxProxy. I’d been looking for an opportunity to give it a try and this turned out to be a perfect fit.
Jake Munson of Yacoblog posted a great introduction to using CFAjaxProxy. Simple and straight to the point. I had it working in no time.
My next stop was a post by Mohammed Irfaan over at the Lynch Consulting Blog which discusses a technique for using ColdFusion to update an underlying table after using Script.aculo.us’s Drag and Drop functionality.
Here’s how I put it all together:
First, I created a table named videocenter to hold my video records. It looks something like this:
video_uuid - Unique identifier for each video record
video_title - Title for the video record
sort_order - Integer reflecting the order in which the video should be displayed.
Next, I wrote my sortvideos CFC which will loop through the list of videos that my page will send to it, and update the sort_order column to reflect the order in which the video are currently displayed on the screen (more about that later):
<cfcomponent>
<cffunction name="updateVideoSort" access="remote" returntype="boolean">
<cfargument name="sortStruct" type="any" required="yes">
<cfset var q="" />
<cfset var i=0 />
<cfloop from="1" to="#ListLen(arguments.sortStruct)#" index="i">
<cfquery name="q" datasource="#application.dsn#">
UPDATE videocenter
SET sort_order = <cfqueryparam value="#i#" cfsqltype="cf_sql_integer">
WHERE video_uuid = <cfqueryparam value="#trim(listGetAt(arguments.sortStruct, i))#" cfsqltype="cf_sql_varchar" />
</cfquery>
</cfloop>
<cfreturn true>
</cffunction>
</cfcomponent>
After downloading and installing the Script.aculo.us JavaScript library, I began to build my page.
I started off by defining the Ajax proxy. This line defines my ColdFusion component (sortvideos) and the JavaScript proxy class that represents the CFC (respond):
<cfajaxproxy cfc="sortvideos" jsclassname="respond">
I then included the necessary Script.aculo.us files and the JavaScript function that will call the Ajax method within my ColdFusion component. Note that you may have to alter the path to the JavaScript files depending on where yours are stored:
<script language="JavaScript" src="js/scriptaculous/lib/prototype.js"></script>
<script language="JavaScript" src="js/scriptaculous/src/scriptaculous.js"></script>
<script type="text/javascript">
function resort() {
var r= new respond();
var orderList = '';
//call the echo function from the CFC
orderedNodes = document.getElementById("sortable_list").getElementsByTagName("li");
for (var i=0;i < orderedNodes.length;i++) {
orderList += orderedNodes[i].getAttribute('recordid') + ', ';
}
r.updateVideoSort(orderList);
}
</script>
When called, orderedNodes will become an array of the LI elements within the “sortable_list” UL element defined below. The elements in the array will be in the order in which the list appears on the page. This is the list that gets sent to the updateVideoSort method within my sortvideos CFC above.
Next, I loop through my video records and display the videos in an unordered list. I add an ID to the UL named “sortable_list” and I add a custom attribute to each LI element (recordid) containing video_uuid from my videos table. After that, I place a submit button that will call my resort() function when clicked.
<cfset qvideos = videosService.getVideos() />
<ul id="sortable_list" style="cursor: move; list-style:none;">
<cfoutput query="qvideos">
<li recordid="#video_uuid#">#video_title#</li>
</cfoutput>
</ul>
<input type="button" onclick="resort();" value="Submit new order" />
Finally, a last bit of required JavaScript to make the Script.aculo.us magic happen. Note that “sortable_list” is the id I gave to my UL element above.
Now I have a list of videos from my videocenter table which can be ordered using drag and drop functionality a la Netflix.
-rG
Posted in 
content rss
August 30th, 2008 at 7:17 pm
Can the same thing be done with the js libraries that come with CF8.0.1?
August 30th, 2008 at 9:58 pm
Hi Mark,
Drag and drop is not included in Adobe’s Spry library.
Glenn
September 11th, 2008 at 5:39 am
Thanks, I meant YUI or extJS.
September 16th, 2008 at 11:36 am
Mark, yes the same method can be used for extJS and YUI. I’m using it right now with extJS for a web based In/Out board.
Jeremy
October 20th, 2008 at 11:41 am
I tried to do a drag and drop as described above, but I’m getting the error:
exception thrown and not caught on the following line
throw new SyntaxError(”parseJSON”);
any hint?
thanks,
Ilir
January 2nd, 2009 at 12:04 am
[...] public links >> scriptaculous Scriptaculous Cheat sheet Saved by rafaeu on Tue 23-12-2008 Drag and Drop Sorting with CFAjaxProxy and Script.aculo.us Saved by toonpulse on Thu 18-12-2008 Weekly Top Standards-Most Gallery #20 Saved by PodBaby on [...]