Sorting Lists with JQuery UI, AJAX and ColdFusion
Join the DZone community and get the full member experience.
Join For FreeSomeone asked me the other day about an old post I did about Sortable list with jQuery and Coldfusion. jQuery UI has been released since I wrote that post so I thought I might as well post an updated version with some additional functionality. Before I continue, I should point out that although I've included some basic security in the demo, requests from the browser can be spoofed so you need to be diligent about security.
What this bit of code does, is allow you to sort a list, the new order is saved automatically using a bit of AJAX. You can also make items go to the top of the list (which is handy if you have a long list which gives you scroll bars in the browser), and also delete items from the list.
Sortable.cfc
<cfcomponent output="false" hint="I respond to AJAX requests"> <!--- -------------------------------------------- Remote Methods -------------------------------------------- ---> <cffunction name="updateOrder" output="false" access="remote"> <cfargument name="orderedList" required="true" type="string"> <cfargument name="key" required="true" type="string"> <cfset var ndx = ""> <cfset var id = 0> <cfset var position = 0> <cfset var updatedids = ""> <cfset var result = {result="false"}> <!--- do a basic security check ---> <cfif isAllowed( arguments.key )> <!--- Prevent race conditions ---> <cflock name="updateOrder" timeout="60"> <cftransaction> <cfloop list="#arguments.orderedList#" index="ndx"> <cfset id = Val( ListLast( ndx, "_" ) )> <cfset position = position+1> <cfset updatedids = ListAppend( updatedids, id )> <cfquery datasource="mydsn"> update myTable set order = <cfqueryparam value="#position#" cfsqltype="cf_sql_integer"> where id = <cfqueryparam value="#id#" cfsqltype="cf_sql_integer"> </cfquery> </cfloop> <!--- delete any items not in the list ---> <cfquery datasource="mydsn"> delete from myTable where id not in ( <cfqueryparam value="#updatedids#" cfsqltype="cf_sql_integer" list="true"> ) </cfquery> </cftransaction> </cflock> <cfset result = {result="true", neworder=updatedids, position=position }> </cfif> <cfreturn result> </cffunction> <!--- -------------------------------------------- Private Methods -------------------------------------------- ---> <cffunction name="isAllowed" output="false" access="private" returntype="boolean"> <cfargument name="key" required="true"> <cfset var result = false> <!--- check that request is coming from the same browser that created the session ---> <cfif IsDefined( "session.ajaxkey" ) AND ( session.ajaxkey eq arguments.key )> <cfset result = true> </cfif> <cfreturn result> </cffunction> </cfcomponent>
sortingdemo.cfm
<html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js"></script> <style type="text/css"> #sortable { list-style-type: none; margin: 0; padding: 0; width: 60%; } #sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 18px; width:400px; border:1px solid gray; background-color:lightgray;} #sortable li span { float:right; margin-left:2px; padding:0px; border:1px solid blue; background-color:lightblue;} </style> <script type="text/javascript"> $(function() { $sortable = $("#sortable").sortable({ update: function(event, ui){ updateOrder(); } }).disableSelection(); $('<span>delete</top>').css('float','right').appendTo( $('li', $sortable) ).click(function(){ $this = $(this); $this.parent().remove(); updateOrder(); }); $('<span>top</top>').css('float','right').appendTo( $('li', $sortable) ).click(function(){ $this = $(this); $li = $this.parent().detach(); $li.prependTo($sortable); updateOrder(); }); function updateOrder(){ $.getJSON( 'http://yourserver/sortable.cfc?wsdl', { method : 'updateOrder', key: '<cfoutput>#session.ajaxkey#</cfoutput>', orderedList: $sortable.sortable('toArray').toString(), returnformat: 'json', queryformat: 'column' }, callback ); } }); function callback(json){ if ( json.RESULT ) { $('#serverresult').text( "Order updated to: " + json.NEWORDER ); } else { $('#serverresult').text( "Something went wrong!" ); } } </script> </head> <body> <div class="demo"> <ul id="sortable"> <li id="id_1">Item 1</li> <li id="id_2">Item 2</li> <li id="id_3">Item 3</li> <li id="id_4">Item 4</li> <li id="id_5">Item 5</li> <li id="id_6">Item 6</li> <li id="id_7">Item 7</li> </ul> <div id="serverresult"> </div> </div> </body> </html>
Application.cfc
<cfcomponent output="false"> <cfset this.name = Hash( GetCurrentTemplatePath() )> <cfset this.sessionManagement = true> <cffunction name="onSessionStart" returnType="void" output="false"> <!--- we'll use this key to provide some basic protection for the AJAX webservice ---> <cfset session.ajaxkey = CreateUUID()> </cffunction> </cfcomponent>
I hope it's useful
Published at DZone with permission of John Whish, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
How To Manage Vulnerabilities in Modern Cloud-Native Applications
-
What to Pay Attention to as Automation Upends the Developer Experience
-
Front-End: Cache Strategies You Should Know
-
A Data-Driven Approach to Application Modernization
Comments