X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dmembres/cotisations/gestion/rappel_supprimer.php?a=blobdiff_plain;f=resources%2Fjquery%2Fjquery.tablesorter.js;h=405c600b767ab7944a1810ad5cadba03e70b5826;hb=7636bea2bf3ccc33389a97d968bdda64036f59c0;hp=8320304ff1515bccf938aa9b8f4634eb1f1549f9;hpb=88a586a12cf9e4674b20ebc060aca2cd9fdb7054;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/jquery/jquery.tablesorter.js b/resources/jquery/jquery.tablesorter.js index 8320304ff1..405c600b76 100644 --- a/resources/jquery/jquery.tablesorter.js +++ b/resources/jquery/jquery.tablesorter.js @@ -98,7 +98,9 @@ // like charAt, toLowerCase and split are expected. return String( data ); } else { - if ( node.tagName.toLowerCase() === 'img' ) { + if ( !node ) { + return $node.text(); + } else if ( node.tagName.toLowerCase() === 'img' ) { return $node.attr( 'alt' ) || ''; // handle undefined alt } else { return $.map( $.makeArray( node.childNodes ), function( elem ) { @@ -113,14 +115,6 @@ } } - function getTextFromRowAndCellIndex( rows, rowIndex, cellIndex ) { - if ( rows[rowIndex] && rows[rowIndex].cells[cellIndex] ) { - return $.trim( getElementSortKey( rows[rowIndex].cells[cellIndex] ) ); - } else { - return ''; - } - } - function detectParserForColumn( table, rows, cellIndex ) { var l = parsers.length, nodeValue, @@ -130,8 +124,13 @@ concurrent = 0, needed = ( rows.length > 4 ) ? 5 : rows.length; - while( i < l ) { - nodeValue = getTextFromRowAndCellIndex( rows, rowIndex, cellIndex ); + while ( i < l ) { + if ( rows[rowIndex] && rows[rowIndex].cells[cellIndex] ) { + nodeValue = $.trim( getElementSortKey( rows[rowIndex].cells[cellIndex] ) ); + } else { + nodeValue = ''; + } + if ( nodeValue !== '') { if ( parsers[i].is( nodeValue, table ) ) { concurrent++; @@ -326,6 +325,40 @@ } + /** + * Sets the sort count of the columns that are not affected by the sorting to have them sorted + * in default (ascending) order when their header cell is clicked the next time. + * + * @param {jQuery} $headers + * @param {Number[][]} sortList + * @param {Number[][]} headerToColumns + */ + function setHeadersOrder( $headers, sortList, headerToColumns ) { + // Loop through all headers to retrieve the indices of the columns the header spans across: + $.each( headerToColumns, function( headerIndex, columns ) { + + $.each( columns, function( i, columnIndex ) { + var header = $headers[headerIndex]; + + if ( !isValueInArray( columnIndex, sortList ) ) { + // Column shall not be sorted: Reset header count and order. + header.order = 0; + header.count = 0; + } else { + // Column shall be sorted: Apply designated count and order. + $.each( sortList, function( j, sortColumn ) { + if ( sortColumn[0] === i ) { + header.order = sortColumn[1]; + header.count = sortColumn[1] + 1; + return false; + } + } ); + } + } ); + + } ); + } + function isValueInArray( v, a ) { var l = a.length; for ( var i = 0; i < l; i++ ) { @@ -425,31 +458,93 @@ ts.dateRegex[0] = new RegExp( /^\s*(\d{1,2})[\,\.\-\/'\s]{1,2}(\d{1,2})[\,\.\-\/'\s]{1,2}(\d{2,4})\s*?/i); // Written Month name, dmy - ts.dateRegex[1] = new RegExp( '^\\s*(\\d{1,2})[\\,\\.\\-\\/\'\\s]*(' + regex + ')' + '[\\,\\.\\-\\/\'\\s]*(\\d{2,4})\\s*$', 'i' ); + ts.dateRegex[1] = new RegExp( '^\\s*(\\d{1,2})[\\,\\.\\-\\/\'\\s]+(' + regex + ')' + '[\\,\\.\\-\\/\'\\s]+(\\d{2,4})\\s*$', 'i' ); // Written Month name, mdy - ts.dateRegex[2] = new RegExp( '^\\s*(' + regex + ')' + '[\\,\\.\\-\\/\'\\s]*(\\d{1,2})[\\,\\.\\-\\/\'\\s]*(\\d{2,4})\\s*$', 'i' ); + ts.dateRegex[2] = new RegExp( '^\\s*(' + regex + ')' + '[\\,\\.\\-\\/\'\\s]+(\\d{1,2})[\\,\\.\\-\\/\'\\s]+(\\d{2,4})\\s*$', 'i' ); } + /** + * Replace all rowspanned cells in the body with clones in each row, so sorting + * need not worry about them. + * + * @param $table jQuery object for a + */ function explodeRowspans( $table ) { - // Split multi row cells into multiple cells with the same content - $table.find( '> tbody > tr > [rowspan]' ).each(function () { - var rowSpan = this.rowSpan; - this.rowSpan = 1; - var cell = $( this ); - var next = cell.parent().nextAll(); + var rowspanCells = $table.find( '> tbody > tr > [rowspan]' ).get(); + + // Short circuit + if ( !rowspanCells.length ) { + return; + } + + // First, we need to make a property like cellIndex but taking into + // account colspans. We also cache the rowIndex to avoid having to take + // cell.parentNode.rowIndex in the sorting function below. + $table.find( '> tbody > tr' ).each( function () { + var col = 0; + var l = this.cells.length; + for ( var i = 0; i < l; i++ ) { + this.cells[i].realCellIndex = col; + this.cells[i].realRowIndex = this.rowIndex; + col += this.cells[i].colSpan; + } + } ); + + // Split multi row cells into multiple cells with the same content. + // Sort by column then row index to avoid problems with odd table structures. + // Re-sort whenever a rowspanned cell's realCellIndex is changed, because it + // might change the sort order. + function resortCells() { + rowspanCells = rowspanCells.sort( function ( a, b ) { + var ret = a.realCellIndex - b.realCellIndex; + if ( !ret ) { + ret = a.realRowIndex - b.realRowIndex; + } + return ret; + } ); + $.each( rowspanCells, function () { + this.needResort = false; + } ); + } + resortCells(); + + var spanningRealCellIndex, rowSpan, colSpan; + function filterfunc() { + return this.realCellIndex >= spanningRealCellIndex; + } + + function fixTdCellIndex() { + this.realCellIndex += colSpan; + if ( this.rowSpan > 1 ) { + this.needResort = true; + } + } + + while ( rowspanCells.length ) { + if ( rowspanCells[0].needResort ) { + resortCells(); + } + + var cell = rowspanCells.shift(); + rowSpan = cell.rowSpan; + colSpan = cell.colSpan; + spanningRealCellIndex = cell.realCellIndex; + cell.rowSpan = 1; + var $nextRows = $( cell ).parent().nextAll(); for ( var i = 0; i < rowSpan - 1; i++ ) { - var td = next.eq( i ).children( 'td' ); - if ( !td.length ) { - next.eq( i ).append( cell.clone() ); - } else if ( this.cellIndex === 0 ) { - td.eq( this.cellIndex ).before( cell.clone() ); + var $tds = $( $nextRows[i].cells ).filter( filterfunc ); + var $clone = $( cell ).clone(); + $clone[0].realCellIndex = spanningRealCellIndex; + if ( $tds.length ) { + $tds.each( fixTdCellIndex ); + $tds.first().before( $clone ); } else { - td.eq( this.cellIndex - 1 ).after( cell.clone() ); + $nextRows.eq( i ).append( $clone ); } } - }); + } } function buildCollationTable() { @@ -511,7 +606,7 @@ $.each( sortObjects, function( i, sortObject ) { $.each ( sortObject, function( columnIndex, order ) { var orderIndex = ( order === 'desc' ) ? 1 : 0; - sortList.push( [columnIndex, orderIndex] ); + sortList.push( [parseInt( columnIndex, 10 ), orderIndex] ); } ); } ); return sortList; @@ -697,6 +792,9 @@ } } + // Reset order/counts of cells not affected by sorting + setHeadersOrder( $headers, config.sortList, headerToColumns ); + // Set CSS for headers setHeadersCss( $table[0], $headers, config.sortList, sortCSS, sortMsg, columnToHeader ); appendToTable( @@ -737,6 +835,10 @@ sortList = convertSortList( sortList ); } + // Set each column's sort count to be able to determine the correct sort + // order when clicking on a header cell the next time + setHeadersOrder( $headers, sortList, headerToColumns ); + // re-build the cache for the tbody cells cache = buildCache( table );