Following this post jQuery table sort (github link: https://github.com/padolsey/jQuery-Plugins/blob/master/sortElements/jquery.sortElements.js), I am successfully sort columns,
Conditions for the code to work:
tds with rowspan must all be on the left of the tabletds in these columns must have a rowspan, even if it's 1jsFiddle: http://jsfiddle.net/5GrAC/77/
var inverse = false;
function sortColumn(index) {
var trs = $('#resultsTable > tbody > tr'),
nbRowspans = trs.first().children('[rowspan]').length,
offset = trs.first().children('[rowspan]').last().offset().left;
var tds = trs.children('[rowspan]').each(function() {
$(this).data('row', $(this).parent().index());
$(this).data('column', $(this).index());
$(this).data('offset', $(this).offset().left)
}).each(function() {
if($(this).data('offset') != offset)
return;
var rowMin = $(this).data('row'),
rowMax = rowMin + parseInt($(this).attr('rowspan'));
trs.slice(rowMin, rowMax).children().filter(function() {
return $(this).index() == index + $(this).parent().children('[rowspan]').length - nbRowspans;
}).sortElements(function(a, b) {
a = convertToNum($(a).text());
b = convertToNum($(b).text());
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
}, function() {
return this.parentNode;
});
});
var trs = $('#resultsTable > tbody > tr');
tds.each(function() {
if($(this).parent().index() != $(this).data('row'))
$(this).insertBefore(trs.eq($(this).data('row')).children().eq($(this).data('column')));
});
inverse = !inverse;
}
Quick explanations:
tds with rowspantds are saved, including left offsettds are filtered by their original offset to work only with the rightmost onestrs related to each kept td are sorted using the wanted columntds with rowspan are finally moved back to their original position if necessaryAbout question 2, I will only complete bartlaarhoven's answer by saying, the code can also be written like the following:
return (
(isNaN(a) || isNaN(b) ? a > b : +a > +b) ? 1 : -1
) * (inverse ? -1 : 1);
You can easily read that inverse is used to inverse the result.
Considering question 1, try this code:
var inverse = false;
var curRowSpan = 0;
var curIndex = 0;
var doRowSpan = false;
function sortColumn(index){
index = index + 1;
var table = jQuery('#resultsTable');
table.find('td').filter(function() {
var result = false;
// if it is a column before the sorting column, watch the rowSpan
if (curRowSpan == 0 && jQuery(this).index() < index && jQuery(this).attr("rowspan") > 1) {
curRowSpan = jQuery(this).attr("rowspan");
doRowSpan = true;
// we are not in the sorting column so we can safely continue
continue;
}
if(!doRowSpan) curIndex = index - (curRowSpan?1:0);
else curIndex = index;
if(jQuery(this).index() == curIndex) {
// we are at the sorting column
if(curRowSpan > 0) {
curRowSpan--;
}
// set this to false for the following row
doRowSpan = false;
result = true;
}
return result;
}).sortElements(function(a, b){
a = convertToNum($(a).text());
b = convertToNum($(b).text());
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
},function(){
return this.parentNode;
});
inverse = !inverse;
}
function convertToNum(str){
if(isNaN(str)){
var holder = "";
for(i=0; i<str.length; i++){
if(!isNaN(str.charAt(i))){
holder += str.charAt(i);
}
}
return holder;
}else{
return str;
}
}
Considering question 2; let's deduct where it comes from. First of all we would like to check whether a > b, and, as you already saw correctly, we make a difference between string comparison and number comparison.
We would then simply give:
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ? 1 : -1;
This checks whether a > b (either string-wise or number-wise) and then returns 1 on true and -1 on false.
Now we insert the inverse parameter, which should inverse the result. This means that if inverse == true, then 1 becomes -1 and -1 becomes 1. In code, this bold piece of text would replace each occurrence of 1 with inverse ? -1 : 1 and each occurrence of -1 with inverse ? 1 : -1. Which is exactly what is done in the resulting code.
UPDATE: Added doRowSpan in the code because it should not adapt the index if we are in the <tr> that contains the rowspan-td.