/* =============================== | TABLESORT.JS | Copyright, Andy Croxall (mitya@mitya.co.uk) | For documentation and demo see http://mitya.co.uk/scripts/Animated-table-sort-REGEXP-friendly-111 | | USAGE | This script may be used, distributed and modified freely but this header must remain in tact. | For usage info and demo, including info on args and params, see www.mitya.co.uk/scripts =============================== */ jQuery.fn.sortTable = function(params) { /*----------- | STOP right now if anim already in progress -----------*/ if ($(this).find(':animated').length > 0) return; /*----------- | VALIDATE TABLE & PARAMS | - if no col to sort on passed, complain and return | - if table doesn't contain requested col, complain and return | If !sortType or invalid sortType, assume ascii sort -----------*/ var error = null; var complain = null; if (!params.onCol) { error = "No column specified to search on"; complain = true; } else if ($(this).find('td:nth-child('+params.onCol+')').length == 0) { error = "The requested column wasn't found in the table"; complain = true; } if (error) { if (complain) alert(error); return; } if (!params.sortType || params.sortType != 'numeric') params.sortType = 'ascii'; /*----------- | PREP | - declare array to store the contents of each
's content into it | - fix the | 's width/height to its offset width/height so that, when we remove its html, it won't change shape | - clear the | 's content | - clear the | 's content | There is no visual effect in this. But it means each | 's content is now 'animatable', since it's position: absolute. -----------*/ var counter = 0; $(this).find('td').each(function() { if ($(this).is('.sortOnThisCol') || (!params.onCol && !params.keepRelationships)) { var valForSort = !params.child ? $(this).text() : (params.child != 'input' ? $(this).find(params.child).text() : $(this).find(params.child).val()); if (params.regexp) { valForSort = valForSort.match(new RegExp(params.regexp))[!params.regexpIndex ? 0 : params.regexpIndex]; } valuesToSort.push(valForSort); } var thisTDHTMLHolder = document.createElement('div'); with($(thisTDHTMLHolder)) { html($(this).html()); if (params.child && params.child == 'input') html(html().replace(/=0) valuesToSort_tempCopy.push(valuesToSort[u]); valuesToSort = valuesToSort_tempCopy; delete(valuesToSort_tempCopy) } /*----------- | Now, for each: -----------*/ for(var k in valuesToSort) { //establish current | relating to this value of the array var currTD = $($(this).find(tdSelectorText).filter(function() { return ( ( !params.regexp && ( ( params.child && ( ( params.child != 'input' && valuesToSort[k] == $(this).find(params.child).text() ) || params.child == 'input' && valuesToSort[k] == $(this).find(params.child).val() ) ) || ( !params.child && valuesToSort[k] == $(this).children('div').html() ) ) ) || ( params.regexp && $(this).children('div').html().match(new RegExp(params.regexp))[!params.regexpIndex ? 0 : params.regexpIndex] == valuesToSort[k] ) ) && !$(this).hasClass('tableSort_TDRepopulated'); }).get(0)); //give current | a class to mark it as having been used, so we don't get confused with duplicate values currTD.addClass('tableSort_TDRepopulated'); //establish target | for this value and store as a node reference on this | var targetTD = $($(this).find(tdSelectorText).get(k)); currTD.get(0).toTD = targetTD; //if we're sorting on a particular column and maintaining relationships, also give the other | s in rows a node reference //denoting ITS target, so they move with their lead siibling if (params.keepRelationships) { var counter = 0; $(currTD).parent().children('td').each(function() { $(this).get(0).toTD = $(targetTD.parent().children().get(counter)); counter++; }); } //establish current relative positions for the current and target | s and use this to calculate how far each needs to move
var currPos = currTD.position();
var targetPos = targetTD.position();
var moveBy_top = targetPos.top - currPos.top;
//invert values if going backwards/upwards
if (targetPos.top > currPos.top) moveBy_top = Math.abs(moveBy_top);
/*-----------
| ANIMATE
| - work out what to animate on.
| - if !keepRelationships, animate only s in the col we're sorting on (identified by .sortOnThisCol)
| - if keepRelationships, animate all cols but | s that aren't .sortOnThisCol follow lead sibiling with .sortOnThisCol
| - run animation. On callback, update each | with content of | that just moved into it and remove s
| - If noAnim, we'll still run aniamte() but give it a low duration so it appears instant
-----------*/
var animateOn = params.keepRelationships ? currTD.add(currTD.siblings()) : currTD;
var done = 0;
animateOn.children('div').animate({top: moveBy_top}, !params.noAnim ? 500 : 0, null, function() {
if ($(this).parent().is('.sortOnThisCol') || !params.keepRelationships) {
done++;
if (done == valuesToSort.length-1) thiss.tableSort_cleanUp();
}
});
}
};
jQuery.fn.tableSort_cleanUp = function() {
/*-----------
| AFTER ANIM
| - assign each its new content as property of it (DON'T populate it yet - this | may still need to be read by
| other | s' toTD node references
| - once new contents for each | gathered, populate
| - remove some identifier classes and properties
-----------*/
$(this).find('td').each(function() {
if($(this).get(0).toTD) $($(this).get(0).toTD).get(0).newHTML = $(this).children('div').html();
});
$(this).find('td').each(function() { $(this).html($(this).get(0).newHTML); });
$('td.tableSort_TDRepopulated').removeClass('tableSort_TDRepopulated');
$(this).find('.sortOnThisCol').removeClass('sortOnThisCol');
$(this).find('td[newHTML]').attr('newHTML', '');
$(this).find('td[toTD]').attr('toTD', '');
}; | |