static/js/csv.js
/**
 * Sort the rows in a HTML Table
 *
 * @param Table The Table DOM object
 * @param col   The zero-based column number by which to sort
 * @param dir   Optional. The sort direction; pass 1 for asc; -1 for desc
 * @returns void
 */
Sort the rows in a HTML Table
@param Table The Table DOM object
@param col   The zero-based column number by which to sort
@param dir   Optional. The sort direction; pass 1 for asc; -1 for desc
@returns void
Sort the rows in a HTML Table @param Table The Table DOM object @param col The zero - based column number by which to sort @param dir Optional . The sort direction ; pass 1 for asc ; - 1 for desc @returns void
function sortTable(Table, col, dir) {
    var sortClass, i;
    sortTable.sortCol = -1;
    sortClass = Table.className.match(/js-sort-\d+/);
    if (null != sortClass) {
        sortTable.sortCol = sortClass[0].replace(/js-sort-/, '');
        Table.className = Table.className.replace(new RegExp(' ?' + sortClass[0] + '\\b'), '');
    }
    if ('undefined' === typeof col) {
        col = sortTable.sortCol;
    }
    if ('undefined' !== typeof dir) {
        sortTable.sortDir = dir == -1 || dir == 'desc' ? -1 : 1;
    } else {
        sortClass = Table.className.match(/js-sort-(a|de)sc/);
        if (null != sortClass && sortTable.sortCol == col) {
            sortTable.sortDir = 'js-sort-asc' == sortClass[0] ? -1 : 1;
        } else {
            sortTable.sortDir = 1;
        }
    }
    Table.className = Table.className.replace(/ ?js-sort-(a|de)sc/g, '');
    Table.className += ' js-sort-' + col;
    sortTable.sortCol = col;
    Table.className += ' js-sort-' + (sortTable.sortDir == -1 ? 'desc' : 'asc');
    if (col < Table.tHead.rows[Table.tHead.rows.length - 1].cells.length) {
        sortClass = Table.tHead.rows[Table.tHead.rows.length - 1].cells[col].className.match(/js-sort-[-\w]+/);
    }
    for (i = 0; i < Table.tHead.rows[Table.tHead.rows.length - 1].cells.length; i++) {
        if (col == Table.tHead.rows[Table.tHead.rows.length - 1].cells[i].getAttribute('data-js-sort-colNum')) {
            sortClass = Table.tHead.rows[Table.tHead.rows.length - 1].cells[i].className.match(/js-sort-[-\w]+/);
        }
    }
    if (null != sortClass) {
        sortTable.sortFunc = sortClass[0].replace(/js-sort-/, '');
    } else {
        sortTable.sortFunc = 'string';
    }
    Table.querySelectorAll('.js-sort-active').forEach(function(Node){
        Node.className = Node.className.replace(/ ?js-sort-active\b/, '');
    });
    Table.querySelectorAll('[data-js-sort-colNum="' + col + '"]:not(:empty)').forEach(function(Node) {
        Node.className += ' js-sort-active';
    });
    var rows = [],
        TBody = Table.tBodies[0];
    for (i = 0; i < TBody.rows.length; i++) {
        rows[i] = TBody.rows[i];
    }
    rows.sort(sortTable.compareRow);
    while (TBody.firstChild) {
        TBody.removeChild(TBody.firstChild);
    }
    for (i = 0; i < rows.length; i++) {
        TBody.appendChild(rows[i]);
    }
}
function sortTable ( Table , col , dir ) { var sortClass , i ; sortTable . sortCol = - 1 ; sortClass = Table . className . match ( / js-sort-\d+ / ) ; if ( null != sortClass ) { sortTable . sortCol = sortClass [ 0 ] . replace ( / js-sort- / , '' ) ; Table . className = Table . className . replace ( new RegExp ( ' ?' + sortClass [ 0 ] + '\\b' ) , '' ) ; } if ( 'undefined' === typeof col ) { col = sortTable . sortCol ; } if ( 'undefined' !== typeof dir ) { sortTable . sortDir = dir == - 1 || dir == 'desc' ? - 1 : 1 ; } else { sortClass = Table . className . match ( / js-sort-(a|de)sc / ) ; if ( null != sortClass && sortTable . sortCol == col ) { sortTable . sortDir = 'js-sort-asc' == sortClass [ 0 ] ? - 1 : 1 ; } else { sortTable . sortDir = 1 ; } } Table . className = Table . className . replace ( /  ?js-sort-(a|de)sc / g , '' ) ; Table . className += ' js-sort-' + col ; sortTable . sortCol = col ; Table . className += ' js-sort-' + ( sortTable . sortDir == - 1 ? 'desc' : 'asc' ) ; if ( col < Table . tHead . rows [ Table . tHead . rows . length - 1 ] . cells . length ) { sortClass = Table . tHead . rows [ Table . tHead . rows . length - 1 ] . cells [ col ] . className . match ( / js-sort-[-\w]+ / ) ; } for ( i = 0 ; i < Table . tHead . rows [ Table . tHead . rows . length - 1 ] . cells . length ; i ++ ) { if ( col == Table . tHead . rows [ Table . tHead . rows . length - 1 ] . cells [ i ] . getAttribute ( 'data-js-sort-colNum' ) ) { sortClass = Table . tHead . rows [ Table . tHead . rows . length - 1 ] . cells [ i ] . className . match ( / js-sort-[-\w]+ / ) ; } } if ( null != sortClass ) { sortTable . sortFunc = sortClass [ 0 ] . replace ( / js-sort- / , '' ) ; } else { sortTable . sortFunc = 'string' ; } Table . querySelectorAll ( '.js-sort-active' ) . forEach ( function ( Node ) { Node . className = Node . className . replace ( /  ?js-sort-active\b / , '' ) ; } ) ; Table . querySelectorAll ( '[data-js-sort-colNum="' + col + '"]:not(:empty)' ) . forEach ( function ( Node ) { Node . className += ' js-sort-active' ; } ) ; var rows = [ ] , TBody = Table . tBodies [ 0 ] ; for ( i = 0 ; i < TBody . rows . length ; i ++ ) { rows [ i ] = TBody . rows [ i ] ; } rows . sort ( sortTable . compareRow ) ; while ( TBody . firstChild ) { TBody . removeChild ( TBody . firstChild ) ; } for ( i = 0 ; i < rows . length ; i ++ ) { TBody . appendChild ( rows [ i ] ) ; } }
Sort the rows in a HTML Table
 @param Table The Table DOM object
 @param col   The zero-based column number by which to sort
 @param dir   Optional.
Sort the rows in a HTML Table @param Table The Table DOM object @param col The zero - based column number by which to sort @param dir Optional .
// get previous sort column // If sort column was not passed, use previous // Accept -1 or 'desc' for descending.  All else is ascending // sort direction was not passed, use opposite of previous // update sort column // update sort direction // get sort type // Improved support for colspan'd headers // Set the headers for the active column to have the decorative class // sort!