1+ /*! tinysort.js
2+ * version: 2.1.1
3+ * author: Ron Valstar (http://www.sjeiti.com/)
4+ * license: MIT/GPL
5+ * build: 2015-01-05
6+ */
7+ ! function ( a , b ) { "use strict" ; function c ( ) { return b } "function" == typeof define && define . amd ? define ( "tinysort" , c ) : a . tinysort = b } ( this , function ( ) { "use strict" ; function a ( a ) { function f ( ) { 0 === arguments . length ? j ( { } ) : d ( arguments , function ( a ) { j ( c ( a ) ? { selector : a } : a ) } ) , q = C . length } function j ( a ) { var b = ! ! a . selector , c = b && ":" === a . selector [ 0 ] , d = e ( a || { } , t ) ; C . push ( e ( { bFind : b , bAttr : ! ( d . attr === i || "" === d . attr ) , bData : d . data !== i , bFilter : c , mFilter : i , fnSort : d . sortFunction , iAsc : "asc" === d . order ? 1 : - 1 } , d ) ) } function m ( ) { d ( a , function ( a , b ) { x ? x !== a . parentNode && ( D = ! 1 ) : x = a . parentNode ; var c = C [ 0 ] , d = c . bFilter , e = c . selector , f = ! e || d && a . matchesSelector ( e ) || e && a . querySelector ( e ) , g = f ? A : B , h = { elm : a , pos : b , posn : g . length } ; z . push ( h ) , g . push ( h ) } ) , w = A . slice ( 0 ) } function s ( ) { A . sort ( u ) } function u ( a , e ) { var f = 0 ; for ( 0 !== r && ( r = 0 ) ; 0 === f && q > r ; ) { var i = C [ r ] , j = i . ignoreDashes ? o : n ; if ( d ( p , function ( a ) { var b = a . prepare ; b && b ( i ) } ) , i . sortFunction ) f = i . sortFunction ( a , e ) ; else if ( "rand" == i . order ) f = Math . random ( ) < .5 ? 1 : - 1 ; else { var k = h , m = b ( a , i ) , s = b ( e , i ) ; if ( ! i . forceStrings ) { var t = c ( m ) ? m && m . match ( j ) : h , u = c ( s ) ? s && s . match ( j ) : h ; if ( t && u ) { var v = m . substr ( 0 , m . length - t [ 0 ] . length ) , w = s . substr ( 0 , s . length - u [ 0 ] . length ) ; v == w && ( k = ! h , m = l ( t [ 0 ] ) , s = l ( u [ 0 ] ) ) } } f = m === g || s === g ? 0 : i . iAsc * ( s > m ? - 1 : m > s ? 1 : 0 ) } d ( p , function ( a ) { var b = a . sort ; b && ( f = b ( i , k , m , s , f ) ) } ) , 0 === f && r ++ } return 0 === f && ( f = a . pos > e . pos ? 1 : - 1 ) , f } function v ( ) { var a = A . length === z . length ; D && a ? ( A . forEach ( function ( a ) { y . appendChild ( a . elm ) } ) , x . appendChild ( y ) ) : ( A . forEach ( function ( a ) { var b = a . elm , c = k . createElement ( "div" ) ; a . ghost = c , b . parentNode . insertBefore ( c , b ) } ) , A . forEach ( function ( a , b ) { var c = w [ b ] . ghost ; c . parentNode . insertBefore ( a . elm , c ) , c . parentNode . removeChild ( c ) } ) ) } c ( a ) && ( a = k . querySelectorAll ( a ) ) , 0 === a . length && console . warn ( "No elements to sort" ) ; var w , x , y = k . createDocumentFragment ( ) , z = [ ] , A = [ ] , B = [ ] , C = [ ] , D = ! 0 ; return f . apply ( i , Array . prototype . slice . call ( arguments , 1 ) ) , m ( ) , s ( ) , v ( ) , A . map ( function ( a ) { return a . elm } ) } function b ( a , b ) { var d , e = a . elm ; return b . selector && ( b . bFilter ? e . matchesSelector ( b . selector ) || ( e = i ) : e = e . querySelector ( b . selector ) ) , b . bAttr ? d = e . getAttribute ( b . attr ) : b . useVal ? d = e . value : b . bData ? d = e . getAttribute ( "data-" + b . data ) : e && ( d = e . textContent ) , c ( d ) && ( b . cases || ( d = d . toLowerCase ( ) ) , d = d . replace ( / \s + / g, " " ) ) , d } function c ( a ) { return "string" == typeof a } function d ( a , b ) { for ( var c , d = a . length , e = d ; e -- ; ) c = d - e - 1 , b ( a [ c ] , c ) } function e ( a , b , c ) { for ( var d in b ) ( c || a [ d ] === g ) && ( a [ d ] = b [ d ] ) ; return a } function f ( a , b , c ) { p . push ( { prepare : a , sort : b , sortBy : c } ) } var g , h = ! 1 , i = null , j = window , k = j . document , l = parseFloat , m = Array . prototype . indexOf , n = / ( - ? \d + \. ? \d * ) $ / g, o = / ( \d + \. ? \d * ) $ / g, p = [ ] , q = 0 , r = 0 , s = "2.1.0" , t = { selector : i , order : "asc" , attr : i , data : i , useVal : h , place : "start" , returns : h , cases : h , forceStrings : h , ignoreDashes : h , sortFunction : i } ; return j . Element && function ( a ) { a . matchesSelector = a . matchesSelector || a . mozMatchesSelector || a . msMatchesSelector || a . oMatchesSelector || a . webkitMatchesSelector || function ( a ) { for ( var b = this , c = ( b . parentNode || b . document ) . querySelectorAll ( a ) , d = - 1 ; c [ ++ d ] && c [ d ] != b ; ) ; return ! ! c [ d ] } } ( Element . prototype ) , e ( f , { indexOf : m , loop : d } ) , e ( a , { plugin : f , version : s , defaults : t } ) } ( ) ) ;
8+
9+ ( function ( $ ) {
10+
11+ var $document = $ ( document ) ,
12+ signClass ,
13+ sortEngine ;
14+
15+ $ . bootstrapSortable = function ( applyLast , sign , customSort ) {
16+
17+ // Check if moment.js is available
18+ var momentJsAvailable = ( typeof moment !== 'undefined' ) ;
19+
20+ // Set class based on sign parameter
21+ signClass = ! sign ? "arrow" : sign ;
22+
23+ // Set sorting algorithm
24+ if ( customSort == 'default' )
25+ customSort = defaultSortEngine ;
26+ sortEngine = customSort || sortEngine || defaultSortEngine ;
27+
28+ // Set attributes needed for sorting
29+ $ ( 'table.sortable' ) . each ( function ( ) {
30+ var $this = $ ( this ) ,
31+ context = lookupSortContext ( $this ) ,
32+ bsSort = context . bsSort ;
33+ applyLast = ( applyLast === true ) ;
34+ $this . find ( 'span.sign' ) . remove ( ) ;
35+
36+ // Add placeholder cells for colspans
37+ $this . find ( 'thead [colspan]' ) . each ( function ( ) {
38+ var colspan = parseFloat ( $ ( this ) . attr ( 'colspan' ) ) ;
39+ for ( var i = 1 ; i < colspan ; i ++ ) {
40+ $ ( this ) . after ( '<th class="colspan-compensate">' ) ;
41+ }
42+ } ) ;
43+
44+ // Add placeholder cells for rowspans
45+ $this . find ( 'thead [rowspan]' ) . each ( function ( ) {
46+ var $cell = $ ( this ) ;
47+ var rowspan = parseFloat ( $cell . attr ( 'rowspan' ) ) ;
48+ for ( var i = 1 ; i < rowspan ; i ++ ) {
49+ var parentRow = $cell . parent ( 'tr' ) ;
50+ var nextRow = parentRow . next ( 'tr' ) ;
51+ var index = parentRow . children ( ) . index ( $cell ) ;
52+ nextRow . children ( ) . eq ( index ) . before ( '<th class="rowspan-compensate">' ) ;
53+ }
54+ } ) ;
55+
56+ // Set indexes to header cells
57+ $this . find ( 'thead tr' ) . each ( function ( rowIndex ) {
58+ $ ( this ) . find ( 'th' ) . each ( function ( columnIndex ) {
59+ var $this = $ ( this ) ;
60+ $this . addClass ( 'nosort' ) . removeClass ( 'up down' ) ;
61+ $this . attr ( 'data-sortcolumn' , columnIndex ) ;
62+ $this . attr ( 'data-sortkey' , columnIndex + '-' + rowIndex ) ;
63+ } ) ;
64+ } ) ;
65+
66+ // Cleanup placeholder cells
67+ $this . find ( 'thead .rowspan-compensate, .colspan-compensate' ) . remove ( ) ;
68+
69+ // Initialize sorting values
70+ $this . find ( 'td' ) . each ( function ( ) {
71+ var $this = $ ( this ) ;
72+ if ( $this . attr ( 'data-dateformat' ) !== undefined && momentJsAvailable ) {
73+ $this . attr ( 'data-value' , moment ( $this . text ( ) , $this . attr ( 'data-dateformat' ) ) . format ( 'YYYY/MM/DD/HH/mm/ss' ) ) ;
74+ }
75+ else {
76+ $this . attr ( 'data-value' ) === undefined && $this . attr ( 'data-value' , $this . text ( ) ) ;
77+ }
78+ } ) ;
79+ $this . find ( 'thead th[data-defaultsort!="disabled"]' ) . each ( function ( index ) {
80+ var $this = $ ( this ) ;
81+ var $sortTable = $this . closest ( 'table.sortable' ) ;
82+ $this . data ( 'sortTable' , $sortTable ) ;
83+ var sortKey = $this . attr ( 'data-sortkey' ) ;
84+ var thisLastSort = applyLast ? context . lastSort : - 1 ;
85+ bsSort [ sortKey ] = applyLast ? bsSort [ sortKey ] : $this . attr ( 'data-defaultsort' ) ;
86+ if ( bsSort [ sortKey ] !== undefined && ( applyLast === ( sortKey === thisLastSort ) ) ) {
87+ bsSort [ sortKey ] = bsSort [ sortKey ] === 'asc' ? 'desc' : 'asc' ;
88+ doSort ( $this , $sortTable ) ;
89+ }
90+ } ) ;
91+ $this . trigger ( 'sorted' ) ;
92+ } ) ;
93+ } ;
94+
95+ // Add click event to table header
96+ $document . on ( 'click' , 'table.sortable thead th[data-defaultsort!="disabled"]' , function ( e ) {
97+ var $this = $ ( this ) , $table = $this . data ( 'sortTable' ) || $this . closest ( 'table.sortable' ) ;
98+ $table . trigger ( 'before-sort' ) ;
99+ doSort ( $this , $table ) ;
100+ $table . trigger ( 'sorted' ) ;
101+ } ) ;
102+
103+ // Look up sorting data appropriate for the specified table (jQuery element).
104+ // This allows multiple tables on one page without collisions.
105+ function lookupSortContext ( $table ) {
106+ var context = $table . data ( "bootstrap-sortable-context" ) ;
107+ if ( context == null ) {
108+ context = { bsSort : [ ] , lastSort : null } ;
109+ $table . data ( "bootstrap-sortable-context" , context ) ;
110+ }
111+ return context ;
112+ }
113+
114+ function defaultSortEngine ( rows , sortingParams ) {
115+ tinysort ( rows , sortingParams ) ;
116+ }
117+
118+ // Sorting mechanism separated
119+ function doSort ( $this , $table ) {
120+ var sortColumn = parseFloat ( $this . attr ( 'data-sortcolumn' ) ) ,
121+ context = lookupSortContext ( $table ) ,
122+ bsSort = context . bsSort ;
123+
124+ var colspan = $this . attr ( 'colspan' ) ;
125+ if ( colspan ) {
126+ var mainSort = Math . min ( colspan - 1 , parseFloat ( $this . data ( 'mainsort' ) ) || 0 ) ;
127+ var rowIndex = parseFloat ( $this . data ( 'sortkey' ) . split ( '-' ) . pop ( ) ) ;
128+
129+ // If there is one more row in header, delve deeper
130+ if ( $table . find ( 'thead tr' ) . length - 1 > rowIndex ) {
131+ doSort ( $table . find ( '[data-sortkey="' + ( sortColumn + mainSort ) + '-' + ( rowIndex + 1 ) + '"]' ) , $table ) ;
132+ return ;
133+ }
134+ // Otherwise, just adjust the sortColumn
135+ sortColumn = sortColumn + mainSort ;
136+ }
137+
138+ var localSignClass = $this . attr ( 'data-defaultsign' ) || signClass ;
139+
140+ // update arrow icon
141+ $table . find ( 'th' ) . each ( function ( ) {
142+ $ ( this ) . removeClass ( 'up' ) . removeClass ( 'down' ) . addClass ( 'nosort' ) ;
143+ } ) ;
144+
145+ if ( $ . browser . mozilla ) {
146+ var moz_arrow = $table . find ( 'div.mozilla' ) ;
147+ if ( moz_arrow !== undefined ) {
148+ moz_arrow . find ( '.sign' ) . remove ( ) ;
149+ moz_arrow . parent ( ) . html ( moz_arrow . html ( ) ) ;
150+ }
151+ $this . wrapInner ( '<div class="mozilla"></div>' ) ;
152+ $this . children ( ) . eq ( 0 ) . append ( '<span class="sign ' + localSignClass + '"></span>' ) ;
153+ }
154+ else {
155+ $table . find ( 'span.sign' ) . remove ( ) ;
156+ $this . append ( '<span class="sign ' + localSignClass + '"></span>' ) ;
157+ }
158+
159+ // sort direction
160+ var sortKey = $this . attr ( 'data-sortkey' ) ;
161+ var initialDirection = $this . attr ( 'data-firstsort' ) !== 'desc' ? 'desc' : 'asc' ;
162+
163+ context . lastSort = sortKey ;
164+ bsSort [ sortKey ] = ( bsSort [ sortKey ] || initialDirection ) === 'asc' ? 'desc' : 'asc' ;
165+ if ( bsSort [ sortKey ] === 'desc' ) {
166+ $this . find ( 'span.sign' ) . addClass ( 'up' ) ;
167+ $this . addClass ( 'up' ) . removeClass ( 'down nosort' ) ;
168+ } else {
169+ $this . addClass ( 'down' ) . removeClass ( 'up nosort' ) ;
170+ }
171+
172+ // sort rows
173+ var rows = $table . children ( 'tbody' ) . children ( 'tr' ) ;
174+ sortEngine ( rows , { selector : 'td:nth-child(' + ( sortColumn + 1 ) + ')' , order : bsSort [ sortKey ] , data : 'value' } ) ;
175+
176+ // add class to sorted column cells
177+ $table . find ( 'td.sorted, th.sorted' ) . removeClass ( 'sorted' ) ;
178+ rows . find ( 'td:eq(' + sortColumn + ')' ) . addClass ( 'sorted' ) ;
179+ $this . addClass ( 'sorted' ) ;
180+ }
181+
182+ // jQuery 1.9 removed this object
183+ if ( ! $ . browser ) {
184+ $ . browser = { chrome : false , mozilla : false , opera : false , msie : false , safari : false } ;
185+ var ua = navigator . userAgent ;
186+ $ . each ( $ . browser , function ( c ) {
187+ $ . browser [ c ] = ( ( new RegExp ( c , 'i' ) . test ( ua ) ) ) ? true : false ;
188+ if ( $ . browser . mozilla && c === 'mozilla' ) { $ . browser . mozilla = ( ( new RegExp ( 'firefox' , 'i' ) . test ( ua ) ) ) ? true : false ; }
189+ if ( $ . browser . chrome && c === 'safari' ) { $ . browser . safari = false ; }
190+ } ) ;
191+ }
192+
193+ // Initialise on DOM ready
194+ $ ( $ . bootstrapSortable ) ;
195+
196+ } ( jQuery ) ) ;
0 commit comments