JQuery_ Novice to Ninja - Earle Castledine [111]
Try it out. Drag an item to the trash, and watch it vanish in a cloud of smoke!
jQuery UI sortable
Another great feature of jQuery UI is the sortable behavior. An element that you declare as sortable becomes a droppable target to its children—and the children all become draggable. The result is that you can reorder the children as you see fit. While sortable allows us to order items within a container, it doesn’t actually sort anything: the sorting is up to the user.
This makes it perfect for lists of elements where order needs to be managed. Rather than using the fiddly move up the list or move down the list buttons that we usually see next to lists, we can apply the sortable behavior to them and allow our users to reorder the list in a much more intuitive way.
On the front page of StarTrackr! there are two lists that show the ranking of the week’s top celebrities. One is for the A-list celebrities, and the other for the B-list. This is the perfect opportunity to show our client a cool trick: let’s make the lists reorderable by the users. They can move the celebs up and down the lists, and even swap them if they challenge their A/B list status. When they’re happy with their reordering, they can click the Accept button and the changes will be submitted to the server.
Lists are the primary targets for the sortable behaviour. With a little extra work a div can also take up the challenge. For this example, we’ll use the following markup:
chapter_07/15_sortables/index.html (excerpt)
Like draggable and droppable, establishing an element as sortable is straightforward:
$("#a-list, #b-list").sortable();
There’s a raft of methods, events, and options that are available when an element becomes sortable, and we can combine them to control the interesting moments that occur during the course of the sorting:
chapter_07/15_sortables/script.js (excerpt)
$("#a-list, #b-list").sortable({
connectWith: '.connected',
placeholder: 'ui-state-highlight',
receive: function(event, ui) { adopt(this) },
remove: function(event, ui) { orphan(this) }
}).disableSelection();
We’ve specified two options and two methods to our sortables, and we’ll build on those methods to make our actions a little more user-friendly. A nice touch we can exploit is that accessing this inside the callbacks (as we’ve done above) gives us a reference to the sortable element.
Note: disableSelection
Chained on the end of our sortable instantiation is a nifty action: disableSelection. disableSelection, and its reverse, enableSelection, are two really powerful methods in jQueryUI. Calling disableSelection makes it impossible for users to select text inside the target elements. It can be used to stop text from being selected when users are dragging—or sorting—the element, and prevents users from accidentally highlighting text when they just want to drag an item.
Let’s look at the two methods we’ve assigned as event handlers:
chapter_07/15_sortables/script.js (excerpt)
function adopt(which) {
if ($(which).hasClass('empty')) {
$(which).removeClass('empty').find('.empty').remove();
}
}
function orphan(which) {
console.log(which);
if ($(which).children().length == 0) {
$(which)
.append($('
.addClass('empty');
}
}
These methods allow us to add the text “empty” to a list when its last item is removed, and remove the text as soon as a new item is added. The receive event is fired when a sortable list receives an item from a connected list. We use it to call our custom adopt method, wherein we remove the “empty” text if it’s found.
Removing a child from a sortable fires the remove event, which we use to call our orphan function. This method checks to see if the parent sortable has no children. Should it be empty, we give it a child