JQuery_ Novice to Ninja - Earle Castledine [121]
We’ll try to build a reusable list-sorting widget. We’ll call it SORTER, and we’d call SORTER.sort(list) to sort a list in ascending order, and SORTER.sort(list, 'desc') to sort in descending order. We’ll assume that the selector passed in will match ordered or unordered lists, but let’s see if we can make that happen:
chapter_08/02_sorting_lists/script.js (excerpt)
var SORTER = {};
SORTER.sort = function(which, dir) {
SORTER.dir = (dir == "desc") ? -1 : 1;
$(which).each(function() {
// Find the list items and sort them
var sorted = $(this).find("> li").sort(function(a, b) {
return $(a).text().toLowerCase() > $(b).text().toLowerCase() ?
SORTER.dir : -SORTER.dir;
});
$(this).append(sorted);
});
};
That code is deceptively short, because it happens to be doing a lot! First up, we check to see if desc was passed in as the dir parameter, and set the SORTER.dir variable accordingly. All we need to do is grab all of the first-level children list elements and give them a sort. We only want the first-level items; if we grabbed further levels, they’d be sorted and dragged up to the parent level. Because calling sort reverts our selections to raw JavaScript, we need to rewrap them in the $() to be able to call the jQuery text method and compare their values. We also convert the values to lowercase—which makes the sorting case-insensitive.
Note: The sort Function
The sort function is plain old JavaScript: it sorts an array based on the results of the function you pass to it. sort will go over the contents of the array and pass them to your function in pairs. If your function returns 1, sort will swap the items and place the second one first. If your function returns -1, JavaScript will put the first item first. Finally, if your function returns 0, sort will consider that both items are equal and no sorting will take place.
We’re doing a little magic to let us use the same function for sorting in ascending and descending order: we’ve set our SORTER.dir variable to -1 or 1, depending on the direction. Then in the sort comparison function, we do a further calculation: if a is less than b, we return -SORTER.dir. If the direction comes in as -1, we process it as -(-1), which is 1—so if we’re trying to sort descending, the return values are swapped.
Once we’ve sorted the items, we can reinsert them into the list in the correct order. Remember, the append function removes the element first—so it removes the item and appends it in the correct position.
To test it out, we’ll add some buttons to our HTML and call SORTER.sort from their click event handlers:
chapter_08/02_sorting_lists/script.js (excerpt)
$('#ascending').click(function() {
SORTER.sort('.sortable');
});
$('#descending').click(function() {
SORTER.sort('.sortable', 'desc');
});
Manipulating Select Box Lists
Although we covered forms in the previous chapter, there’s still time to have a look at certain form elements in the context of lists. Here we’re going to examine select elements, especially those with multiple="multiple" (that is, select boxes which appear as selectable lists of items).
Swapping List Elements
The StarTrackr! client has asked us to improve the admin functionality for assigning celebrities to the A-list. The current functionality consists of two select elements: one contains the A-list celebrities, and the other contains every other celebrity in the system. But the world of popularity is extremely fickle—and an A-lister today can be a nobody tomorrow. So the client wants to be able to easily swap the celebrities between each list. We’ll add a few controls to the interface to let him do just that, as shown in Figure 8.2.
Figure 8.2. List boxes with controls
This is the HTML we’re dealing with, consisting of the two select elements, and a few buttons for performing various