tablesorter/js/widgets/widget-sort2Hash.js
Rob Garrison c1c55c5688 v2.28.15
2017-07-04 12:56:45 -05:00

259 lines
8.8 KiB
JavaScript

/*! Widget: sort2Hash (BETA) - updated 7/4/2017 (v2.28.15) */
/* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
;( function( $ ) {
'use strict';
var ts = $.tablesorter || {},
s2h = ts.sort2Hash = {
init : function( c, wo ) {
var filter, temp, page, size,
table = c.table,
pager = c.pager,
hasSaveSort = ts.hasWidget( table, 'saveSort' ),
sort = s2h.decodeHash( c, wo, 'sort' );
if ( ( sort && !hasSaveSort ) || ( sort && hasSaveSort && wo.sort2Hash_overrideSaveSort ) ) {
s2h.convertString2Sort( c, wo, sort );
}
if ( ts.hasWidget( c.table, 'pager' ) ) {
temp = parseInt( s2h.decodeHash( c, wo, 'page' ), 10 );
page = pager.page = ( temp < 0 ? 0 : ( temp > pager.totalPages ? pager.totalPages - 1 : temp ) );
size = pager.size = parseInt( s2h.decodeHash( c, wo, 'size' ), 10 );
}
if ( ts.hasWidget( table, 'filter' ) ) {
filter = s2h.decodeHash( c, wo, 'filter' );
if ( filter ) {
filter = filter.split( wo.sort2Hash_separator );
c.$table.one( 'tablesorter-ready', function() {
setTimeout(function(){
c.$table.one( 'filterEnd', function() {
$(this).triggerHandler( 'pageAndSize', [ page, size ] );
});
// use the newest filter comparison code
if ( ts.filter.equalFilters ) {
temp = ts.filter.equalFilters( c, c.lastSearch, filter );
} else {
// quick n' dirty comparison... it will miss filter changes of
// the same value in a different column, see #1363
temp = ( c.lastSearch || [] ).join( '' ) !== ( filter || [] ).join( '' );
}
// don't set filters if they haven't changed
if ( !temp ) {
$.tablesorter.setFilters( table, filter, true );
}
}, 100 );
});
}
}
if ( !filter ) {
c.$table.one( 'tablesorter-ready', function() {
c.$table.triggerHandler( 'pageAndSize', [ page, size ] );
});
}
c.$table.on( 'sortEnd.sort2hash filterEnd.sort2hash pagerComplete.sort2Hash', function() {
if ( this.hasInitialized ) {
s2h.setHash( this.config, this.config.widgetOptions );
}
});
},
getTableId : function( c, wo ) {
// option > table id > table index on page
return wo.sort2Hash_tableId ||
c.table.id ||
'table' + $( 'table' ).index( c.$table );
},
regexEscape : function( v ) {
return v.replace( /([\.\^\$\*\+\-\?\(\)\[\]\{\}\\\|])/g, '\\$1');
},
// convert 'first%20name,asc,last%20name,desc' into [[0,0], [1,1]]
convertString2Sort : function( c, wo, sortHash ) {
var regex, column, direction, temp, index, $cell,
arry = sortHash.split( wo.sort2Hash_separator ),
indx = 0,
len = arry.length,
sort = [];
while ( indx < len ) {
// column index or text
column = arry[ indx++ ];
temp = parseInt( column, 10 );
// ignore wo.sort2Hash_useHeaderText setting &
// just see if column contains a number
if ( isNaN( temp ) || temp > c.columns ) {
regex = new RegExp( '(' + s2h.regexEscape( column ) + ')', 'i' );
for ( index = 0; index < c.columns; index++ ) {
$cell = c.$headerIndexed[ index ];
if ( regex.test( $cell.attr( wo.sort2Hash_headerTextAttr ) ) ) {
column = index;
index = c.columns;
}
}
}
direction = arry[ indx++ ];
// ignore unpaired values
if ( typeof column !== 'undefined' && typeof direction !== 'undefined' ) {
// convert text to 0, 1
if ( isNaN( direction ) ) {
// default to ascending sort
direction = direction.indexOf( wo.sort2Hash_directionText[ 1 ] ) > -1 ? 1 : 0;
}
sort.push( [ column, direction ] );
}
}
if ( sort.length ) {
c.sortList = sort;
}
},
// convert [[0,0],[1,1]] to 'first%20name,asc,last%20name,desc'
convertSort2String : function( c, wo ) {
var index, txt, column, direction,
sort = [],
arry = c.sortList || [],
len = arry.length;
for ( index = 0; index < len; index++ ) {
column = arry[ index ][ 0 ];
txt = $.trim( c.$headerIndexed[ column ].attr( wo.sort2Hash_headerTextAttr ) );
sort.push( txt !== '' ? encodeURIComponent( txt ) : column );
direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ];
sort.push( direction );
}
// join with separator
return sort.join( wo.sort2Hash_separator );
},
convertFilter2String : function( c, wo ) {
var index, txt, column, direction,
sort = [],
arry = c.sortList || [],
len = arry.length;
for ( index = 0; index < len; index++ ) {
column = arry[ index ][ 0 ];
txt = $.trim( c.$headerIndexed[ column ].attr( wo.sort2Hash_headerTextAttr ) );
column = typeof txt !== 'undefined' ? encodeURIComponent( txt ) : column;
sort.push( column );
direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ];
sort.push( direction );
}
// join with separator
return sort.join( wo.sort2Hash_separator );
},
// Get URL Parameters (getParam)
// modified from http://www.netlobo.com/url_query_string_javascript.html
getParam : function ( name, hash, returnRegex ) {
if ( !hash ) { hash = window.location.hash; }
var regex = new RegExp( '[\\?&]' + s2h.regexEscape( name ) + '=([^&#]*)' ),
match = regex.exec( hash );
if ( returnRegex ) { return regex; }
return match === null ? '' : decodeURIComponent( match[ 1 ] );
},
// remove parameter from hash
removeParam : function( name, hash ) {
if ( !hash ) { hash = window.location.hash; }
var index,
regex = s2h.getParam( name, hash, true ),
result = [],
parts = hash.split( '&' ),
len = parts.length;
for ( index = 0; index < len; index++ ) {
// regex expects a leading '&'...
if ( !regex.test( '&' + parts[ index ] ) ) {
result.push( parts[ index ] );
}
}
return result.length ? result.join( '&' ) : '';
},
encodeHash : function( c, wo, component, value, rawValue ) {
var result = false,
tableId = s2h.getTableId( c, wo );
if ( typeof wo.sort2Hash_encodeHash === 'function' ) {
result = wo.sort2Hash_encodeHash( c, tableId, component, value, rawValue || value );
}
if ( result === false ) {
result = '&' + component + '[' + tableId + ']=' + value;
}
return result;
},
decodeHash : function( c, wo, component ) {
var result = false,
tableId = s2h.getTableId( c, wo );
if ( typeof wo.sort2Hash_decodeHash === 'function' ) {
// return a string
result = wo.sort2Hash_decodeHash( c, tableId, component );
}
if ( result === false ) {
result = s2h.getParam( component + '[' + tableId + ']' );
}
return result || '';
},
cleanHash : function( c, wo, component, hash ) {
var result = false,
tableId = s2h.getTableId( c, wo );
if ( typeof wo.sort2Hash_cleanHash === 'function' ) {
// can return an array or string
result = wo.sort2Hash_cleanHash( c, tableId, component, hash );
}
if ( result === false ) {
// parameter example: 'sort[table0]=0,0'
result = s2h.removeParam( component + '[' + tableId + ']', hash );
}
return result || '';
},
setHash : function( c, wo ) {
var str = '',
hash = window.location.hash,
hasPager = ts.hasWidget( c.table, 'pager' ),
hasFilter = ts.hasWidget( c.table, 'filter' ),
sortList = s2h.convertSort2String( c, wo ),
filters = ( hasFilter && c.lastSearch.join('') !== '' ? c.lastSearch : [] ),
filtersStr = encodeURIComponent( filters.join( c.widgetOptions.sort2Hash_separator ) ),
components = {
'sort' : sortList ? s2h.encodeHash( c, wo, 'sort', sortList, c.sortList ) : '',
'page' : hasPager ? s2h.encodeHash( c, wo, 'page', c.pager.page + 1 ) : '',
'size' : hasPager ? s2h.encodeHash( c, wo, 'size', c.pager.size ) : '',
'filter' : filtersStr ? s2h.encodeHash( c, wo, 'filter', filtersStr, filters ) : ''
};
// remove old hash
$.each( components, function( component, value ) {
hash = s2h.cleanHash( c, wo, component, hash );
str += value;
});
// add updated hash
window.location.hash = ( ( window.location.hash || '' ).replace( '#', '' ).length ? hash : wo.sort2Hash_hash ) + str;
}
};
ts.addWidget({
id: 'sort2Hash',
priority: 60, // after saveSort & pager
options: {
sort2Hash_hash : '#', // hash prefix
sort2Hash_separator : '-', // don't '#' or '=' here
sort2Hash_headerTextAttr : 'data-header', // data attribute containing alternate header text
sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
sort2Hash_overrideSaveSort : false, // if true, override saveSort widget if saved sort available
// this option > table ID > table index on page
sort2Hash_tableId : null,
// custom hash processing functions
sort2Hash_encodeHash : null,
sort2Hash_decodeHash : null,
sort2Hash_cleanHash : null
},
init: function(table, thisWidget, c, wo) {
s2h.init( c, wo );
},
remove: function(table, c) {
c.$table.off( '.sort2hash' );
}
});
})(jQuery);