Skip to content Skip to sidebar Skip to footer

Jquery Sortcolumns Plugin: How To Sort Correctly With Rowspan

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, how

Solution 1:

Conditions for the code to work:

  • Columns containing tds with rowspan must all be on the left of the table
  • All the tds in these columns must have a rowspan, even if it's 1
  • The groups of rows to sort are made with the rightmost of these columns (but it can easily be changed)

jsFiddle: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() {
            returnthis.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:

  • Finding all tds with rowspan
  • Positions of these tds are saved, including left offset
  • These tds are filtered by their original offset to work only with the rightmost ones
  • trs related to each kept td are sorted using the wanted column
  • All tds with rowspan are finally moved back to their original position if necessary

About 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.

Solution 2:

Considering question 1, try this code:

var inverse = false;
var curRowSpan = 0;
var curIndex = 0;
var doRowSpan = false;
functionsortColumn(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 rowSpanif (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 continuecontinue;
        }

        if(!doRowSpan) curIndex = index - (curRowSpan?1:0);
        else curIndex = index;

        if(jQuery(this).index() == curIndex) {
            // we are at the sorting columnif(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(){
            returnthis.parentNode;
        });
        inverse = !inverse;
    }
    functionconvertToNum(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.

Post a Comment for "Jquery Sortcolumns Plugin: How To Sort Correctly With Rowspan"