I currently use the sort function to sort my div elements based on the count value. Here\'s how it\'s being done now: (I\'m not sure if it\'s an efficient method or not..)>
Only the sort comparator function needs to change. I'm sure there are plugins available to do this, and you might want to take a look at them, but implementing what you want is fairly trivial. The sortDescending
method gets two divs each time, and comparison must follow the criteria you've specified:
Here's the ugly straightforward non-optimized version:
function sortDescending(a, b) {
if(getCount(a) < getCount(b)) {
return -1;
}
else if(getCount(a) > getCount(b)) {
return 1;
}
else if(getTimestamp(a) < getTimestamp(b)) {
return -1;
}
else if(getTimestamp(a) > getTimestamp(b) {
return 1;
}
else {
return 0;
}
}
If you see the if-else
structure, it may seem obvious that you can genericize this approach to be able to handle any type of custom ordering. So here's a jab at a sortBy
method that takes in a number callback functions, where each callback defines one sorting criteria.
function sortBy() {
var callbacks = arguments;
return function(a, b) {
for(var i = 0; i < callbacks; i++) {
var value = callbacks[i](a, b);
if(value != 0) {
return value;
}
}
return 0;
};
}
Then pass all criteria's as callbacks to this sortBy
function. Here's a rough example for your code:
function compareCount(a, b) {
return getCount(a) - getCount(b);
}
function compareTimestamp(a, b) {
return getTimestamp(a) - getTimestamp(b);
}
$("selector").sort(sortBy(compareCount, compareTimestamp));
And while we are at it, let's also make a jQuery plugin out of this. It will have a nice and easy interface:
$("parent selector").sortBy("child selector 1", "child selector 2", ...);
The idea is to pass a jQuery selector that will select a node whose text will determine the value to sort by. We will give integers a higher priority and first try to sort numerically if both values are so, otherwise do a regular comparison.
jQuery.fn.sortBy = function() {
var selectors = arguments;
this.sort(function(a, b) {
// run through each selector, and return first non-zero match
for(var i = 0; i < selectors.length; i++) {
var selector = selectors[i];
var first = $(selector, a).text();
var second = $(selector, b).text();
var isNumeric = Number(first) && Number(second);
if(isNumeric) {
var diff = first - second;
if(diff != 0) {
return diff;
}
}
else if(first != second) {
return first < second ? -1 : 1;
}
}
return 0;
});
this.appendTo(this.parent());
return this;
};
Use as
$('#list .list_item').sortBy('.count', '.timestmap');
See an example of the plugin here.
Btw, none of this will actually sort the elements in the document itself. See this question for how to do that.