2015-11-02 16:50:31 +00:00
/*! Widget: grouping - updated 11/2/2015 (v2.24.1) */
2015-10-31 15:08:21 +00:00
/ *
* Requires tablesorter v2 . 8 + and jQuery 1.7 +
* by Rob Garrison
* /
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
2015-11-02 07:21:29 +00:00
! function ( a ) { "use strict" ; var b = a . tablesorter , c = b . grouping = { types : { number : function ( a , c , d , e ) { var f , g = c . hasClass ( b . css . sortAsc ) ;
// show range
return e > 1 && "" !== d ? ( f = g ? Math . floor ( parseFloat ( d ) / e ) * e : Math . ceil ( parseFloat ( d ) / e ) * e , f += " - " + ( f + ( e - 1 ) * ( g ? 1 : - 1 ) ) ) : f = parseFloat ( d ) || d , f } , separator : function ( b , c , d , e ) { var f = ( d + "" ) . split ( b . widgetOptions . group _separator ) ;
// return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
return a . trim ( f [ e - 1 ] || "" ) } , text : function ( a , b , c ) { return c } , word : function ( a , b , c , d ) { var e = ( c + " " ) . match ( /\w+/g ) || [ ] ;
// return word && word.length >= num ? word[num - 1] : txt || '';
return e [ d - 1 ] || "" } , letter : function ( a , b , c , d ) { return c ? ( c + " " ) . substring ( 0 , d ) : "" } , date : function ( a , b , d , e , f ) { var g , h , i = a . widgetOptions , j = new Date ( d || "" ) ;
2015-10-31 15:08:21 +00:00
// check for valid date
// check for valid date
2015-11-02 07:21:29 +00:00
return j instanceof Date && isFinite ( j ) ? ( g = j . getFullYear ( ) , h = c . findMonth ( i , j . getMonth ( ) ) , "year" === e ? g : "month" === e ? h : "monthyear" === e ? h + " " + g : "day" === e ? h + " " + j . getDate ( ) : "week" === e ? c . findWeek ( i , j . getDay ( ) ) : "time" === e ? c . findTime ( i , j ) : i . group _dateString ( j , a , b ) ) : i . group _dateInvalid } } ,
2015-10-31 15:08:21 +00:00
// group date type functions to allow using this widget with Globalize
findMonth : function ( a , b ) {
// CLDR returns an object { 1: "Jan", 2: "Feb", 3: "Mar", ..., 12: "Dec" }
return a . group _months [ b + ( "" === ( a . group _months [ 0 ] || "" ) ? 1 : 0 ) ] } , findWeek : function ( b , c ) { if ( a . isArray ( b . group _week ) ) return b . group _week [ c ] ; if ( ! a . isEmptyObject ( b . group _week ) ) {
// CLDR returns { sun: "Sun", mon: "Mon", tue: "Tue", wed: "Wed", thu: "Thu", ... }
2015-11-02 07:21:29 +00:00
var d = [ "sun" , "mon" , "tue" , "wed" , "thu" , "fri" , "sat" ] ; return b . group _week [ d [ c ] ] } } , findTime : function ( a , b ) { var c ,
2015-10-31 15:08:21 +00:00
// CLDR returns { am: "AM", pm: "PM", ... }
2015-11-02 07:21:29 +00:00
d = a . group _time . am && a . group _time . pm , e = b . getHours ( ) , f = e >= 12 ? 1 : 0 , g = a . group _time24Hour && e > 12 ? e - 12 : a . group _time24Hour && 0 === e ? e + 12 : e , h = ( "00" + g ) . slice ( - 2 ) , i = ( "00" + b . getMinutes ( ) ) . slice ( - 2 ) ; return c = a . group _time [ d ? [ "am" , "pm" ] [ f ] : f ] , h + ":" + i + ( a . group _time24Hour ? "" : " " + ( c || "" ) ) } , update : function ( b , d , e ) { if ( ! a . isEmptyObject ( d . cache ) ) { var f = "undefined" != typeof d . sortList [ 0 ] , g = { } , h = a . isArray ( e . group _forceColumn ) && "undefined" != typeof e . group _forceColumn [ 0 ] ? e . group _enforceSort && ! f ? - 1 : e . group _forceColumn [ 0 ] : f ? d . sortList [ 0 ] [ 0 ] : - 1 ; d . $table . find ( "tr.group-hidden" ) . removeClass ( "group-hidden" ) . end ( ) . find ( "tr.group-header" ) . remove ( ) , e . group _collapsible &&
2015-10-31 15:08:21 +00:00
// clear pager saved spacer height (in case the rows are collapsed)
2015-11-02 07:21:29 +00:00
d . $table . data ( "pagerSavedHeight" , 0 ) , h >= 0 && h < d . columns && ! d . $headerIndexed [ h ] . hasClass ( "group-false" ) && ( e . group _collapsedGroup = "" , // save current groups
e . group _collapsedGroups = { } , g . column = h ,
// group class finds 'group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}'
g . groupClass = ( d . $headerIndexed [ h ] . attr ( "class" ) || "" ) . match ( /(group-\w+(-\w+)?)/g ) ,
// grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
g . grouping = g . groupClass ? g . groupClass [ 0 ] . split ( "-" ) : [ "group" , "letter" , 1 ] , // default to letter 1
// save current grouping
g . savedGroup = c . saveCurrentGrouping ( d , e , g ) ,
// find column groups
c . findColumnGroups ( d , e , g ) , c . processHeaders ( d , e , g ) , d . $table . trigger ( e . group _complete ) ) } } , processHeaders : function ( b , c , d ) { var e , f , g , h , i , j , k = b . $table . find ( "tr.group-header" ) , l = k . length ; for ( k . bind ( "selectstart" , ! 1 ) , e = 0 ; l > e ; e ++ ) j = k . eq ( e ) , i = j . nextUntil ( "tr.group-header" ) . filter ( ":visible" ) , ( c . group _count || a . isFunction ( c . group _callback ) ) && ( g = j . find ( ".group-count" ) , g . length && ( c . group _count && g . html ( c . group _count . replace ( /\{num\}/g , i . length ) ) , a . isFunction ( c . group _callback ) && c . group _callback ( j . find ( "td" ) , i , d . column , b . table ) ) ) , c . group _saveGroups && ! a . isEmptyObject ( c . group _collapsedGroups ) && c . group _collapsedGroups [ c . group _collapsedGroup ] . length ? ( h = j . find ( ".group-name" ) . text ( ) . toLowerCase ( ) + j . attr ( "data-group-index" ) , f = a . inArray ( h , c . group _collapsedGroups [ c . group _collapsedGroup ] ) > - 1 , j . toggleClass ( "collapsed" , f ) , i . toggleClass ( "group-hidden" , f ) ) : c . group _collapsed && c . group _collapsible && ( j . addClass ( "collapsed" ) , i . addClass ( "group-hidden" ) ) } , groupHeaderHTML : function ( a , b , c ) { return '<tr class="group-header ' + a . selectorRemove . slice ( 1 ) + '" unselectable="on" ' + ( a . tabIndex ? 'tabindex="0" ' : "" ) + 'data-group-index="' + c . groupIndex ++ + '"><td colspan="' + a . columns + '">' + ( b . group _collapsible ? "<i/>" : "" ) + '<span class="group-name">' + c . currentGroup + '</span><span class="group-count"></span></td></tr>' } , saveCurrentGrouping : function ( a , c , d ) {
// save current grouping
var e , f , g = ! 1 ;
// include direction when saving groups (reversed numbers shows different range values)
// combine column, sort direction & grouping as save key
return c . group _collapsible && c . group _saveGroups && b . storage && ( c . group _collapsedGroups = b . storage ( a . table , "tablesorter-groups" ) || { } , f = "dir" + a . sortList [ 0 ] [ 1 ] , e = c . group _collapsedGroup = "" + a . sortList [ 0 ] [ 0 ] + f + d . grouping . join ( "" ) , c . group _collapsedGroups [ e ] ? g = ! 0 : c . group _collapsedGroups [ e ] = [ ] ) , g } , findColumnGroups : function ( a , d , e ) { var f , g , h , i , j = b . hasWidget ( a . table , "pager" ) ; for ( e . groupIndex = 0 , f = 0 ; f < a . $tbodies . length ; f ++ ) for ( g = a . cache [ f ] . normalized , e . group = "" , // clear grouping across tbodies
h = j ? a . pager . startRow - 1 : 0 , i = j ? a . pager . endRow : g . length ; i > h ; h ++ ) e . rowData = g [ h ] , e . $row = e . rowData [ a . columns ] . $row ,
// fixes #438
e . $row . is ( ":visible" ) && c . types [ e . grouping [ 1 ] ] && c . insertGroupHeader ( a , d , e ) } , insertGroupHeader : function ( b , d , e ) { var f = b . $headerIndexed [ e . column ] , g = e . rowData [ e . column ] , h = /date/ . test ( e . groupClass ) ? e . grouping [ 2 ] : parseInt ( e . grouping [ 2 ] || 1 , 10 ) || 1 ; e . currentGroup = e . rowData ? c . types [ e . grouping [ 1 ] ] ( b , f , g , h , e . group ) : e . currentGroup , e . group !== e . currentGroup && ( e . group = e . currentGroup , a . isFunction ( d . group _formatter ) && ( e . currentGroup = d . group _formatter ( ( e . group || "" ) . toString ( ) , e . column , b . table , b , d ) || e . group ) , e . $row . before ( c . groupHeaderHTML ( b , d , e ) ) , d . group _saveGroups && ! e . savedGroup && d . group _collapsed && d . group _collapsible &&
// all groups start collapsed
d . group _collapsedGroups [ d . group _collapsedGroup ] . push ( e . currentGroup ) ) } , bindEvents : function ( d , e , f ) { f . group _collapsible && ( f . group _collapsedGroups = [ ] ,
2015-10-31 15:08:21 +00:00
// .on() requires jQuery 1.7+
2015-11-02 07:21:29 +00:00
e . $table . on ( "click toggleGroup keyup" , "tr.group-header" , function ( c ) {
2015-10-31 15:08:21 +00:00
// pressing enter will toggle the group
2015-11-02 07:21:29 +00:00
if ( c . stopPropagation ( ) , "keyup" !== c . type || 13 === c . which ) { var g , h , i , j = a ( this ) , k = j . find ( ".group-name" ) . text ( ) . toLowerCase ( ) + j . attr ( "data-group-index" ) ;
2015-10-31 15:08:21 +00:00
// use shift-click to toggle ALL groups
2015-11-02 07:21:29 +00:00
! c . shiftKey || "click" !== c . type && "keyup" !== c . type || j . siblings ( ".group-header" ) . trigger ( "toggleGroup" ) , j . toggleClass ( "collapsed" ) ,
2015-10-31 15:08:21 +00:00
// nextUntil requires jQuery 1.4+
j . nextUntil ( "tr.group-header" ) . toggleClass ( "group-hidden" , j . hasClass ( "collapsed" ) ) ,
// save collapsed groups
2015-11-02 07:21:29 +00:00
f . group _saveGroups && b . storage && ( h = e . $table . find ( ".group-header" ) , g = j . hasClass ( "collapsed" ) , f . group _collapsedGroups [ f . group _collapsedGroup ] || ( f . group _collapsedGroups [ f . group _collapsedGroup ] = [ ] ) , g && f . group _collapsedGroup ? f . group _collapsedGroups [ f . group _collapsedGroup ] . push ( k ) : f . group _collapsedGroup && ( i = a . inArray ( k , f . group _collapsedGroups [ f . group _collapsedGroup ] ) , i > - 1 && f . group _collapsedGroups [ f . group _collapsedGroup ] . splice ( i , 1 ) ) , b . storage ( d , "tablesorter-groups" , f . group _collapsedGroups ) ) } } ) ) , a ( f . group _saveReset ) . on ( "click" , function ( ) { c . clearSavedGroups ( d ) } ) , e . $table . on ( "pagerChange.tsgrouping" , function ( ) { c . update ( d , e , f ) } ) } , clearSavedGroups : function ( a ) { a && b . storage && ( b . storage ( a , "tablesorter-groups" , "" ) , c . update ( a , a . config , a . config . widgetOptions ) ) } } ; b . addWidget ( { id : "group" , priority : 100 , options : { group _collapsible : ! 0 , // make the group header clickable and collapse the rows below it.
2015-10-31 15:08:21 +00:00
group _collapsed : ! 1 , // start with all groups collapsed
group _saveGroups : ! 0 , // remember collapsed groups
group _saveReset : null , // element to clear saved collapsed groups
group _count : " ({num})" , // if not false, the '{num}' string is replaced with the number of rows in the group
group _separator : "-" , // group name separator; used when group-separator-# class is used.
group _formatter : null , // function(txt, column, table, c, wo) { return txt; }
group _callback : null , // function($cell, $rows, column, table){}, callback allowing modification of the group header labels
group _complete : "groupingComplete" , // event triggered on the table when the grouping widget has finished work
// apply the grouping widget only to selected column
group _forceColumn : [ ] , // only the first value is used; set as an array for future expansion
group _enforceSort : ! 0 , // only apply group_forceColumn when a sort is applied to the table
// checkbox parser text used for checked/unchecked values
group _checkbox : [ "checked" , "unchecked" ] ,
// change these default date names based on your language preferences
group _months : [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ] , group _week : [ "Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" ] , group _time : [ "AM" , "PM" ] ,
// use 12 vs 24 hour time
group _time24Hour : ! 1 ,
// group header text added for invalid dates
group _dateInvalid : "Invalid Date" ,
// this function is used when 'group-date' is set to create the date string
// you can just return date, date.toLocaleString(), date.toLocaleDateString() or d.toLocaleTimeString()
// reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Conversion_getter
2015-11-02 07:21:29 +00:00
group _dateString : function ( a ) { return a . toLocaleString ( ) } } , init : function ( a , b , d , e ) { c . bindEvents ( a , d , e ) } , format : function ( a , b , d ) { c . update ( a , b , d ) } , remove : function ( a , b , c ) { b . $table . off ( "click" , "tr.group-header" ) . off ( "pagerChange.tsgrouping" ) . find ( ".group-hidden" ) . removeClass ( "group-hidden" ) . end ( ) . find ( "tr.group-header" ) . remove ( ) } } ) } ( jQuery ) ;