jquery-tablesorter 1.17.2 → 1.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +1 -1
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +76 -71
  5. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +1 -1
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +2647 -2576
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +174 -119
  8. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +2487 -2471
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +15 -15
  10. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-iso8601.js +1 -1
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +4 -4
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-range.js +1 -1
  13. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-two-digit-year.js +12 -12
  14. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +4 -4
  15. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +1 -1
  16. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-duration.js +1 -1
  17. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-feet-inch-fraction.js +6 -6
  18. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-file-type.js +22 -22
  19. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +1 -1
  20. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-ignore-articles.js +15 -15
  21. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-image.js +3 -3
  22. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +10 -3
  23. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-metric.js +2 -2
  24. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +3 -3
  25. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-network.js +1 -1
  26. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-roman.js +4 -4
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +122 -121
  28. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +13 -13
  29. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +2 -2
  30. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +324 -324
  31. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columns.js +60 -60
  32. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +219 -219
  33. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-html5.js +360 -361
  34. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-jui.js +666 -666
  35. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-select2.js +124 -124
  36. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +1 -1
  37. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +1448 -1433
  38. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-formatter.js +1 -1
  39. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +213 -213
  40. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js +3 -3
  41. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +271 -216
  42. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +339 -320
  43. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +1057 -1045
  44. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +109 -109
  45. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +114 -115
  46. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +360 -359
  47. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +59 -59
  48. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +818 -806
  49. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +128 -0
  50. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sortTbodies.js +195 -195
  51. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +90 -90
  52. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +257 -257
  53. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +76 -76
  54. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +170 -170
  55. metadata +3 -3
  56. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.quicksearch.js +0 -195
