jquery-tablesorter 1.17.2 → 1.17.3

Sign up to get free protection for your applications and to get access to all the features.
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);