@@ -1,1150 +1,1162 @@
1
- /*! Widget: Pager - updated 5/17/2015 (v2.22.0) */
1
+ /*! Widget: Pager - updated 7/28/2015 (v2.22.4) */
2
2
  /* Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  ;(function($){
7
- "use strict";
8
- var tsp,
7
+ 'use strict';
8
+ var tsp,
9
9
  ts = $.tablesorter;
10
10
 
11
- ts.addWidget({
12
- id: "pager",
13
- priority: 55, // load pager after filter widget
14
- options : {
15
- // output default: '{page}/{totalPages}'
16
- // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
17
- pager_output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
18
-
19
- // apply disabled classname to the pager arrows when the rows at either extreme is visible
20
- pager_updateArrows: true,
21
-
22
- // starting page of the pager (zero based index)
23
- pager_startPage: 0,
24
-
25
- // reset pager after filtering; set to desired page #
26
- // set to false to not change page at filter start
27
- pager_pageReset: 0,
28
-
29
- // Number of visible rows
30
- pager_size: 10,
31
-
32
- // Number of options to include in the pager number selector
33
- pager_maxOptionSize: 20,
11
+ ts.addWidget({
12
+ id: 'pager',
13
+ priority: 55, // load pager after filter widget
14
+ options : {
15
+ // output default: '{page}/{totalPages}'
16
+ // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
17
+ pager_output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
18
+
19
+ // apply disabled classname to the pager arrows when the rows at either extreme is visible
20
+ pager_updateArrows: true,
21
+
22
+ // starting page of the pager (zero based index)
23
+ pager_startPage: 0,
24
+
25
+ // reset pager after filtering; set to desired page #
26
+ // set to false to not change page at filter start
27
+ pager_pageReset: 0,
28
+
29
+ // Number of visible rows
30
+ pager_size: 10,
31
+
32
+ // Number of options to include in the pager number selector
33
+ pager_maxOptionSize: 20,
34
+
35
+ // Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
36
+ pager_savePages: true,
37
+
38
+ // defines custom storage key
39
+ pager_storageKey: 'tablesorter-pager',
40
+
41
+ // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
42
+ // table row set to a height to compensate; default is false
43
+ pager_fixedHeight: false,
44
+
45
+ // count child rows towards the set page size? (set true if it is a visible table row within the pager)
46
+ // if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
47
+ // may distort the table if rowspan or cellspans are included.
48
+ pager_countChildRows: false,
49
+
50
+ // remove rows from the table to speed up the sort of large tables.
51
+ // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
52
+ pager_removeRows: false, // removing rows in larger tables speeds up the sort
53
+
54
+ // use this format: 'http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}'
55
+ // where {page} is replaced by the page number, {size} is replaced by the number of records to show,
56
+ // {sortList:col} adds the sortList to the url into a 'col' array, and {filterList:fcol} adds
57
+ // the filterList to the url into an 'fcol' array.
58
+ // So a sortList = [[2,0],[3,0]] becomes '&col[2]=0&col[3]=0' in the url
59
+ // and a filterList = [[2,Blue],[3,13]] becomes '&fcol[2]=Blue&fcol[3]=13' in the url
60
+ pager_ajaxUrl: null,
61
+
62
+ // modify the url after all processing has been applied
63
+ pager_customAjaxUrl: function(table, url) { return url; },
64
+
65
+ // modify the $.ajax object to allow complete control over your ajax requests
66
+ pager_ajaxObject: {
67
+ dataType: 'json'
68
+ },
69
+
70
+ // set this to false if you want to block ajax loading on init
71
+ pager_processAjaxOnInit: true,
72
+
73
+ // process ajax so that the following information is returned:
74
+ // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
75
+ // example:
76
+ // [
77
+ // 100, // total rows
78
+ // [
79
+ // [ "row1cell1", "row1cell2", ... "row1cellN" ],
80
+ // [ "row2cell1", "row2cell2", ... "row2cellN" ],
81
+ // ...
82
+ // [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
83
+ // ],
84
+ // [ "header1", "header2", ... "headerN" ] // optional
85
+ // ]
86
+ pager_ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
87
+
88
+ // css class names of pager arrows
89
+ pager_css: {
90
+ container : 'tablesorter-pager',
91
+ errorRow : 'tablesorter-errorRow', // error information row (don't include period at beginning)
92
+ disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows 'disabled' on first page)
93
+ },
94
+
95
+ // jQuery selectors
96
+ pager_selectors: {
97
+ container : '.pager', // target the pager markup
98
+ first : '.first', // go to first page arrow
99
+ prev : '.prev', // previous page arrow
100
+ next : '.next', // next page arrow
101
+ last : '.last', // go to last page arrow
102
+ gotoPage : '.gotoPage', // go to page selector - select dropdown that sets the current page
103
+ pageDisplay : '.pagedisplay', // location of where the 'output' is displayed
104
+ pageSize : '.pagesize' // page size selector - select dropdown that sets the 'size' option
105
+ }
106
+ },
107
+ init: function(table){
108
+ tsp.init(table);
109
+ },
110
+ // only update to complete sorter initialization
111
+ format: function(table, c){
112
+ if (!(c.pager && c.pager.initialized)){
113
+ return tsp.initComplete(table, c);
114
+ }
115
+ tsp.moveToPage(table, c.pager, false);
116
+ },
117
+ remove: function(table, c, wo, refreshing){
118
+ tsp.destroyPager(table, c, refreshing);
119
+ }
120
+ });
34
121
 
35
- // Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
36
- pager_savePages: true,
122
+ /* pager widget functions */
123
+ tsp = ts.pager = {
37
124
 
38
- //defines custom storage key
39
- pager_storageKey: 'tablesorter-pager',
125
+ init: function(table) {
126
+ // check if tablesorter has initialized
127
+ if (table.hasInitialized && table.config.pager.initialized) { return; }
128
+ var t,
129
+ c = table.config,
130
+ wo = c.widgetOptions,
131
+ s = wo.pager_selectors,
132
+
133
+ // save pager variables
134
+ p = c.pager = $.extend({
135
+ totalPages: 0,
136
+ filteredRows: 0,
137
+ filteredPages: 0,
138
+ currentFilters: [],
139
+ page: wo.pager_startPage,
140
+ startRow: 0,
141
+ endRow: 0,
142
+ ajaxCounter: 0,
143
+ $size: null,
144
+ last: {},
145
+ // save original pager size
146
+ setSize: wo.pager_size,
147
+ setPage: wo.pager_startPage,
148
+ events: 'filterInit filterStart filterEnd sortEnd disable enable destroy updateComplete ' +
149
+ 'pageSize pageSet pageAndSize pagerUpdate refreshComplete '
150
+ }, c.pager);
151
+
152
+ // pager initializes multiple times before table has completed initialization
153
+ if (p.isInitializing) { return; }
154
+
155
+ p.isInitializing = true;
156
+ if (c.debug) {
157
+ console.log('Pager: Initializing');
158
+ }
40
159
 
41
- // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
42
- // table row set to a height to compensate; default is false
43
- pager_fixedHeight: false,
160
+ p.size = $.data(table, 'pagerLastSize') || wo.pager_size;
161
+ // added in case the pager is reinitialized after being destroyed.
162
+ p.$container = $(s.container).addClass(wo.pager_css.container).show();
163
+ // goto selector
164
+ p.$goto = p.$container.find(s.gotoPage); // goto is a reserved word #657
165
+ // page size selector
166
+ p.$size = p.$container.find(s.pageSize);
167
+ p.totalRows = c.$tbodies.eq(0).children('tr').not( wo.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
168
+ p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
169
+ c.appender = tsp.appender;
170
+ p.initializing = true;
171
+ if (wo.pager_savePages && ts.storage) {
172
+ t = ts.storage(table, wo.pager_storageKey) || {}; // fixes #387
173
+ p.page = ( isNaN(t.page) ? p.page : t.page ) || p.setPage || 0;
174
+ p.size = ( isNaN(t.size) ? p.size : t.size ) || p.setSize || 10;
175
+ $.data(table, 'pagerLastSize', p.size);
176
+ }
44
177
 
45
- // count child rows towards the set page size? (set true if it is a visible table row within the pager)
46
- // if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
47
- // may distort the table if rowspan or cellspans are included.
48
- pager_countChildRows: false,
178
+ // skipped rows
179
+ p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.slice(1) + '|' + c.cssChildRow + ')');
49
180
 
50
- // remove rows from the table to speed up the sort of large tables.
51
- // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
52
- pager_removeRows: false, // removing rows in larger tables speeds up the sort
181
+ // clear initialized flag
182
+ p.initialized = false;
183
+ // before initialization event
184
+ c.$table.trigger('pagerBeforeInitialized', c);
53
185
 
54
- // use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
55
- // where {page} is replaced by the page number, {size} is replaced by the number of records to show,
56
- // {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
57
- // the filterList to the url into an "fcol" array.
58
- // So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
59
- // and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
60
- pager_ajaxUrl: null,
186
+ tsp.enablePager(table, c, false);
61
187
 
62
- // modify the url after all processing has been applied
63
- pager_customAjaxUrl: function(table, url) { return url; },
188
+ // p must have ajaxObject
189
+ p.ajaxObject = wo.pager_ajaxObject; // $.extend({}, wo.pager_ajaxObject );
190
+ p.ajaxObject.url = wo.pager_ajaxUrl;
64
191
 
65
- // modify the $.ajax object to allow complete control over your ajax requests
66
- pager_ajaxObject: {
67
- dataType: 'json'
68
- },
192
+ if ( typeof wo.pager_ajaxUrl === 'string' ) {
193
+ // ajax pager; interact with database
194
+ p.ajax = true;
195
+ // When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
196
+ wo.filter_serversideFiltering = true;
197
+ c.serverSideSorting = true;
198
+ tsp.moveToPage(table, p);
199
+ } else {
200
+ p.ajax = false;
201
+ // Regular pager; all rows stored in memory
202
+ c.$table.trigger('appendCache', [ {}, true ]);
203
+ }
69
204
 
70
- // set this to false if you want to block ajax loading on init
71
- pager_processAjaxOnInit: true,
72
-
73
- // process ajax so that the following information is returned:
74
- // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
75
- // example:
76
- // [
77
- // 100, // total rows
78
- // [
79
- // [ "row1cell1", "row1cell2", ... "row1cellN" ],
80
- // [ "row2cell1", "row2cell2", ... "row2cellN" ],
81
- // ...
82
- // [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
83
- // ],
84
- // [ "header1", "header2", ... "headerN" ] // optional
85
- // ]
86
- pager_ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
87
-
88
- // css class names of pager arrows
89
- pager_css: {
90
- container : 'tablesorter-pager',
91
- errorRow : 'tablesorter-errorRow', // error information row (don't include period at beginning)
92
- disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows "disabled" on first page)
93
205
  },
94
206
 
95
- // jQuery selectors
96
- pager_selectors: {
97
- container : '.pager', // target the pager markup
98
- first : '.first', // go to first page arrow
99
- prev : '.prev', // previous page arrow
100
- next : '.next', // next page arrow
101
- last : '.last', // go to last page arrow
102
- gotoPage : '.gotoPage', // go to page selector - select dropdown that sets the current page
103
- pageDisplay : '.pagedisplay', // location of where the "output" is displayed
104
- pageSize : '.pagesize' // page size selector - select dropdown that sets the "size" option
105
- }
106
- },
107
- init: function(table){
108
- tsp.init(table);
109
- },
110
- // only update to complete sorter initialization
111
- format: function(table, c){
112
- if (!(c.pager && c.pager.initialized)){
113
- return tsp.initComplete(table, c);
114
- }
115
- tsp.moveToPage(table, c.pager, false);
116
- },
117
- remove: function(table, c, wo, refreshing){
118
- tsp.destroyPager(table, c, refreshing);
119
- }
120
- });
121
-
122
- /* pager widget functions */
123
- tsp = ts.pager = {
124
-
125
- init: function(table) {
126
- // check if tablesorter has initialized
127
- if (table.hasInitialized && table.config.pager.initialized) { return; }
128
- var t,
129
- c = table.config,
130
- wo = c.widgetOptions,
131
- s = wo.pager_selectors,
132
-
133
- // save pager variables
134
- p = c.pager = $.extend({
135
- totalPages: 0,
136
- filteredRows: 0,
137
- filteredPages: 0,
138
- currentFilters: [],
139
- page: wo.pager_startPage,
140
- startRow: 0,
141
- endRow: 0,
142
- ajaxCounter: 0,
143
- $size: null,
144
- last: {},
145
- // save original pager size
146
- setSize: wo.pager_size,
147
- setPage: wo.pager_startPage,
148
- events: 'filterInit filterStart filterEnd sortEnd disable enable destroy updateComplete ' +
149
- 'pageSize pageSet pageAndSize pagerUpdate refreshComplete '
150
- }, c.pager);
151
-
152
- // pager initializes multiple times before table has completed initialization
153
- if (p.isInitializing) { return; }
154
-
155
- p.isInitializing = true;
156
- if (c.debug) {
157
- ts.log('Pager: Initializing');
158
- }
159
-
160
- p.size = $.data(table, 'pagerLastSize') || wo.pager_size;
161
- // added in case the pager is reinitialized after being destroyed.
162
- p.$container = $(s.container).addClass(wo.pager_css.container).show();
163
- // goto selector
164
- p.$goto = p.$container.find(s.gotoPage); // goto is a reserved word #657
165
- // page size selector
166
- p.$size = p.$container.find(s.pageSize);
167
- p.totalRows = c.$tbodies.eq(0).children('tr').not( wo.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
168
- p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
169
- c.appender = tsp.appender;
170
- p.initializing = true;
171
- if (wo.pager_savePages && ts.storage) {
172
- t = ts.storage(table, wo.pager_storageKey) || {}; // fixes #387
173
- p.page = ( isNaN(t.page) ? p.page : t.page ) || p.setPage || 0;
174
- p.size = ( isNaN(t.size) ? p.size : t.size ) || p.setSize || 10;
175
- $.data(table, 'pagerLastSize', p.size);
176
- }
177
-
178
- // skipped rows
179
- p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.slice(1) + '|' + c.cssChildRow + ')');
180
-
181
- // clear initialized flag
182
- p.initialized = false;
183
- // before initialization event
184
- c.$table.trigger('pagerBeforeInitialized', c);
185
-
186
- tsp.enablePager(table, c, false);
187
-
188
- // p must have ajaxObject
189
- p.ajaxObject = wo.pager_ajaxObject; // $.extend({}, wo.pager_ajaxObject );
190
- p.ajaxObject.url = wo.pager_ajaxUrl;
191
-
192
- if ( typeof(wo.pager_ajaxUrl) === 'string' ) {
193
- // ajax pager; interact with database
194
- p.ajax = true;
195
- // When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
196
- wo.filter_serversideFiltering = true;
197
- c.serverSideSorting = true;
198
- tsp.moveToPage(table, p);
199
- } else {
200
- p.ajax = false;
201
- // Regular pager; all rows stored in memory
202
- c.$table.trigger('appendCache', [{}, true]);
203
- }
207
+ initComplete: function(table, c){
208
+ var p = c.pager;
209
+ tsp.bindEvents(table, c);
210
+ tsp.setPageSize(table, 0, c); // page size 0 is ignored
204
211
 
205
- },
212
+ if (!p.ajax) {
213
+ tsp.hideRowsSetup(table, c);
214
+ }
206
215
 
207
- initComplete: function(table, c){
208
- var p = c.pager;
209
- tsp.bindEvents(table, c);
210
- tsp.setPageSize(table, 0, c); // page size 0 is ignored
216
+ // pager initialized
217
+ p.initialized = true;
218
+ p.initializing = false;
219
+ p.isInitializing = false;
220
+ if (c.debug) {
221
+ console.log('Pager: Triggering pagerInitialized');
222
+ }
223
+ c.$table.trigger('pagerInitialized', c);
224
+ // filter widget not initialized; it will update the output display & fire off the pagerComplete event
225
+ if ( !( c.widgetOptions.filter_initialized && ts.hasWidget(table, 'filter') ) ) {
226
+ // if ajax, then don't fire off pagerComplete
227
+ tsp.updatePageDisplay(table, c, !p.ajax);
228
+ }
229
+ },
211
230
 
212
- if (!p.ajax) {
213
- tsp.hideRowsSetup(table, c);
214
- }
231
+ bindEvents: function(table, c){
232
+ var ctrls, fxn,
233
+ p = c.pager,
234
+ wo = c.widgetOptions,
235
+ namespace = c.namespace + 'pager',
236
+ s = wo.pager_selectors;
215
237
 
216
- // pager initialized
217
- p.initialized = true;
218
- p.initializing = false;
219
- p.isInitializing = false;
220
- if (c.debug) {
221
- ts.log('Pager: Triggering pagerInitialized');
222
- }
223
- c.$table.trigger('pagerInitialized', c);
224
- // filter widget not initialized; it will update the output display & fire off the pagerComplete event
225
- if ( !( c.widgetOptions.filter_initialized && ts.hasWidget(table, 'filter') ) ) {
226
- // if ajax, then don't fire off pagerComplete
227
- tsp.updatePageDisplay(table, c, !p.ajax);
228
- }
229
- },
230
-
231
- bindEvents: function(table, c){
232
- var ctrls, fxn,
233
- p = c.pager,
234
- wo = c.widgetOptions,
235
- s = wo.pager_selectors;
236
-
237
- c.$table
238
- .off( $.trim(p.events.split(' ').join('.pager ')) )
239
- .on('filterInit.pager filterStart.pager', function(e, filters) {
240
- p.currentFilters = $.isArray(filters) ? filters : c.$table.data('lastSearch');
241
- // don't change page if filters are the same (pager updating, etc)
242
- if (e.type === 'filterStart' && wo.pager_pageReset !== false && (c.lastCombinedFilter || '') !== (p.currentFilters || []).join('')) {
243
- p.page = wo.pager_pageReset; // fixes #456 & #565
244
- }
245
- })
246
- // update pager after filter widget completes
247
- .on('filterEnd.pager sortEnd.pager', function() {
248
- p.currentFilters = c.$table.data('lastSearch');
249
- if (p.initialized || p.initializing) {
250
- if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
251
- // make sure we have a copy of all table rows once the cache has been built
238
+ c.$table
239
+ .off( $.trim(p.events.split(' ').join(namespace + ' ')) )
240
+ .on('filterInit filterStart '.split(' ').join(namespace + ' '), function(e, filters) {
241
+ p.currentFilters = $.isArray(filters) ? filters : c.$table.data('lastSearch');
242
+ // don't change page if filters are the same (pager updating, etc)
243
+ if (e.type === 'filterStart' && wo.pager_pageReset !== false && (c.lastCombinedFilter || '') !== (p.currentFilters || []).join('')) {
244
+ p.page = wo.pager_pageReset; // fixes #456 & #565
245
+ }
246
+ })
247
+ // update pager after filter widget completes
248
+ .on('filterEnd sortEnd '.split(' ').join(namespace + ' '), function() {
249
+ p.currentFilters = c.$table.data('lastSearch');
250
+ if (p.initialized || p.initializing) {
251
+ if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
252
+ // make sure we have a copy of all table rows once the cache has been built
253
+ tsp.updateCache(table);
254
+ }
255
+ tsp.updatePageDisplay(table, c, false);
256
+ // tsp.moveToPage(table, p, false); <-- called when applyWidgets is triggered
257
+ c.$table.trigger('applyWidgets');
258
+ }
259
+ })
260
+ .on('disable' + namespace, function(e){
261
+ e.stopPropagation();
262
+ tsp.showAllRows(table, c);
263
+ })
264
+ .on('enable' + namespace, function(e){
265
+ e.stopPropagation();
266
+ tsp.enablePager(table, c, true);
267
+ })
268
+ .on('destroy' + namespace, function(e, refreshing){
269
+ e.stopPropagation();
270
+ tsp.destroyPager(table, c, refreshing);
271
+ })
272
+ .on('updateComplete' + namespace, function(e, table, triggered){
273
+ e.stopPropagation();
274
+ // table can be unintentionally undefined in tablesorter v2.17.7 and earlier
275
+ // don't recalculate total rows/pages if using ajax
276
+ if (!table || triggered || p.ajax) { return; }
277
+ var $rows = c.$tbodies.eq(0).children('tr').not(c.selectorRemove);
278
+ p.totalRows = $rows.length - ( wo.pager_countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
279
+ p.totalPages = Math.ceil( p.totalRows / p.size );
280
+ if ($rows.length && c.rowsCopy && c.rowsCopy.length === 0) {
281
+ // make a copy of all table rows once the cache has been built
252
282
  tsp.updateCache(table);
253
283
  }
284
+ if ( p.page >= p.totalPages ) {
285
+ tsp.moveToLastPage(table, p);
286
+ }
287
+ tsp.hideRows(table, c);
288
+ tsp.changeHeight(table, c);
289
+ // update without triggering pagerComplete
254
290
  tsp.updatePageDisplay(table, c, false);
255
- // tsp.moveToPage(table, p, false); <-- called when applyWidgets is triggered
291
+ // make sure widgets are applied - fixes #450
256
292
  c.$table.trigger('applyWidgets');
257
- }
258
- })
259
- .on('disable.pager', function(e){
260
- e.stopPropagation();
261
- tsp.showAllRows(table, c);
262
- })
263
- .on('enable.pager', function(e){
264
- e.stopPropagation();
265
- tsp.enablePager(table, c, true);
266
- })
267
- .on('destroy.pager', function(e, refreshing){
268
- e.stopPropagation();
269
- tsp.destroyPager(table, c, refreshing);
270
- })
271
- .on('updateComplete.pager', function(e, table, triggered){
272
- e.stopPropagation();
273
- // table can be unintentionally undefined in tablesorter v2.17.7 and earlier
274
- // don't recalculate total rows/pages if using ajax
275
- if (!table || triggered || p.ajax) { return; }
276
- var $rows = c.$tbodies.eq(0).children('tr').not(c.selectorRemove);
277
- p.totalRows = $rows.length - ( wo.pager_countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
278
- p.totalPages = Math.ceil( p.totalRows / p.size );
279
- if ($rows.length && c.rowsCopy && c.rowsCopy.length === 0) {
280
- // make a copy of all table rows once the cache has been built
281
- tsp.updateCache(table);
282
- }
283
- if ( p.page >= p.totalPages ) {
284
- tsp.moveToLastPage(table, p);
285
- }
286
- tsp.hideRows(table, c);
287
- tsp.changeHeight(table, c);
288
- // update without triggering pagerComplete
289
- tsp.updatePageDisplay(table, c, false);
290
- // make sure widgets are applied - fixes #450
291
- c.$table.trigger('applyWidgets');
292
- tsp.updatePageDisplay(table, c);
293
- })
294
- .on('pageSize.pager refreshComplete.pager', function(e,v){
295
- e.stopPropagation();
296
- tsp.setPageSize(table, parseInt(v, 10) || p.setSize || 10, c);
297
- tsp.hideRows(table, c);
298
- tsp.updatePageDisplay(table, c, false);
299
- })
300
- .on('pageSet.pager pagerUpdate.pager', function(e,v){
301
- e.stopPropagation();
302
- // force pager refresh
303
- if (e.type === 'pagerUpdate') {
304
- v = typeof v === 'undefined' ? p.page + 1 : v;
305
- p.last.page = true;
306
- }
307
- p.page = (parseInt(v, 10) || 1) - 1;
308
- tsp.moveToPage(table, p, true);
309
- tsp.updatePageDisplay(table, c, false);
310
- })
311
- .on('pageAndSize.pager', function(e, page, size){
312
- e.stopPropagation();
313
- p.page = (parseInt(page, 10) || 1) - 1;
314
- tsp.setPageSize(table, parseInt(size, 10) || p.setSize || 10, c);
315
- tsp.moveToPage(table, p, true);
316
- tsp.hideRows(table, c);
317
- tsp.updatePageDisplay(table, c, false);
318
- });
319
-
320
- // clicked controls
321
- ctrls = [ s.first, s.prev, s.next, s.last ];
322
- fxn = [ 'moveToFirstPage', 'moveToPrevPage', 'moveToNextPage', 'moveToLastPage' ];
323
- if (c.debug && !p.$container.length) {
324
- ts.log('Pager: >> Container not found');
325
- }
326
- p.$container.find(ctrls.join(','))
327
- .attr("tabindex", 0)
328
- .off('click.pager')
329
- .on('click.pager', function(e){
330
- e.stopPropagation();
331
- var i,
332
- $c = $(this),
333
- l = ctrls.length;
334
- if ( !$c.hasClass(wo.pager_css.disabled) ) {
335
- for (i = 0; i < l; i++) {
336
- if ($c.is(ctrls[i])) {
337
- tsp[fxn[i]](table, p);
338
- break;
339
- }
293
+ tsp.updatePageDisplay(table, c);
294
+ })
295
+ .on('pageSize refreshComplete '.split(' ').join(namespace + ' '), function(e, v){
296
+ e.stopPropagation();
297
+ tsp.setPageSize(table, parseInt(v, 10) || p.setSize || 10, c);
298
+ tsp.hideRows(table, c);
299
+ tsp.updatePageDisplay(table, c, false);
300
+ })
301
+ .on('pageSet pagerUpdate '.split(' ').join(namespace + ' '), function(e, v){
302
+ e.stopPropagation();
303
+ // force pager refresh
304
+ if (e.type === 'pagerUpdate') {
305
+ v = typeof v === 'undefined' ? p.page + 1 : v;
306
+ p.last.page = true;
340
307
  }
341
- }
342
- });
343
-
344
- if ( p.$goto.length ) {
345
- p.$goto
346
- .off('change.pager')
347
- .on('change.pager', function(){
348
- p.page = $(this).val() - 1;
308
+ p.page = (parseInt(v, 10) || 1) - 1;
349
309
  tsp.moveToPage(table, p, true);
350
310
  tsp.updatePageDisplay(table, c, false);
311
+ })
312
+ .on('pageAndSize' + namespace, function(e, page, size){
313
+ e.stopPropagation();
314
+ p.page = (parseInt(page, 10) || 1) - 1;
315
+ tsp.setPageSize(table, parseInt(size, 10) || p.setSize || 10, c);
316
+ tsp.moveToPage(table, p, true);
317
+ tsp.hideRows(table, c);
318
+ tsp.updatePageDisplay(table, c, false);
351
319
  });
352
- } else if (c.debug) {
353
- ts.log('Pager: >> Goto selector not found');
354
- }
355
320
 
356
- if ( p.$size.length ) {
357
- // setting an option as selected appears to cause issues with initial page size
358
- p.$size.find('option').removeAttr('selected');
359
- p.$size
360
- .off('change.pager')
361
- .on('change.pager', function() {
362
- p.$size.val( $(this).val() ); // in case there are more than one pagers
363
- if ( !$(this).hasClass(wo.pager_css.disabled) ) {
364
- tsp.setPageSize(table, parseInt( $(this).val(), 10 ), c);
365
- tsp.changeHeight(table, c);
321
+ // clicked controls
322
+ ctrls = [ s.first, s.prev, s.next, s.last ];
323
+ fxn = [ 'moveToFirstPage', 'moveToPrevPage', 'moveToNextPage', 'moveToLastPage' ];
324
+ if (c.debug && !p.$container.length) {
325
+ console.warn('Pager: >> Container not found');
326
+ }
327
+ p.$container.find(ctrls.join(','))
328
+ .attr('tabindex', 0)
329
+ .off('click' + namespace)
330
+ .on('click' + namespace, function(e){
331
+ e.stopPropagation();
332
+ var i,
333
+ $c = $(this),
334
+ l = ctrls.length;
335
+ if ( !$c.hasClass(wo.pager_css.disabled) ) {
336
+ for (i = 0; i < l; i++) {
337
+ if ($c.is(ctrls[i])) {
338
+ tsp[fxn[i]](table, p);
339
+ break;
340
+ }
341
+ }
366
342
  }
367
- return false;
368
343
  });
369
- } else if (c.debug) {
370
- ts.log('Pager: >> Size selector not found');
371
- }
372
344
 
373
- },
374
-
375
- // hide arrows at extremes
376
- pagerArrows: function(c, disable) {
377
- var p = c.pager,
378
- dis = !!disable,
379
- first = dis || p.page === 0,
380
- tp = Math.min( p.totalPages, p.filteredPages ),
381
- last = dis || p.page === tp - 1 || tp === 0,
382
- wo = c.widgetOptions,
383
- s = wo.pager_selectors;
384
- if ( wo.pager_updateArrows ) {
385
- p.$container.find(s.first + ',' + s.prev).toggleClass(wo.pager_css.disabled, first).attr('aria-disabled', first);
386
- p.$container.find(s.next + ',' + s.last).toggleClass(wo.pager_css.disabled, last).attr('aria-disabled', last);
387
- }
388
- },
389
-
390
- calcFilters: function(table, c) {
391
- var normalized, indx, len,
392
- wo = c.widgetOptions,
393
- p = c.pager,
394
- hasFilters = c.$table.hasClass('hasFilters');
395
- if (hasFilters && !wo.pager_ajaxUrl) {
396
- if ($.isEmptyObject(c.cache)) {
397
- // delayInit: true so nothing is in the cache
398
- p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( wo.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
399
- } else {
400
- p.filteredRows = 0;
401
- normalized = c.cache[0].normalized;
402
- len = normalized.length;
403
- for (indx = 0; indx < len; indx++) {
404
- p.filteredRows += p.regexRows.test(normalized[indx][c.columns].$row[0].className) ? 0 : 1;
345
+ if ( p.$goto.length ) {
346
+ p.$goto
347
+ .off('change' + namespace)
348
+ .on('change' + namespace, function(){
349
+ p.page = $(this).val() - 1;
350
+ tsp.moveToPage(table, p, true);
351
+ tsp.updatePageDisplay(table, c, false);
352
+ });
353
+ } else if (c.debug) {
354
+ console.warn('Pager: >> Goto selector not found');
355
+ }
356
+
357
+ if ( p.$size.length ) {
358
+ // setting an option as selected appears to cause issues with initial page size
359
+ p.$size.find('option').removeAttr('selected');
360
+ p.$size
361
+ .off('change' + namespace)
362
+ .on('change' + namespace, function() {
363
+ p.$size.val( $(this).val() ); // in case there are more than one pagers
364
+ if ( !$(this).hasClass(wo.pager_css.disabled) ) {
365
+ tsp.setPageSize(table, parseInt( $(this).val(), 10 ), c);
366
+ tsp.changeHeight(table, c);
367
+ }
368
+ return false;
369
+ });
370
+ } else if (c.debug) {
371
+ console.warn('Pager: >> Size selector not found');
372
+ }
373
+
374
+ },
375
+
376
+ // hide arrows at extremes
377
+ pagerArrows: function(c, disable) {
378
+ var p = c.pager,
379
+ dis = !!disable,
380
+ first = dis || p.page === 0,
381
+ tp = Math.min( p.totalPages, p.filteredPages ),
382
+ last = dis || p.page === tp - 1 || tp === 0,
383
+ wo = c.widgetOptions,
384
+ s = wo.pager_selectors;
385
+ if ( wo.pager_updateArrows ) {
386
+ p.$container.find(s.first + ',' + s.prev).toggleClass(wo.pager_css.disabled, first).attr('aria-disabled', first);
387
+ p.$container.find(s.next + ',' + s.last).toggleClass(wo.pager_css.disabled, last).attr('aria-disabled', last);
388
+ }
389
+ },
390
+
391
+ calcFilters: function(table, c) {
392
+ var normalized, indx, len,
393
+ wo = c.widgetOptions,
394
+ p = c.pager,
395
+ hasFilters = c.$table.hasClass('hasFilters');
396
+ if (hasFilters && !wo.pager_ajaxUrl) {
397
+ if ($.isEmptyObject(c.cache)) {
398
+ // delayInit: true so nothing is in the cache
399
+ p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( wo.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
400
+ } else {
401
+ p.filteredRows = 0;
402
+ normalized = c.cache[0].normalized;
403
+ len = normalized.length;
404
+ for (indx = 0; indx < len; indx++) {
405
+ p.filteredRows += p.regexRows.test(normalized[indx][c.columns].$row[0].className) ? 0 : 1;
406
+ }
405
407
  }
408
+ } else if (!hasFilters) {
409
+ p.filteredRows = p.totalRows;
406
410
  }
407
- } else if (!hasFilters) {
408
- p.filteredRows = p.totalRows;
409
- }
410
- },
411
-
412
- updatePageDisplay: function(table, c, completed) {
413
- if ( c.pager.initializing ) { return; }
414
- var s, t, $out, options, indx, len,
415
- wo = c.widgetOptions,
416
- p = c.pager,
417
- sz = p.size || p.setSize || 10; // don't allow dividing by zero
418
- if (wo.pager_countChildRows) { t.push(c.cssChildRow); }
419
- p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
420
- p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
421
- c.totalRows = p.totalRows;
422
- tsp.calcFilters(table, c);
423
- c.filteredRows = p.filteredRows;
424
- p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
425
- if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
426
- t = (p.size * p.page > p.filteredRows) && completed;
427
- p.page = (t) ? wo.pager_pageReset || 0 : p.page;
428
- p.startRow = (t) ? p.size * p.page + 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
429
- p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
430
- $out = p.$container.find(wo.pager_selectors.pageDisplay);
431
- // form the output string (can now get a new output string from the server)
432
- s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || wo.pager_output : wo.pager_output )
433
- // {page} = one-based index; {page+#} = zero based index +/- value
434
- .replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
435
- return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
436
- })
437
- // {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
438
- .replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
439
- var len, indx,
440
- str = m.replace(/[{}\s]/g,''),
441
- extra = str.split(':'),
442
- data = p.ajaxData,
443
- // return zero for default page/row numbers
444
- deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
445
- if (/(startRow|page)/.test(extra[0]) && extra[1] === 'input') {
446
- len = ('' + (extra[0] === 'page' ? p.totalPages : p.totalRows)).length;
447
- indx = extra[0] === 'page' ? p.page + 1 : p.startRow;
448
- return '<input type="text" class="ts-' + extra[0] + '" style="max-width:' + len + 'em" value="' + indx + '"/>';
411
+ },
412
+
413
+ updatePageDisplay: function(table, c, completed) {
414
+ if ( c.pager.initializing ) { return; }
415
+ var s, t, $out, options, indx, len,
416
+ wo = c.widgetOptions,
417
+ p = c.pager,
418
+ namespace = c.namespace + 'pager',
419
+ sz = p.size || p.setSize || 10; // don't allow dividing by zero
420
+ if (wo.pager_countChildRows) { t.push(c.cssChildRow); }
421
+ p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
422
+ p.totalPages = Math.ceil( p.totalRows / sz ); // needed for 'pageSize' method
423
+ c.totalRows = p.totalRows;
424
+ tsp.calcFilters(table, c);
425
+ c.filteredRows = p.filteredRows;
426
+ p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
427
+ if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
428
+ t = (p.size * p.page > p.filteredRows) && completed;
429
+ p.page = (t) ? wo.pager_pageReset || 0 : p.page;
430
+ p.startRow = (t) ? p.size * p.page + 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
431
+ p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
432
+ $out = p.$container.find(wo.pager_selectors.pageDisplay);
433
+ // form the output string (can now get a new output string from the server)
434
+ s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || wo.pager_output : wo.pager_output )
435
+ // {page} = one-based index; {page+#} = zero based index +/- value
436
+ .replace(/\{page([\-+]\d+)?\}/gi, function(m, n){
437
+ return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
438
+ })
439
+ // {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
440
+ .replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
441
+ var len, indx,
442
+ str = m.replace(/[{}\s]/g, ''),
443
+ extra = str.split(':'),
444
+ data = p.ajaxData,
445
+ // return zero for default page/row numbers
446
+ deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
447
+ if (/(startRow|page)/.test(extra[0]) && extra[1] === 'input') {
448
+ len = ('' + (extra[0] === 'page' ? p.totalPages : p.totalRows)).length;
449
+ indx = extra[0] === 'page' ? p.page + 1 : p.startRow;
450
+ return '<input type="text" class="ts-' + extra[0] + '" style="max-width:' + len + 'em" value="' + indx + '"/>';
451
+ }
452
+ return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
453
+ });
454
+ if ( p.$goto.length ) {
455
+ t = '';
456
+ options = tsp.buildPageSelect(p, c);
457
+ len = options.length;
458
+ for (indx = 0; indx < len; indx++) {
459
+ t += '<option value="' + options[indx] + '">' + options[indx] + '</option>';
449
460
  }
450
- return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
451
- });
452
- if ( p.$goto.length ) {
453
- t = '';
454
- options = tsp.buildPageSelect(p, c);
455
- len = options.length;
456
- for (indx = 0; indx < len; indx++) {
457
- t += '<option value="' + options[indx] + '">' + options[indx] + '</option>';
461
+ // innerHTML doesn't work in IE9 - http://support2.microsoft.com/kb/276228
462
+ p.$goto.html(t).val( p.page + 1 );
463
+ }
464
+ if ($out.length) {
465
+ $out[ ($out[0].nodeName === 'INPUT') ? 'val' : 'html' ](s);
466
+ // rebind startRow/page inputs
467
+ $out.find('.ts-startRow, .ts-page').off('change' + namespace).on('change' + namespace, function(){
468
+ var v = $(this).val(),
469
+ pg = $(this).hasClass('ts-startRow') ? Math.floor( v / p.size ) + 1 : v;
470
+ c.$table.trigger('pageSet' + namespace, [ pg ]);
471
+ });
458
472
  }
459
- // innerHTML doesn't work in IE9 - http://support2.microsoft.com/kb/276228
460
- p.$goto.html(t).val( p.page + 1 );
461
473
  }
462
- if ($out.length) {
463
- $out[ ($out[0].nodeName === 'INPUT') ? 'val' : 'html' ](s);
464
- // rebind startRow/page inputs
465
- $out.find('.ts-startRow, .ts-page').off('change.pager').on('change.pager', function(){
466
- var v = $(this).val(),
467
- pg = $(this).hasClass('ts-startRow') ? Math.floor( v/p.size ) + 1 : v;
468
- c.$table.trigger('pageSet.pager', [ pg ]);
469
- });
474
+ tsp.pagerArrows(c);
475
+ tsp.fixHeight(table, c);
476
+ if (p.initialized && completed !== false) {
477
+ if (c.debug) {
478
+ console.log('Pager: Triggering pagerComplete');
479
+ }
480
+ c.$table.trigger('pagerComplete', c);
481
+ // save pager info to storage
482
+ if (wo.pager_savePages && ts.storage) {
483
+ ts.storage(table, wo.pager_storageKey, {
484
+ page : p.page,
485
+ size : p.size
486
+ });
487
+ }
470
488
  }
471
- }
472
- tsp.pagerArrows(c);
473
- tsp.fixHeight(table, c);
474
- if (p.initialized && completed !== false) {
475
- if (c.debug) {
476
- ts.log('Pager: Triggering pagerComplete');
489
+ },
490
+
491
+ buildPageSelect: function(p, c) {
492
+ // Filter the options page number link array if it's larger than 'pager_maxOptionSize'
493
+ // as large page set links will slow the browser on large dom inserts
494
+ var i, central_focus_size, focus_option_pages, insert_index, option_length, focus_length,
495
+ wo = c.widgetOptions,
496
+ pg = Math.min( p.totalPages, p.filteredPages ) || 1,
497
+ // make skip set size multiples of 5
498
+ skip_set_size = Math.ceil( ( pg / wo.pager_maxOptionSize ) / 5 ) * 5,
499
+ large_collection = pg > wo.pager_maxOptionSize,
500
+ current_page = p.page + 1,
501
+ start_page = skip_set_size,
502
+ end_page = pg - skip_set_size,
503
+ option_pages = [ 1 ],
504
+ // construct default options pages array
505
+ option_pages_start_page = (large_collection) ? skip_set_size : 1;
506
+
507
+ for ( i = option_pages_start_page; i <= pg; ) {
508
+ option_pages.push(i);
509
+ i = i + ( large_collection ? skip_set_size : 1 );
477
510
  }
478
- c.$table.trigger('pagerComplete', c);
479
- // save pager info to storage
480
- if (wo.pager_savePages && ts.storage) {
481
- ts.storage(table, wo.pager_storageKey, {
482
- page : p.page,
483
- size : p.size
511
+ option_pages.push(pg);
512
+
513
+ if (large_collection) {
514
+ focus_option_pages = [];
515
+ // don't allow central focus size to be > 5 on either side of current page
516
+ central_focus_size = Math.max( Math.floor( wo.pager_maxOptionSize / skip_set_size ) - 1, 5 );
517
+
518
+ start_page = current_page - central_focus_size;
519
+ if (start_page < 1) { start_page = 1; }
520
+ end_page = current_page + central_focus_size;
521
+ if (end_page > pg) { end_page = pg; }
522
+ // construct an array to get a focus set around the current page
523
+ for (i = start_page; i <= end_page ; i++) {
524
+ focus_option_pages.push(i);
525
+ }
526
+
527
+ // keep unique values
528
+ option_pages = $.grep(option_pages, function(value, indx) {
529
+ return $.inArray(value, option_pages) === indx;
484
530
  });
485
- }
486
- }
487
- },
488
-
489
- buildPageSelect: function(p, c) {
490
- // Filter the options page number link array if it's larger than 'pager_maxOptionSize'
491
- // as large page set links will slow the browser on large dom inserts
492
- var i, central_focus_size, focus_option_pages, insert_index, option_length, focus_length,
493
- wo = c.widgetOptions,
494
- pg = Math.min( p.totalPages, p.filteredPages ) || 1,
495
- // make skip set size multiples of 5
496
- skip_set_size = Math.ceil( ( pg / wo.pager_maxOptionSize ) / 5 ) * 5,
497
- large_collection = pg > wo.pager_maxOptionSize,
498
- current_page = p.page + 1,
499
- start_page = skip_set_size,
500
- end_page = pg - skip_set_size,
501
- option_pages = [1],
502
- // construct default options pages array
503
- option_pages_start_page = (large_collection) ? skip_set_size : 1;
504
-
505
- for ( i = option_pages_start_page; i <= pg; ) {
506
- option_pages.push(i);
507
- i = i + ( large_collection ? skip_set_size : 1 );
508
- }
509
- option_pages.push(pg);
510
-
511
- if (large_collection) {
512
- focus_option_pages = [];
513
- // don't allow central focus size to be > 5 on either side of current page
514
- central_focus_size = Math.max( Math.floor( wo.pager_maxOptionSize / skip_set_size ) - 1, 5 );
515
-
516
- start_page = current_page - central_focus_size;
517
- if (start_page < 1) { start_page = 1; }
518
- end_page = current_page + central_focus_size;
519
- if (end_page > pg) { end_page = pg; }
520
- // construct an array to get a focus set around the current page
521
- for (i = start_page; i <= end_page ; i++) {
522
- focus_option_pages.push(i);
531
+
532
+ option_length = option_pages.length;
533
+ focus_length = focus_option_pages.length;
534
+
535
+ // make sure at all option_pages aren't replaced
536
+ if (option_length - focus_length > skip_set_size / 2 && option_length + focus_length > wo.pager_maxOptionSize ) {
537
+ insert_index = Math.floor(option_length / 2) - Math.floor(focus_length / 2);
538
+ Array.prototype.splice.apply(option_pages, [ insert_index, focus_length ]);
539
+ }
540
+ option_pages = option_pages.concat(focus_option_pages);
541
+
523
542
  }
524
543
 
525
- // keep unique values
544
+ // keep unique values again
526
545
  option_pages = $.grep(option_pages, function(value, indx) {
527
546
  return $.inArray(value, option_pages) === indx;
528
- });
547
+ })
548
+ .sort(function(a, b) { return a - b; });
529
549
 
530
- option_length = option_pages.length;
531
- focus_length = focus_option_pages.length;
550
+ return option_pages;
551
+ },
532
552
 
533
- // make sure at all option_pages aren't replaced
534
- if (option_length - focus_length > skip_set_size / 2 && option_length + focus_length > wo.pager_maxOptionSize ) {
535
- insert_index = Math.floor(option_length / 2) - Math.floor(focus_length / 2);
536
- Array.prototype.splice.apply(option_pages, [ insert_index, focus_length ]);
553
+ fixHeight: function(table, c) {
554
+ var d, h,
555
+ p = c.pager,
556
+ wo = c.widgetOptions,
557
+ $b = c.$tbodies.eq(0);
558
+ $b.find('tr.pagerSavedHeightSpacer').remove();
559
+ if (wo.pager_fixedHeight && !p.isDisabled) {
560
+ h = $.data(table, 'pagerSavedHeight');
561
+ if (h) {
562
+ d = h - $b.height();
563
+ if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
564
+ $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.slice(1) + '" style="height:' + d + 'px;"></tr>');
565
+ }
566
+ }
537
567
  }
538
- option_pages = option_pages.concat(focus_option_pages);
539
-
540
- }
568
+ },
541
569
 
542
- // keep unique values again
543
- option_pages = $.grep(option_pages, function(value, indx) {
544
- return $.inArray(value, option_pages) === indx;
545
- })
546
- .sort(function(a,b) { return a - b; });
547
-
548
- return option_pages;
549
- },
550
-
551
- fixHeight: function(table, c) {
552
- var d, h,
553
- p = c.pager,
554
- wo = c.widgetOptions,
555
- $b = c.$tbodies.eq(0);
556
- $b.find('tr.pagerSavedHeightSpacer').remove();
557
- if (wo.pager_fixedHeight && !p.isDisabled) {
558
- h = $.data(table, 'pagerSavedHeight');
559
- if (h) {
560
- d = h - $b.height();
561
- if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
562
- $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.slice(1) + '" style="height:' + d + 'px;"></tr>');
563
- }
570
+ changeHeight: function(table, c) {
571
+ var h, $b = c.$tbodies.eq(0);
572
+ $b.find('tr.pagerSavedHeightSpacer').remove();
573
+ if (!$b.children('tr:visible').length) {
574
+ $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.slice(1) + '"><td>&nbsp</td></tr>');
564
575
  }
565
- }
566
- },
576
+ h = $b.children('tr').eq(0).height() * c.pager.size;
577
+ $.data(table, 'pagerSavedHeight', h);
578
+ tsp.fixHeight(table, c);
579
+ $.data(table, 'pagerLastSize', c.pager.size);
580
+ },
567
581
 
568
- changeHeight: function(table, c) {
569
- var h, $b = c.$tbodies.eq(0);
570
- $b.find('tr.pagerSavedHeightSpacer').remove();
571
- if (!$b.children('tr:visible').length) {
572
- $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.slice(1) + '"><td>&nbsp</td></tr>');
573
- }
574
- h = $b.children('tr').eq(0).height() * c.pager.size;
575
- $.data(table, 'pagerSavedHeight', h);
576
- tsp.fixHeight(table, c);
577
- $.data(table, 'pagerLastSize', c.pager.size);
578
- },
579
-
580
- hideRows: function(table, c){
581
- if (!c.widgetOptions.pager_ajaxUrl) {
582
- var i,
583
- lastIndex = 0,
584
- p = c.pager,
585
- wo = c.widgetOptions,
586
- rows = c.$tbodies.eq(0).children('tr'),
587
- l = rows.length,
588
- s = ( p.page * p.size ),
589
- e = s + p.size,
590
- f = wo && wo.filter_filteredRow || 'filtered',
591
- last = 0, // for cache indexing
592
- j = 0; // size counter
593
- p.cacheIndex = [];
594
- for ( i = 0; i < l; i++ ){
595
- if ( !rows[i].className.match(f) ) {
596
- if (j === s && rows[i].className.match(c.cssChildRow)) {
597
- // hide child rows @ start of pager (if already visible)
598
- rows[i].style.display = 'none';
599
- } else {
600
- rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
601
- if ( last !== j && j >= s && j < e ) {
602
- p.cacheIndex.push(i);
603
- last = j;
582
+ hideRows: function(table, c){
583
+ if ( !c.widgetOptions.pager_ajaxUrl ) {
584
+ var tbodyIndex, rowIndex, $rows, len, lastIndex,
585
+ p = c.pager,
586
+ wo = c.widgetOptions,
587
+ tbodyLen = c.$tbodies.length,
588
+ start = ( p.page * p.size ),
589
+ end = start + p.size,
590
+ filtr = wo && wo.filter_filteredRow || 'filtered',
591
+ last = 0, // for cache indexing
592
+ size = 0; // size counter
593
+ p.cacheIndex = [];
594
+ for ( tbodyIndex = 0; tbodyIndex < tbodyLen; tbodyIndex++ ) {
595
+ $rows = c.$tbodies.eq( tbodyIndex ).children( 'tr' );
596
+ len = $rows.length;
597
+ lastIndex = 0;
598
+ last = 0; // for cache indexing
599
+ size = 0; // size counter
600
+ for ( rowIndex = 0; rowIndex < len; rowIndex++ ) {
601
+ if ( !$rows[ rowIndex ].className.match( filtr ) ) {
602
+ if ( size === start && $rows[ rowIndex ].className.match( c.cssChildRow ) ) {
603
+ // hide child rows @ start of pager (if already visible)
604
+ $rows[ rowIndex ].style.display = 'none';
605
+ } else {
606
+ $rows[ rowIndex ].style.display = ( size >= start && size < end ) ? '' : 'none';
607
+ if ( last !== size && size >= start && size < end ) {
608
+ p.cacheIndex.push( rowIndex );
609
+ last = size;
610
+ }
611
+ // don't count child rows
612
+ size += $rows[ rowIndex ].className
613
+ .match( c.cssChildRow + '|' + c.selectorRemove.slice( 1 ) ) && !wo.pager_countChildRows ? 0 : 1;
614
+ if ( size === end && $rows[ rowIndex ].style.display !== 'none' &&
615
+ $rows[ rowIndex ].className.match( ts.css.cssHasChild ) ) {
616
+ lastIndex = rowIndex;
617
+ }
618
+ }
604
619
  }
605
- // don't count child rows
606
- j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.slice(1)) && !wo.pager_countChildRows ? 0 : 1;
607
- if ( j === e && rows[i].style.display !== 'none' && rows[i].className.match(ts.css.cssHasChild) ) {
608
- lastIndex = i;
620
+ }
621
+ // add any attached child rows to last row of pager. Fixes part of issue #396
622
+ if ( lastIndex > 0 && $rows[ lastIndex ].className.match( ts.css.cssHasChild ) ) {
623
+ while ( ++lastIndex < len && $rows[ lastIndex ].className.match( c.cssChildRow ) ) {
624
+ $rows[ lastIndex ].style.display = '';
609
625
  }
610
626
  }
611
627
  }
612
628
  }
613
- // add any attached child rows to last row of pager. Fixes part of issue #396
614
- if ( lastIndex > 0 && rows[lastIndex].className.match(ts.css.cssHasChild) ) {
615
- while ( ++lastIndex < l && rows[lastIndex].className.match(c.cssChildRow) ) {
616
- rows[lastIndex].style.display = '';
617
- }
618
- }
619
- }
620
- },
621
-
622
- hideRowsSetup: function(table, c){
623
- var p = c.pager;
624
- p.size = parseInt( p.$size.val(), 10 ) || p.size || p.setSize || 10;
625
- $.data(table, 'pagerLastSize', p.size);
626
- tsp.pagerArrows(c);
627
- if ( !c.widgetOptions.pager_removeRows ) {
628
- tsp.hideRows(table, c);
629
- c.$table.on('sortEnd.pager filterEnd.pager', function(){
629
+ },
630
+
631
+ hideRowsSetup: function(table, c){
632
+ var p = c.pager,
633
+ namespace = c.namespace + 'pager';
634
+ p.size = parseInt( p.$size.val(), 10 ) || p.size || p.setSize || 10;
635
+ $.data(table, 'pagerLastSize', p.size);
636
+ tsp.pagerArrows(c);
637
+ if ( !c.widgetOptions.pager_removeRows ) {
630
638
  tsp.hideRows(table, c);
631
- });
632
- }
633
- },
634
-
635
- renderAjax: function(data, table, c, xhr, exception){
636
- var p = c.pager,
637
- wo = c.widgetOptions;
638
- // process data
639
- if ( $.isFunction(wo.pager_ajaxProcessing) ) {
640
- // ajaxProcessing result: [ total, rows, headers ]
641
- var i, j, t, hsh, $f, $sh, $headers, $h, icon, th, d, l, rr_count, len,
642
- $table = c.$table,
643
- tds = '',
644
- result = wo.pager_ajaxProcessing(data, table, xhr) || [ 0, [] ],
645
- hl = $table.find('thead th').length;
646
-
647
- // Clean up any previous error.
648
- ts.showError(table);
649
-
650
- if ( exception ) {
651
- if (c.debug) {
652
- ts.log('Pager: >> Ajax Error', xhr, exception);
653
- }
654
- ts.showError(table, exception.message + ' (' + xhr.status + ')');
655
- c.$tbodies.eq(0).children('tr').detach();
656
- p.totalRows = 0;
657
- } else {
658
- // process ajax object
659
- if (!$.isArray(result)) {
660
- p.ajaxData = result;
661
- c.totalRows = p.totalRows = result.total;
662
- c.filteredRows = p.filteredRows = typeof result.filteredRows !== 'undefined' ? result.filteredRows : result.total;
663
- th = result.headers;
664
- d = result.rows || [];
639
+ c.$table.on('sortEnd filterEnd '.split(' ').join(namespace + ' '), function(){
640
+ tsp.hideRows(table, c);
641
+ });
642
+ }
643
+ },
644
+
645
+ renderAjax: function(data, table, c, xhr, exception){
646
+ var p = c.pager,
647
+ wo = c.widgetOptions;
648
+ // process data
649
+ if ( $.isFunction(wo.pager_ajaxProcessing) ) {
650
+ // ajaxProcessing result: [ total, rows, headers ]
651
+ var i, j, t, hsh, $f, $sh, $headers, $h, icon, th, d, l, rr_count, len,
652
+ $table = c.$table,
653
+ tds = '',
654
+ result = wo.pager_ajaxProcessing(data, table, xhr) || [ 0, [] ],
655
+ hl = $table.find('thead th').length;
656
+
657
+ // Clean up any previous error.
658
+ ts.showError(table);
659
+
660
+ if ( exception ) {
661
+ if (c.debug) {
662
+ console.error('Pager: >> Ajax Error', xhr, exception);
663
+ }
664
+ ts.showError(table, exception.message + ' (' + xhr.status + ')');
665
+ c.$tbodies.eq(0).children('tr').detach();
666
+ p.totalRows = 0;
665
667
  } else {
666
- // allow [ total, rows, headers ] or [ rows, total, headers ]
667
- t = isNaN(result[0]) && !isNaN(result[1]);
668
- // ensure a zero returned row count doesn't fail the logical ||
669
- rr_count = result[t ? 1 : 0];
670
- p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
671
- // can't set filtered rows when returning an array
672
- c.totalRows = c.filteredRows = p.filteredRows = p.totalRows;
673
- // set row data to empty array if nothing found - see http://stackoverflow.com/q/30875583/145346
674
- d = p.totalRows === 0 ? [] : result[t ? 0 : 1] || []; // row data
675
- th = result[2]; // headers
676
- }
677
- l = d && d.length;
678
- if (d instanceof jQuery) {
679
- if (wo.pager_processAjaxOnInit) {
680
- // append jQuery object
681
- c.$tbodies.eq(0).children('tr').detach();
682
- c.$tbodies.eq(0).append(d);
668
+ // process ajax object
669
+ if (!$.isArray(result)) {
670
+ p.ajaxData = result;
671
+ c.totalRows = p.totalRows = result.total;
672
+ c.filteredRows = p.filteredRows = typeof result.filteredRows !== 'undefined' ? result.filteredRows : result.total;
673
+ th = result.headers;
674
+ d = result.rows || [];
675
+ } else {
676
+ // allow [ total, rows, headers ] or [ rows, total, headers ]
677
+ t = isNaN(result[0]) && !isNaN(result[1]);
678
+ // ensure a zero returned row count doesn't fail the logical ||
679
+ rr_count = result[t ? 1 : 0];
680
+ p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
681
+ // can't set filtered rows when returning an array
682
+ c.totalRows = c.filteredRows = p.filteredRows = p.totalRows;
683
+ // set row data to empty array if nothing found - see http://stackoverflow.com/q/30875583/145346
684
+ d = p.totalRows === 0 ? [] : result[t ? 0 : 1] || []; // row data
685
+ th = result[2]; // headers
683
686
  }
684
- } else if (l) {
685
- // build table from array
686
- for ( i = 0; i < l; i++ ) {
687
- tds += '<tr>';
688
- for ( j = 0; j < d[i].length; j++ ) {
689
- // build tbody cells; watch for data containing HTML markup - see #434
690
- tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
687
+ l = d && d.length;
688
+ if (d instanceof jQuery) {
689
+ if (wo.pager_processAjaxOnInit) {
690
+ // append jQuery object
691
+ c.$tbodies.eq(0).children('tr').detach();
692
+ c.$tbodies.eq(0).append(d);
691
693
  }
692
- tds += '</tr>';
693
- }
694
- // add rows to first tbody
695
- if (wo.pager_processAjaxOnInit) {
696
- c.$tbodies.eq(0).html( tds );
697
- }
698
- }
699
- wo.pager_processAjaxOnInit = true;
700
- // only add new header text if the length matches
701
- if ( th && th.length === hl ) {
702
- hsh = $table.hasClass('hasStickyHeaders');
703
- $sh = hsh ? wo.$sticky.children('thead:first').children('tr').children() : '';
704
- $f = $table.find('tfoot tr:first').children();
705
- // don't change td headers (may contain pager)
706
- $headers = c.$headers.filter( 'th ');
707
- len = $headers.length;
708
- for ( j = 0; j < len; j++ ) {
709
- $h = $headers.eq( j );
710
- // add new test within the first span it finds, or just in the header
711
- if ( $h.find('.' + ts.css.icon).length ) {
712
- icon = $h.find('.' + ts.css.icon).clone(true);
713
- $h.find('.tablesorter-header-inner').html( th[j] ).append(icon);
714
- if ( hsh && $sh.length ) {
715
- icon = $sh.eq(j).find('.' + ts.css.icon).clone(true);
716
- $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icon);
694
+ } else if (l) {
695
+ // build table from array
696
+ for ( i = 0; i < l; i++ ) {
697
+ tds += '<tr>';
698
+ for ( j = 0; j < d[i].length; j++ ) {
699
+ // build tbody cells; watch for data containing HTML markup - see #434
700
+ tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
717
701
  }
718
- } else {
719
- $h.find('.tablesorter-header-inner').html( th[j] );
720
- if (hsh && $sh.length) {
721
- $sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
702
+ tds += '</tr>';
703
+ }
704
+ // add rows to first tbody
705
+ if (wo.pager_processAjaxOnInit) {
706
+ c.$tbodies.eq(0).html( tds );
707
+ }
708
+ }
709
+ wo.pager_processAjaxOnInit = true;
710
+ // only add new header text if the length matches
711
+ if ( th && th.length === hl ) {
712
+ hsh = $table.hasClass('hasStickyHeaders');
713
+ $sh = hsh ? wo.$sticky.children('thead:first').children('tr').children() : '';
714
+ $f = $table.find('tfoot tr:first').children();
715
+ // don't change td headers (may contain pager)
716
+ $headers = c.$headers.filter( 'th ');
717
+ len = $headers.length;
718
+ for ( j = 0; j < len; j++ ) {
719
+ $h = $headers.eq( j );
720
+ // add new test within the first span it finds, or just in the header
721
+ if ( $h.find('.' + ts.css.icon).length ) {
722
+ icon = $h.find('.' + ts.css.icon).clone(true);
723
+ $h.find('.tablesorter-header-inner').html( th[j] ).append(icon);
724
+ if ( hsh && $sh.length ) {
725
+ icon = $sh.eq(j).find('.' + ts.css.icon).clone(true);
726
+ $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icon);
727
+ }
728
+ } else {
729
+ $h.find('.tablesorter-header-inner').html( th[j] );
730
+ if (hsh && $sh.length) {
731
+ $sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
732
+ }
722
733
  }
734
+ $f.eq(j).html( th[j] );
723
735
  }
724
- $f.eq(j).html( th[j] );
725
736
  }
726
737
  }
727
- }
728
- if (c.showProcessing) {
729
- ts.isProcessing(table); // remove loading icon
730
- }
731
- // make sure last pager settings are saved, prevents multiple server side calls with
732
- // the same parameters
733
- p.totalPages = Math.ceil( p.totalRows / ( p.size || p.setSize || 10 ) );
734
- p.last.totalRows = p.totalRows;
735
- p.last.currentFilters = p.currentFilters;
736
- p.last.sortList = (c.sortList || []).join(',');
737
- p.initializing = false;
738
- // update display without triggering pager complete... before updating cache
739
- tsp.updatePageDisplay(table, c, false);
740
- $table.trigger('updateCache', [function(){
741
- if (p.initialized) {
742
- // apply widgets after table has rendered & after a delay to prevent
743
- // multiple applyWidget blocking code from blocking this trigger
744
- setTimeout(function(){
745
- if (c.debug) {
746
- ts.log('Pager: Triggering pagerChange');
747
- }
748
- $table
749
- .trigger('applyWidgets')
750
- .trigger('pagerChange', p);
751
- tsp.updatePageDisplay(table, c);
752
- }, 0);
738
+ if (c.showProcessing) {
739
+ ts.isProcessing(table); // remove loading icon
753
740
  }
754
- }]);
755
- }
756
- if (!p.initialized) {
757
- c.$table.trigger('applyWidgets');
758
- }
759
- },
760
-
761
- getAjax: function(table, c){
762
- var counter,
763
- url = tsp.getAjaxUrl(table, c),
764
- $doc = $(document),
765
- p = c.pager;
766
- if ( url !== '' ) {
767
- if (c.showProcessing) {
768
- ts.isProcessing(table, true); // show loading icon
741
+ // make sure last pager settings are saved, prevents multiple server side calls with
742
+ // the same parameters
743
+ p.totalPages = Math.ceil( p.totalRows / ( p.size || p.setSize || 10 ) );
744
+ p.last.totalRows = p.totalRows;
745
+ p.last.currentFilters = p.currentFilters;
746
+ p.last.sortList = (c.sortList || []).join(',');
747
+ p.initializing = false;
748
+ // update display without triggering pager complete... before updating cache
749
+ tsp.updatePageDisplay(table, c, false);
750
+ $table.trigger('updateCache', [ function(){
751
+ if (p.initialized) {
752
+ // apply widgets after table has rendered & after a delay to prevent
753
+ // multiple applyWidget blocking code from blocking this trigger
754
+ setTimeout(function(){
755
+ if (c.debug) {
756
+ console.log('Pager: Triggering pagerChange');
757
+ }
758
+ $table
759
+ .trigger('applyWidgets')
760
+ .trigger('pagerChange', p);
761
+ tsp.updatePageDisplay(table, c);
762
+ }, 0);
763
+ }
764
+ } ]);
765
+ }
766
+ if (!p.initialized) {
767
+ c.$table.trigger('applyWidgets');
769
768
  }
770
- $doc.on('ajaxError.pager', function(e, xhr, settings, exception) {
771
- tsp.renderAjax(null, table, c, xhr, exception);
772
- $doc.off('ajaxError.pager');
773
- });
774
- counter = ++p.ajaxCounter;
775
- p.last.ajaxUrl = url; // remember processed url
776
- p.ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
777
- p.ajaxObject.success = function(data, status, jqxhr) {
778
- // Refuse to process old ajax commands that were overwritten by new ones - see #443
779
- if (counter < p.ajaxCounter){
780
- return;
769
+ },
770
+
771
+ getAjax: function(table, c){
772
+ var counter,
773
+ url = tsp.getAjaxUrl(table, c),
774
+ $doc = $(document),
775
+ namespace = c.namespace + 'pager',
776
+ p = c.pager;
777
+ if ( url !== '' ) {
778
+ if (c.showProcessing) {
779
+ ts.isProcessing(table, true); // show loading icon
781
780
  }
782
- tsp.renderAjax(data, table, c, jqxhr);
783
- $doc.off('ajaxError.pager');
781
+ $doc.on('ajaxError' + namespace, function(e, xhr, settings, exception) {
782
+ tsp.renderAjax(null, table, c, xhr, exception);
783
+ $doc.off('ajaxError' + namespace);
784
+ });
785
+ counter = ++p.ajaxCounter;
786
+ p.last.ajaxUrl = url; // remember processed url
787
+ p.ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
788
+ p.ajaxObject.success = function(data, status, jqxhr) {
789
+ // Refuse to process old ajax commands that were overwritten by new ones - see #443
790
+ if (counter < p.ajaxCounter){
791
+ return;
792
+ }
793
+ tsp.renderAjax(data, table, c, jqxhr);
794
+ $doc.off('ajaxError' + namespace);
784
795
  if (typeof p.oldAjaxSuccess === 'function') {
785
796
  p.oldAjaxSuccess(data);
786
797
  }
787
- };
788
- if (c.debug) {
789
- ts.log('Pager: Ajax initialized', p.ajaxObject);
798
+ };
799
+ if (c.debug) {
800
+ console.log('Pager: Ajax initialized', p.ajaxObject);
801
+ }
802
+ $.ajax(p.ajaxObject);
790
803
  }
791
- $.ajax(p.ajaxObject);
792
- }
793
- },
794
-
795
- getAjaxUrl: function(table, c) {
796
- var indx, len,
797
- p = c.pager,
798
- wo = c.widgetOptions,
799
- url = (wo.pager_ajaxUrl) ? wo.pager_ajaxUrl
800
- // allow using "{page+1}" in the url string to switch to a non-zero based index
801
- .replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
802
- .replace(/\{size\}/g, p.size) : '',
803
- sortList = c.sortList,
804
- filterList = p.currentFilters || $(table).data('lastSearch') || [],
805
- sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
806
- filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
807
- arry = [];
808
- if (sortCol) {
809
- sortCol = sortCol[1];
810
- len = sortList.length;
811
- for (indx = 0; indx < len; indx++) {
812
- arry.push(sortCol + '[' + sortList[indx][0] + ']=' + sortList[indx][1]);
804
+ },
805
+
806
+ getAjaxUrl: function(table, c) {
807
+ var indx, len,
808
+ p = c.pager,
809
+ wo = c.widgetOptions,
810
+ url = (wo.pager_ajaxUrl) ? wo.pager_ajaxUrl
811
+ // allow using '{page+1}' in the url string to switch to a non-zero based index
812
+ .replace(/\{page([\-+]\d+)?\}/, function(s, n){ return p.page + (n ? parseInt(n, 10) : 0); })
813
+ .replace(/\{size\}/g, p.size) : '',
814
+ sortList = c.sortList,
815
+ filterList = p.currentFilters || $(table).data('lastSearch') || [],
816
+ sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
817
+ filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
818
+ arry = [];
819
+ if (sortCol) {
820
+ sortCol = sortCol[1];
821
+ len = sortList.length;
822
+ for (indx = 0; indx < len; indx++) {
823
+ arry.push(sortCol + '[' + sortList[indx][0] + ']=' + sortList[indx][1]);
824
+ }
825
+ // if the arry is empty, just add the col parameter... '&{sortList:col}' becomes '&col'
826
+ url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
827
+ arry = [];
813
828
  }
814
- // if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
815
- url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
816
- arry = [];
817
- }
818
- if (filterCol) {
819
- filterCol = filterCol[1];
820
- len = filterList.length;
821
- for (indx = 0; indx < len; indx++) {
822
- if (filterList[indx]) {
823
- arry.push(filterCol + '[' + indx + ']=' + encodeURIComponent(filterList[indx]));
829
+ if (filterCol) {
830
+ filterCol = filterCol[1];
831
+ len = filterList.length;
832
+ for (indx = 0; indx < len; indx++) {
833
+ if (filterList[indx]) {
834
+ arry.push(filterCol + '[' + indx + ']=' + encodeURIComponent(filterList[indx]));
835
+ }
824
836
  }
837
+ // if the arry is empty, just add the fcol parameter... '&{filterList:fcol}' becomes '&fcol'
838
+ url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
839
+ p.currentFilters = filterList;
825
840
  }
826
- // if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
827
- url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
828
- p.currentFilters = filterList;
829
- }
830
- if ( $.isFunction(wo.pager_customAjaxUrl) ) {
831
- url = wo.pager_customAjaxUrl(table, url);
832
- }
833
- if (c.debug) {
834
- ts.log('Pager: Ajax url = ' + url);
835
- }
836
- return url;
837
- },
838
-
839
- renderTable: function(table, rows) {
840
- var $tb, index, count, added,
841
- c = table.config,
842
- p = c.pager,
843
- wo = c.widgetOptions,
844
- f = c.$table.hasClass('hasFilters'),
845
- l = rows && rows.length || 0, // rows may be undefined
846
- s = ( p.page * p.size ),
847
- e = p.size;
848
- if ( l < 1 ) {
849
- if (c.debug) {
850
- ts.log('Pager: >> No rows for pager to render');
841
+ if ( $.isFunction(wo.pager_customAjaxUrl) ) {
842
+ url = wo.pager_customAjaxUrl(table, url);
851
843
  }
852
- // empty table, abort!
853
- return;
854
- }
855
- if ( p.page >= p.totalPages ) {
856
- // lets not render the table more than once
857
- return tsp.moveToLastPage(table, p);
858
- }
859
- p.cacheIndex = [];
860
- p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
861
- if (p.initialized) {
862
844
  if (c.debug) {
863
- ts.log('Pager: Triggering pagerChange');
845
+ console.log('Pager: Ajax url = ' + url);
864
846
  }
865
- c.$table.trigger('pagerChange', c);
866
- }
867
- if ( !wo.pager_removeRows ) {
868
- tsp.hideRows(table, c);
869
- } else {
870
- ts.clearTableBody(table);
871
- $tb = ts.processTbody(table, c.$tbodies.eq(0), true);
872
- // not filtered, start from the calculated starting point (s)
873
- // if filtered, start from zero
874
- index = f ? 0 : s;
875
- count = f ? 0 : s;
876
- added = 0;
877
- while (added < e && index < rows.length) {
878
- if (!f || !/filtered/.test(rows[index][0].className)){
879
- count++;
880
- if (count > s && added <= e) {
881
- added++;
882
- p.cacheIndex.push(index);
883
- $tb.append(rows[index]);
847
+ return url;
848
+ },
849
+
850
+ renderTable: function(table, rows) {
851
+ var $tb, index, count, added,
852
+ c = table.config,
853
+ p = c.pager,
854
+ wo = c.widgetOptions,
855
+ f = c.$table.hasClass('hasFilters'),
856
+ l = rows && rows.length || 0, // rows may be undefined
857
+ s = ( p.page * p.size ),
858
+ e = p.size;
859
+ if ( l < 1 ) {
860
+ if (c.debug) {
861
+ console.warn('Pager: >> No rows for pager to render');
862
+ }
863
+ // empty table, abort!
864
+ return;
865
+ }
866
+ if ( p.page >= p.totalPages ) {
867
+ // lets not render the table more than once
868
+ return tsp.moveToLastPage(table, p);
869
+ }
870
+ p.cacheIndex = [];
871
+ p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
872
+ if (p.initialized) {
873
+ if (c.debug) {
874
+ console.log('Pager: Triggering pagerChange');
875
+ }
876
+ c.$table.trigger('pagerChange', c);
877
+ }
878
+ if ( !wo.pager_removeRows ) {
879
+ tsp.hideRows(table, c);
880
+ } else {
881
+ ts.clearTableBody(table);
882
+ $tb = ts.processTbody(table, c.$tbodies.eq(0), true);
883
+ // not filtered, start from the calculated starting point (s)
884
+ // if filtered, start from zero
885
+ index = f ? 0 : s;
886
+ count = f ? 0 : s;
887
+ added = 0;
888
+ while (added < e && index < rows.length) {
889
+ if (!f || !/filtered/.test(rows[index][0].className)){
890
+ count++;
891
+ if (count > s && added <= e) {
892
+ added++;
893
+ p.cacheIndex.push(index);
894
+ $tb.append(rows[index]);
895
+ }
884
896
  }
897
+ index++;
885
898
  }
886
- index++;
899
+ ts.processTbody(table, $tb, false);
887
900
  }
888
- ts.processTbody(table, $tb, false);
889
- }
890
- tsp.updatePageDisplay(table, c);
901
+ tsp.updatePageDisplay(table, c);
891
902
 
892
- wo.pager_startPage = p.page;
893
- wo.pager_size = p.size;
894
- if (table.isUpdating) {
895
- if (c.debug) {
896
- ts.log('Pager: Triggering updateComplete');
903
+ wo.pager_startPage = p.page;
904
+ wo.pager_size = p.size;
905
+ if (table.isUpdating) {
906
+ if (c.debug) {
907
+ console.log('Pager: Triggering updateComplete');
908
+ }
909
+ c.$table.trigger('updateComplete', [ table, true ]);
897
910
  }
898
- c.$table.trigger('updateComplete', [ table, true ]);
899
- }
900
911
 
901
- },
912
+ },
902
913
 
903
- showAllRows: function(table, c){
904
- var index, $controls, len,
905
- p = c.pager,
906
- wo = c.widgetOptions;
907
- if ( p.ajax ) {
908
- tsp.pagerArrows(c, true);
909
- } else {
910
- p.isDisabled = true;
911
- $.data(table, 'pagerLastPage', p.page);
912
- $.data(table, 'pagerLastSize', p.size);
913
- p.page = 0;
914
- p.size = p.totalRows;
915
- p.totalPages = 1;
916
- c.$table
917
- .addClass('pagerDisabled')
918
- .removeAttr('aria-describedby')
919
- .find('tr.pagerSavedHeightSpacer').remove();
920
- tsp.renderTable(table, c.rowsCopy);
921
- c.$table.trigger('applyWidgets');
922
- if (c.debug) {
923
- ts.log('Pager: Disabled');
924
- }
925
- }
926
- // disable size selector
927
- $controls = p.$size
928
- .add( p.$goto )
929
- .add( p.$container.find( '.ts-startRow, .ts-page ' ) );
930
- len = $controls.length;
931
- for ( index = 0; index < len; index++ ) {
932
- $controls.eq( index )
933
- .attr( 'aria-disabled', 'true' )
934
- .addClass( wo.pager_css.disabled )[0].disabled = true;
935
- }
936
- },
937
-
938
- // updateCache if delayInit: true
939
- // this is normally done by "appendToTable" function in the tablesorter core AFTER a sort
940
- updateCache: function(table) {
941
- var c = table.config,
942
- p = c.pager;
943
- c.$table.trigger('updateCache', [ function(){
944
- if ( !$.isEmptyObject(table.config.cache) ) {
945
- var i,
946
- rows = [],
947
- n = table.config.cache[0].normalized;
948
- p.totalRows = n.length;
949
- for (i = 0; i < p.totalRows; i++) {
950
- rows.push(n[i][c.columns].$row);
914
+ showAllRows: function(table, c){
915
+ var index, $controls, len,
916
+ p = c.pager,
917
+ wo = c.widgetOptions;
918
+ if ( p.ajax ) {
919
+ tsp.pagerArrows(c, true);
920
+ } else {
921
+ p.isDisabled = true;
922
+ $.data(table, 'pagerLastPage', p.page);
923
+ $.data(table, 'pagerLastSize', p.size);
924
+ p.page = 0;
925
+ p.size = p.totalRows;
926
+ p.totalPages = 1;
927
+ c.$table
928
+ .addClass('pagerDisabled')
929
+ .removeAttr('aria-describedby')
930
+ .find('tr.pagerSavedHeightSpacer').remove();
931
+ tsp.renderTable(table, c.rowsCopy);
932
+ c.$table.trigger('applyWidgets');
933
+ if (c.debug) {
934
+ console.log('Pager: Disabled');
951
935
  }
952
- c.rowsCopy = rows;
953
- tsp.moveToPage(table, p, true);
954
- // clear out last search to force an update
955
- p.last.currentFilters = [' '];
956
936
  }
957
- } ]);
958
- },
937
+ // disable size selector
938
+ $controls = p.$size
939
+ .add( p.$goto )
940
+ .add( p.$container.find( '.ts-startRow, .ts-page ' ) );
941
+ len = $controls.length;
942
+ for ( index = 0; index < len; index++ ) {
943
+ $controls.eq( index )
944
+ .attr( 'aria-disabled', 'true' )
945
+ .addClass( wo.pager_css.disabled )[0].disabled = true;
946
+ }
947
+ },
959
948
 
960
- moveToPage: function(table, p, pageMoved) {
961
- if ( p.isDisabled ) { return; }
962
- if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
963
- return tsp.updateCache(table);
964
- }
965
- var pg, c = table.config,
966
- wo = c.widgetOptions,
967
- l = p.last;
968
-
969
- // abort page move if the table has filters and has not been initialized
970
- if (p.ajax && !wo.filter_initialized && ts.hasWidget(table, 'filter')) { return; }
971
-
972
- tsp.calcFilters(table, c);
973
- pg = Math.min( p.totalPages, p.filteredPages );
974
- if ( p.page < 0 ) { p.page = 0; }
975
- if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
976
-
977
- // fixes issue where one current filter is [] and the other is ['','',''],
978
- // making the next if comparison think the filters as different. Fixes #202.
979
- l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
980
- p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
981
- // don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
982
- if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
983
- (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
984
- // check for ajax url changes see #730
985
- (l.ajaxUrl || '') === (p.ajaxObject.url || '') &&
986
- // & ajax url option changes (dynamically add/remove/rename sort & filter parameters)
987
- (l.optAjaxUrl || '') === (wo.pager_ajaxUrl || '') &&
988
- l.sortList === (c.sortList || []).join(',') ) {
949
+ // updateCache if delayInit: true
950
+ // this is normally done by 'appendToTable' function in the tablesorter core AFTER a sort
951
+ updateCache: function(table) {
952
+ var c = table.config,
953
+ p = c.pager;
954
+ c.$table.trigger('updateCache', [ function(){
955
+ if ( !$.isEmptyObject(table.config.cache) ) {
956
+ var i,
957
+ rows = [],
958
+ n = table.config.cache[0].normalized;
959
+ p.totalRows = n.length;
960
+ for (i = 0; i < p.totalRows; i++) {
961
+ rows.push(n[i][c.columns].$row);
962
+ }
963
+ c.rowsCopy = rows;
964
+ tsp.moveToPage(table, p, true);
965
+ // clear out last search to force an update
966
+ p.last.currentFilters = [ ' ' ];
967
+ }
968
+ } ]);
969
+ },
970
+
971
+ moveToPage: function(table, p, pageMoved) {
972
+ if ( p.isDisabled ) { return; }
973
+ if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
974
+ return tsp.updateCache(table);
975
+ }
976
+ var pg, c = table.config,
977
+ wo = c.widgetOptions,
978
+ l = p.last;
979
+
980
+ // abort page move if the table has filters and has not been initialized
981
+ if (p.ajax && !wo.filter_initialized && ts.hasWidget(table, 'filter')) { return; }
982
+
983
+ tsp.calcFilters(table, c);
984
+ pg = Math.min( p.totalPages, p.filteredPages );
985
+ if ( p.page < 0 ) { p.page = 0; }
986
+ if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
987
+
988
+ // fixes issue where one current filter is [] and the other is [ '', '', '' ],
989
+ // making the next if comparison think the filters as different. Fixes #202.
990
+ l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
991
+ p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
992
+ // don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
993
+ if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
994
+ (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
995
+ // check for ajax url changes see #730
996
+ (l.ajaxUrl || '') === (p.ajaxObject.url || '') &&
997
+ // & ajax url option changes (dynamically add/remove/rename sort & filter parameters)
998
+ (l.optAjaxUrl || '') === (wo.pager_ajaxUrl || '') &&
999
+ l.sortList === (c.sortList || []).join(',') ) {
989
1000
  return;
990
1001
  }
991
- if (c.debug) {
992
- ts.log('Pager: Changing to page ' + p.page);
993
- }
994
- p.last = {
995
- page : p.page,
996
- size : p.size,
997
- // fixes #408; modify sortList otherwise it auto-updates
998
- sortList : (c.sortList || []).join(','),
999
- totalRows : p.totalRows,
1000
- currentFilters : p.currentFilters || [],
1001
- ajaxUrl : p.ajaxObject.url || '',
1002
- optAjaxUrl : wo.pager_ajaxUrl
1003
- };
1004
- if (p.ajax) {
1005
- tsp.getAjax(table, c);
1006
- } else if (!p.ajax) {
1007
- tsp.renderTable(table, c.rowsCopy);
1008
- }
1009
- $.data(table, 'pagerLastPage', p.page);
1010
- if (p.initialized && pageMoved !== false) {
1011
1002
  if (c.debug) {
1012
- ts.log('Pager: Triggering pageMoved');
1003
+ console.log('Pager: Changing to page ' + p.page);
1013
1004
  }
1014
- c.$table
1015
- .trigger('pageMoved', c)
1016
- .trigger('applyWidgets');
1017
- if (!p.ajax && table.isUpdating) {
1005
+ p.last = {
1006
+ page : p.page,
1007
+ size : p.size,
1008
+ // fixes #408; modify sortList otherwise it auto-updates
1009
+ sortList : (c.sortList || []).join(','),
1010
+ totalRows : p.totalRows,
1011
+ currentFilters : p.currentFilters || [],
1012
+ ajaxUrl : p.ajaxObject.url || '',
1013
+ optAjaxUrl : wo.pager_ajaxUrl
1014
+ };
1015
+ if (p.ajax) {
1016
+ tsp.getAjax(table, c);
1017
+ } else if (!p.ajax) {
1018
+ tsp.renderTable(table, c.rowsCopy);
1019
+ }
1020
+ $.data(table, 'pagerLastPage', p.page);
1021
+ if (p.initialized && pageMoved !== false) {
1018
1022
  if (c.debug) {
1019
- ts.log('Pager: Triggering updateComplete');
1023
+ console.log('Pager: Triggering pageMoved');
1024
+ }
1025
+ c.$table
1026
+ .trigger('pageMoved', c)
1027
+ .trigger('applyWidgets');
1028
+ if (!p.ajax && table.isUpdating) {
1029
+ if (c.debug) {
1030
+ console.log('Pager: Triggering updateComplete');
1031
+ }
1032
+ c.$table.trigger('updateComplete', [ table, true ]);
1020
1033
  }
1021
- c.$table.trigger('updateComplete', [ table, true ]);
1022
1034
  }
1023
- }
1024
- },
1025
-
1026
- setPageSize: function(table, size, c) {
1027
- var p = c.pager;
1028
- p.size = size || p.size || p.setSize || 10;
1029
- p.$size.val(p.size);
1030
- $.data(table, 'pagerLastPage', p.page);
1031
- $.data(table, 'pagerLastSize', p.size);
1032
- p.totalPages = Math.ceil( p.totalRows / p.size );
1033
- p.filteredPages = Math.ceil( p.filteredRows / p.size );
1034
- tsp.moveToPage(table, p, true);
1035
- },
1036
-
1037
- moveToFirstPage: function(table, p) {
1038
- p.page = 0;
1039
- tsp.moveToPage(table, p, true);
1040
- },
1041
-
1042
- moveToLastPage: function(table, p) {
1043
- p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
1044
- tsp.moveToPage(table, p, true);
1045
- },
1046
-
1047
- moveToNextPage: function(table, p) {
1048
- p.page++;
1049
- if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
1050
- p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
1051
- }
1052
- tsp.moveToPage(table, p, true);
1053
- },
1035
+ },
1036
+
1037
+ setPageSize: function(table, size, c) {
1038
+ var p = c.pager;
1039
+ p.size = size || p.size || p.setSize || 10;
1040
+ p.$size.val(p.size);
1041
+ $.data(table, 'pagerLastPage', p.page);
1042
+ $.data(table, 'pagerLastSize', p.size);
1043
+ p.totalPages = Math.ceil( p.totalRows / p.size );
1044
+ p.filteredPages = Math.ceil( p.filteredRows / p.size );
1045
+ tsp.moveToPage(table, p, true);
1046
+ },
1054
1047
 
1055
- moveToPrevPage: function(table, p) {
1056
- p.page--;
1057
- if ( p.page <= 0 ) {
1048
+ moveToFirstPage: function(table, p) {
1058
1049
  p.page = 0;
1059
- }
1060
- tsp.moveToPage(table, p, true);
1061
- },
1062
-
1063
- destroyPager: function(table, c, refreshing){
1064
- var p = c.pager;
1065
- p.initialized = false;
1066
- c.$table.off( $.trim(p.events.split(' ').join('.pager ')) );
1067
- if (refreshing) { return; }
1068
- tsp.showAllRows(table, c);
1069
- p.$container.hide(); // hide pager
1070
- c.appender = null; // remove pager appender function
1071
- delete table.config.rowsCopy;
1072
- if (ts.storage) {
1073
- ts.storage(table, c.widgetOptions.pager_storageKey, '');
1074
- }
1075
- },
1076
-
1077
- enablePager: function(table, c, triggered){
1078
- var info, p = c.pager;
1079
- p.isDisabled = false;
1080
- p.page = $.data(table, 'pagerLastPage') || p.page || 0;
1081
- p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || p.setSize || 10;
1082
- p.$size.val(p.size); // set page size
1083
- p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
1084
- c.$table.removeClass('pagerDisabled');
1085
- // if table id exists, include page display with aria info
1086
- if ( table.id ) {
1087
- info = table.id + '_pager_info';
1088
- p.$container.find(c.widgetOptions.pager_selectors.pageDisplay).attr('id', info);
1089
- c.$table.attr('aria-describedby', info);
1090
- }
1091
- tsp.changeHeight(table, c);
1092
- if ( triggered ) {
1093
- c.$table.trigger('updateRows');
1094
- tsp.setPageSize(table, p.size, c);
1095
- tsp.hideRowsSetup(table, c);
1096
- if (c.debug) {
1097
- ts.log('Pager: Enabled');
1050
+ tsp.moveToPage(table, p, true);
1051
+ },
1052
+
1053
+ moveToLastPage: function(table, p) {
1054
+ p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
1055
+ tsp.moveToPage(table, p, true);
1056
+ },
1057
+
1058
+ moveToNextPage: function(table, p) {
1059
+ p.page++;
1060
+ if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
1061
+ p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
1098
1062
  }
1099
- }
1100
- },
1101
-
1102
- appender: function(table, rows) {
1103
- var c = table.config,
1104
- wo = c.widgetOptions,
1105
- p = c.pager;
1106
- if ( !p.ajax ) {
1107
- c.rowsCopy = rows;
1108
- p.totalRows = wo.pager_countChildRows ? c.$tbodies.eq(0).children('tr').length : rows.length;
1109
- p.size = $.data(table, 'pagerLastSize') || p.size || wo.pager_size || p.setSize || 10;
1110
- p.totalPages = Math.ceil( p.totalRows / p.size );
1111
- tsp.moveToPage(table, p);
1112
- // update display here in case all rows are removed
1113
- tsp.updatePageDisplay(table, c, false);
1114
- } else {
1115
1063
  tsp.moveToPage(table, p, true);
1116
- }
1117
- }
1118
-
1119
- };
1120
-
1121
- // see #486
1122
- ts.showError = function( table, message ) {
1123
- var index, $row, c, wo, errorRow,
1124
- $table = $( table ),
1125
- len = $table.length;
1126
- for ( index = 0; index < len; index++ ) {
1127
- c = $table[ index ].config;
1128
- if ( c ) {
1129
- wo = c.widgetOptions;
1130
- errorRow = c.pager && c.pager.cssErrorRow || wo.pager_css && wo.pager_css.errorRow || 'tablesorter-errorRow';
1131
- if ( typeof message === 'undefined' ) {
1132
- c.$table.find('thead').find(c.selectorRemove).remove();
1064
+ },
1065
+
1066
+ moveToPrevPage: function(table, p) {
1067
+ p.page--;
1068
+ if ( p.page <= 0 ) {
1069
+ p.page = 0;
1070
+ }
1071
+ tsp.moveToPage(table, p, true);
1072
+ },
1073
+
1074
+ destroyPager: function(table, c, refreshing){
1075
+ var p = c.pager,
1076
+ namespace = c.namespace + 'pager';
1077
+ p.initialized = false;
1078
+ c.$table.off( $.trim(p.events.split(' ').join(namespace + ' ')) );
1079
+ if (refreshing) { return; }
1080
+ tsp.showAllRows(table, c);
1081
+ p.$container.hide(); // hide pager
1082
+ c.appender = null; // remove pager appender function
1083
+ delete table.config.rowsCopy;
1084
+ if (ts.storage) {
1085
+ ts.storage(table, c.widgetOptions.pager_storageKey, '');
1086
+ }
1087
+ },
1088
+
1089
+ enablePager: function(table, c, triggered){
1090
+ var info, p = c.pager;
1091
+ p.isDisabled = false;
1092
+ p.page = $.data(table, 'pagerLastPage') || p.page || 0;
1093
+ p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || p.setSize || 10;
1094
+ p.$size.val(p.size); // set page size
1095
+ p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
1096
+ c.$table.removeClass('pagerDisabled');
1097
+ // if table id exists, include page display with aria info
1098
+ if ( table.id ) {
1099
+ info = table.id + '_pager_info';
1100
+ p.$container.find(c.widgetOptions.pager_selectors.pageDisplay).attr('id', info);
1101
+ c.$table.attr('aria-describedby', info);
1102
+ }
1103
+ tsp.changeHeight(table, c);
1104
+ if ( triggered ) {
1105
+ c.$table.trigger('updateRows');
1106
+ tsp.setPageSize(table, p.size, c);
1107
+ tsp.hideRowsSetup(table, c);
1108
+ if (c.debug) {
1109
+ console.log('Pager: Enabled');
1110
+ }
1111
+ }
1112
+ },
1113
+
1114
+ appender: function(table, rows) {
1115
+ var c = table.config,
1116
+ wo = c.widgetOptions,
1117
+ p = c.pager;
1118
+ if ( !p.ajax ) {
1119
+ c.rowsCopy = rows;
1120
+ p.totalRows = wo.pager_countChildRows ? c.$tbodies.eq(0).children('tr').length : rows.length;
1121
+ p.size = $.data(table, 'pagerLastSize') || p.size || wo.pager_size || p.setSize || 10;
1122
+ p.totalPages = Math.ceil( p.totalRows / p.size );
1123
+ tsp.moveToPage(table, p);
1124
+ // update display here in case all rows are removed
1125
+ tsp.updatePageDisplay(table, c, false);
1133
1126
  } else {
1134
- $row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
1135
- .click(function(){
1136
- $(this).remove();
1137
- })
1138
- // add error row to thead instead of tbody, or clicking on the header will result in a parser error
1139
- .appendTo( c.$table.find('thead:first') )
1140
- .addClass( errorRow + ' ' + c.selectorRemove.slice(1) )
1141
- .attr({
1142
- role : 'alert',
1143
- 'aria-live' : 'assertive'
1144
- });
1127
+ tsp.moveToPage(table, p, true);
1128
+ }
1129
+ }
1130
+
1131
+ };
1132
+
1133
+ // see #486
1134
+ ts.showError = function( table, message ) {
1135
+ var index, $row, c, wo, errorRow,
1136
+ $table = $( table ),
1137
+ len = $table.length;
1138
+ for ( index = 0; index < len; index++ ) {
1139
+ c = $table[ index ].config;
1140
+ if ( c ) {
1141
+ wo = c.widgetOptions;
1142
+ errorRow = c.pager && c.pager.cssErrorRow || wo.pager_css && wo.pager_css.errorRow || 'tablesorter-errorRow';
1143
+ if ( typeof message === 'undefined' ) {
1144
+ c.$table.find('thead').find(c.selectorRemove).remove();
1145
+ } else {
1146
+ $row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
1147
+ .click(function(){
1148
+ $(this).remove();
1149
+ })
1150
+ // add error row to thead instead of tbody, or clicking on the header will result in a parser error
1151
+ .appendTo( c.$table.find('thead:first') )
1152
+ .addClass( errorRow + ' ' + c.selectorRemove.slice(1) )
1153
+ .attr({
1154
+ role : 'alert',
1155
+ 'aria-live' : 'assertive'
1156
+ });
1157
+ }
1145
1158
  }
1146
1159
  }
1147
- }
1148
- };
1160
+ };
1149
1161
 
1150
1162
  })(jQuery);