jquery-tablesorter 1.10.10 → 1.11.0
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +47 -18
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +206 -167
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter-select2.js +134 -0
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter.js +69 -67
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +98 -51
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +82 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +17 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +359 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +272 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +49 -18
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +179 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +18 -45
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +123 -0
- metadata +8 -2
@@ -0,0 +1,272 @@
|
|
1
|
+
/* Output widget (beta) for TableSorter 4/14/2014 (v2.16.0)
|
2
|
+
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
|
+
* Modified from:
|
4
|
+
* HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
|
5
|
+
* Download-File-JS: https://github.com/PixelsCommander/Download-File-JS (http://www.apache.org/licenses/LICENSE-2.0)
|
6
|
+
*/
|
7
|
+
/*jshint browser:true, jquery:true, unused:false */
|
8
|
+
/*global jQuery: false */
|
9
|
+
;(function($){
|
10
|
+
"use strict";
|
11
|
+
|
12
|
+
var ts = $.tablesorter,
|
13
|
+
|
14
|
+
output = ts.output = {
|
15
|
+
|
16
|
+
event : 'outputTable',
|
17
|
+
|
18
|
+
// wrap line breaks & tabs in quotes
|
19
|
+
regexQuote : /([\n\t]|<[^<]+>)/, // test
|
20
|
+
regexBR : /(<br([\s\/])?>|\n)/g, // replace
|
21
|
+
regexIMG : /<img[^>]+alt\s*=\s*['"]([^'"]+)['"][^>]*>/i, // match
|
22
|
+
regexHTML : /<[^<]+>/g, // replace
|
23
|
+
|
24
|
+
replaceCR : '\\n',
|
25
|
+
replaceTab : '\\t',
|
26
|
+
|
27
|
+
popupTitle : 'Output',
|
28
|
+
popupStyle : 'width:100%;height:100%;', // for textarea
|
29
|
+
message : 'Your device does not support downloading. Please try again in desktop browser.',
|
30
|
+
|
31
|
+
init : function(c) {
|
32
|
+
c.$table
|
33
|
+
.off(output.event)
|
34
|
+
.on(output.event, function(){
|
35
|
+
// explicitly use table.config.widgetOptions because we want
|
36
|
+
// the most up-to-date values; not the "wo" from initialization
|
37
|
+
output.process(c, c.widgetOptions);
|
38
|
+
});
|
39
|
+
},
|
40
|
+
|
41
|
+
processRow: function(c, $rows, isHeader, isJSON) {
|
42
|
+
var $this, row, col, rowlen, collen, txt,
|
43
|
+
wo = c.widgetOptions,
|
44
|
+
tmpRow = [],
|
45
|
+
addSpanIndex = isHeader && isJSON && wo.output_headerRows && $.isFunction(wo.output_callbackJSON),
|
46
|
+
rowIndex = 0,
|
47
|
+
cellIndex = 0;
|
48
|
+
$rows.each(function(rowIndex) {
|
49
|
+
if (!tmpRow[rowIndex]) { tmpRow[rowIndex] = []; }
|
50
|
+
cellIndex = 0;
|
51
|
+
$(this).children().each(function(){
|
52
|
+
$this = $(this);
|
53
|
+
// process rowspans
|
54
|
+
if ($this.filter('[rowspan]').length) {
|
55
|
+
rowlen = parseInt( $this.attr('rowspan'), 10) - 1;
|
56
|
+
txt = output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
|
57
|
+
for (row = 1; row <= rowlen; row++) {
|
58
|
+
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
|
59
|
+
tmpRow[rowIndex + row][cellIndex] = txt;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
// process colspans
|
63
|
+
if ($this.filter('[colspan]').length) {
|
64
|
+
collen = parseInt( $this.attr('colspan'), 10) - 1;
|
65
|
+
txt = output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
|
66
|
+
for (col = 1; col <= collen; col++) {
|
67
|
+
// if we're processing the header & making JSON, the header names need to be unique
|
68
|
+
if ($this.filter('[rowspan]').length) {
|
69
|
+
rowlen = parseInt( $this.attr('rowspan'), 10);
|
70
|
+
for (row = 0; row < rowlen; row++) {
|
71
|
+
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
|
72
|
+
tmpRow[rowIndex + row][cellIndex + col] = addSpanIndex ?
|
73
|
+
wo.output_callbackJSON($this, txt, cellIndex + col) || txt + '(' + (cellIndex + col) + ')' : txt;
|
74
|
+
}
|
75
|
+
} else {
|
76
|
+
tmpRow[rowIndex][cellIndex + col] = addSpanIndex ?
|
77
|
+
wo.output_callbackJSON($this, txt, cellIndex + col) || txt + '(' + (cellIndex + col) + ')' : txt;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
// don't include hidden columns
|
83
|
+
if ( $this.css('display') !== 'none' ) {
|
84
|
+
// skip column if already defined
|
85
|
+
while (tmpRow[rowIndex][cellIndex]) { cellIndex++; }
|
86
|
+
tmpRow[rowIndex][cellIndex] = tmpRow[rowIndex][cellIndex] ||
|
87
|
+
output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
|
88
|
+
cellIndex++;
|
89
|
+
}
|
90
|
+
});
|
91
|
+
});
|
92
|
+
return tmpRow;
|
93
|
+
},
|
94
|
+
|
95
|
+
process : function(c, wo) {
|
96
|
+
var mydata, $this, $rows, headers, csvData, len,
|
97
|
+
hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
|
98
|
+
indx = 0,
|
99
|
+
tmpData = (wo.output_separator || ',').toLowerCase(),
|
100
|
+
outputJSON = tmpData === 'json',
|
101
|
+
outputArray = tmpData === 'array',
|
102
|
+
separator = outputJSON || outputArray ? ',' : wo.output_separator,
|
103
|
+
$el = c.$table;
|
104
|
+
// regex to look for the set separator or HTML
|
105
|
+
wo.output_regex = new RegExp('(' + (/\\/.test(separator) ? '\\' : '' ) + separator + ')' );
|
106
|
+
|
107
|
+
// get header cells
|
108
|
+
$this = $el.find('thead tr:visible').not('.' + (ts.css.filterRow || 'tablesorter-filter-row') );
|
109
|
+
headers = output.processRow(c, $this, true, outputJSON);
|
110
|
+
|
111
|
+
// all tbody rows
|
112
|
+
$rows = $el.children('tbody').children('tr');
|
113
|
+
// get (f)iltered, (v)isible or all rows (look for the first letter only)
|
114
|
+
$rows = /f/.test(wo.output_saveRows) ? $rows.not('.' + (wo.filter_filteredRow || 'filtered') ) :
|
115
|
+
/v/.test(wo.output_saveRows) ? $rows.filter(':visible') : $rows;
|
116
|
+
|
117
|
+
// process to array of arrays
|
118
|
+
csvData = output.processRow(c, $rows);
|
119
|
+
len = headers.length;
|
120
|
+
|
121
|
+
if (outputJSON) {
|
122
|
+
tmpData = [];
|
123
|
+
$.each( csvData, function(indx, val){
|
124
|
+
// multiple header rows & output_headerRows = true, pick the last row...
|
125
|
+
tmpData.push( output.row2Hash( headers[ (len > 1 && wo.output_headerRows) ? indx % len : len - 1], val ) );
|
126
|
+
});
|
127
|
+
// requires JSON stringify; if it doesn't exist, the output will show [object Object],... in the output window
|
128
|
+
mydata = hasStringify ? JSON.stringify(tmpData) : tmpData;
|
129
|
+
} else {
|
130
|
+
tmpData = output.row2CSV(wo, wo.output_headerRows ? headers : [ headers[ (len > 1 && wo.output_headerRows) ? indx % len : len - 1] ], outputArray)
|
131
|
+
.concat( output.row2CSV(wo, csvData, outputArray) );
|
132
|
+
// stringify the array; if stringify doesn't exist the array will be flattened
|
133
|
+
mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
|
134
|
+
}
|
135
|
+
|
136
|
+
// callback; if true returned, continue processing
|
137
|
+
if (!wo.output_callback(mydata)) { return; }
|
138
|
+
|
139
|
+
if ( /p/.test( (wo.output_delivery || '').toLowerCase() ) ) {
|
140
|
+
output.popup(mydata, wo.output_popupStyle, outputJSON || outputArray);
|
141
|
+
} else {
|
142
|
+
output.download(wo, mydata);
|
143
|
+
}
|
144
|
+
|
145
|
+
}, // end process
|
146
|
+
|
147
|
+
row2CSV : function(wo, tmpRow, outputArray) {
|
148
|
+
var tmp, rowIndex,
|
149
|
+
csvData = [],
|
150
|
+
rowLen = tmpRow.length;
|
151
|
+
for (rowIndex = 0; rowIndex < rowLen; rowIndex++) {
|
152
|
+
// remove any blank rows
|
153
|
+
tmp = tmpRow[rowIndex].join('').replace(/\"/g,'');
|
154
|
+
if (tmpRow[rowIndex].length > 0 && tmp !== '') {
|
155
|
+
csvData[csvData.length] = outputArray ? tmpRow[rowIndex] : tmpRow[rowIndex].join(wo.output_separator);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
return csvData;
|
159
|
+
},
|
160
|
+
|
161
|
+
row2Hash : function(keys, values) {
|
162
|
+
var json = {};
|
163
|
+
$.each(values, function(indx, val) {
|
164
|
+
if ( indx < keys.length ) {
|
165
|
+
json[ keys[indx] ] = val;
|
166
|
+
}
|
167
|
+
});
|
168
|
+
return json;
|
169
|
+
},
|
170
|
+
|
171
|
+
formatData : function(wo, input, isHeader) {
|
172
|
+
var txt,
|
173
|
+
quotes = (wo.output_separator || ',').toLowerCase(),
|
174
|
+
separator = quotes === 'json' || quotes === 'array',
|
175
|
+
// replace " with “ if undefined
|
176
|
+
result = input.replace(/\"/g, wo.output_replaceQuote || '\u201c');
|
177
|
+
// replace line breaks with \\n & tabs with \\t
|
178
|
+
result = result.replace(output.regexBR, output.replaceCR).replace(/\t/g, output.replaceTab);
|
179
|
+
// extract img alt text
|
180
|
+
txt = result.match(output.regexIMG);
|
181
|
+
if (!wo.output_includeHTML && txt !== null) {
|
182
|
+
result = txt[1];
|
183
|
+
}
|
184
|
+
// replace/remove html
|
185
|
+
result = wo.output_includeHTML && !isHeader ? result : result.replace(output.regexHTML, '');
|
186
|
+
result = wo.output_trimSpaces || isHeader ? $.trim(result) : result;
|
187
|
+
// JSON & array outputs don't need quotes
|
188
|
+
quotes = separator ? false : wo.output_wrapQuotes || wo.output_regex.test(result) || output.regexQuote.test(result);
|
189
|
+
return quotes ? '"' + result + '"' : result;
|
190
|
+
},
|
191
|
+
|
192
|
+
popup : function(data, style, wrap) {
|
193
|
+
var generator = window.open('', output.popupTitle, style);
|
194
|
+
generator.document.write(
|
195
|
+
'<html><head><title>' + output.popupTitle + '</title></head><body>' +
|
196
|
+
'<textarea wrap="' + (wrap ? 'on' : 'off') + '" style="' + output.popupStyle + '">' + data + '\n</textarea>' +
|
197
|
+
'</body></html>'
|
198
|
+
);
|
199
|
+
generator.document.close();
|
200
|
+
generator.focus();
|
201
|
+
// select all text and focus within the textarea in the popup
|
202
|
+
// $(generator.document).find('textarea').select().focus();
|
203
|
+
return true;
|
204
|
+
},
|
205
|
+
|
206
|
+
// modified from https://github.com/PixelsCommander/Download-File-JS
|
207
|
+
download : function (wo, data){
|
208
|
+
var e, link,
|
209
|
+
processedData = 'data:text/csv;charset=utf8,' + encodeURIComponent(data);
|
210
|
+
|
211
|
+
// iOS devices do not support downloading. We have to inform user about this.
|
212
|
+
if (/(iP)/g.test(navigator.userAgent)) {
|
213
|
+
alert(output.message);
|
214
|
+
return false;
|
215
|
+
}
|
216
|
+
// If in Chrome or Safari - download via virtual link click
|
217
|
+
if ( /(chrome|safari)/.test(navigator.userAgent.toLowerCase()) ) {
|
218
|
+
// Creating new link node.
|
219
|
+
link = document.createElement('a');
|
220
|
+
link.href = processedData;
|
221
|
+
link.download = wo.output_saveFileName;
|
222
|
+
// Dispatching click event.
|
223
|
+
if (document.createEvent) {
|
224
|
+
e = document.createEvent('MouseEvents');
|
225
|
+
e.initEvent('click', true, true);
|
226
|
+
link.dispatchEvent(e);
|
227
|
+
return true;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
// Force file download (whether supported by server).
|
231
|
+
processedData += '?download';
|
232
|
+
window.open(processedData, '_self');
|
233
|
+
return true;
|
234
|
+
},
|
235
|
+
|
236
|
+
remove : function(c) {
|
237
|
+
c.$table.off(output.event);
|
238
|
+
}
|
239
|
+
|
240
|
+
};
|
241
|
+
|
242
|
+
ts.addWidget({
|
243
|
+
id: "output",
|
244
|
+
options: {
|
245
|
+
output_separator : ',', // set to "json", "array" or any separator
|
246
|
+
output_dataAttrib : 'data-name', // header attrib containing modified header name
|
247
|
+
output_headerRows : false, // if true, include multiple header rows (JSON only)
|
248
|
+
output_delivery : 'popup', // popup, download
|
249
|
+
output_saveRows : 'filtered', // all, visible or filtered
|
250
|
+
output_replaceQuote : '\u201c;', // left double quote
|
251
|
+
output_includeHTML : false,
|
252
|
+
output_trimSpaces : true,
|
253
|
+
output_wrapQuotes : false,
|
254
|
+
output_popupStyle : 'width=500,height=300',
|
255
|
+
output_saveFileName : 'mytable.csv',
|
256
|
+
// callback executed when processing completes
|
257
|
+
// return true to continue download/output
|
258
|
+
// return false to stop delivery & do something else with the data
|
259
|
+
output_callback : function(data){ return true; },
|
260
|
+
// JSON callback executed when a colspan is encountered in the header
|
261
|
+
output_callbackJSON : function($cell, txt, cellIndex) { return txt + '(' + (cellIndex + col) + ')'; }
|
262
|
+
},
|
263
|
+
init: function(table, thisWidget, c) {
|
264
|
+
output.init(c);
|
265
|
+
},
|
266
|
+
remove: function(table, c){
|
267
|
+
output.remove(c);
|
268
|
+
}
|
269
|
+
|
270
|
+
});
|
271
|
+
|
272
|
+
})(jQuery);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Pager widget (beta) for TableSorter 4/
|
1
|
+
/* Pager widget (beta) for TableSorter 4/23/2014 (v2.16.0) */
|
2
2
|
/*jshint browser:true, jquery:true, unused:false */
|
3
3
|
;(function($){
|
4
4
|
"use strict";
|
@@ -19,6 +19,10 @@ ts.addWidget({
|
|
19
19
|
// starting page of the pager (zero based index)
|
20
20
|
pager_startPage: 0,
|
21
21
|
|
22
|
+
// reset pager after filtering; set to desired page #
|
23
|
+
// set to false to not change page at filter start
|
24
|
+
pager_pageReset: 0,
|
25
|
+
|
22
26
|
// Number of visible rows
|
23
27
|
pager_size: 10,
|
24
28
|
|
@@ -164,6 +168,10 @@ tsp = ts.pager = {
|
|
164
168
|
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
|
165
169
|
$.data(table, 'pagerLastSize', p.size);
|
166
170
|
}
|
171
|
+
|
172
|
+
// skipped rows
|
173
|
+
p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.substring(1) + '|' + c.cssChildRow + ')');
|
174
|
+
|
167
175
|
// clear initialized flag
|
168
176
|
p.initialized = false;
|
169
177
|
// before initialization event
|
@@ -210,13 +218,17 @@ tsp = ts.pager = {
|
|
210
218
|
.unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
|
211
219
|
.bind('filterStart.pager', function(e, filters) {
|
212
220
|
p.currentFilters = filters;
|
213
|
-
|
221
|
+
// don't change page is filters are the same (pager updating, etc)
|
222
|
+
if (wo.pager_pageReset !== false && (c.lastCombinedFilter || '') !== (filters || []).join('')) {
|
223
|
+
p.page = wo.pager_pageReset; // fixes #456 & #565
|
224
|
+
}
|
214
225
|
})
|
215
226
|
// update pager after filter widget completes
|
216
227
|
.bind('filterEnd.pager sortEnd.pager', function() {
|
217
228
|
if (p.initialized) {
|
218
|
-
|
229
|
+
// update page display first, so we update p.filteredPages
|
219
230
|
tsp.updatePageDisplay(table, c, false);
|
231
|
+
tsp.moveToPage(table, p, false);
|
220
232
|
tsp.fixHeight(table, c);
|
221
233
|
}
|
222
234
|
})
|
@@ -315,17 +327,25 @@ tsp = ts.pager = {
|
|
315
327
|
},
|
316
328
|
|
317
329
|
updatePageDisplay: function(table, c, completed) {
|
318
|
-
var i, pg, s, out,
|
330
|
+
var i, pg, s, out, regex,
|
319
331
|
wo = c.widgetOptions,
|
320
332
|
p = c.pager,
|
321
333
|
f = c.$table.hasClass('hasFilters') && !wo.pager_ajaxUrl,
|
322
|
-
t =
|
323
|
-
(wo.pager_countChildRows ? '' : ',.' + c.cssChildRow),
|
334
|
+
t = [],
|
324
335
|
sz = p.size || 10; // don't allow dividing by zero
|
336
|
+
t = [ wo && wo.filter_filteredRow || 'filtered', c.selectorRemove ];
|
337
|
+
if (wo.pager_countChildRows) { t.push(c.cssChildRow); }
|
338
|
+
regex = new RegExp( '(' + t.join('|') + ')' );
|
325
339
|
p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
|
326
340
|
p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
|
327
|
-
p.filteredRows = (f) ?
|
328
|
-
p.filteredPages =
|
341
|
+
p.filteredRows = (f) ? 0 : p.totalRows;
|
342
|
+
p.filteredPages = p.totalPages;
|
343
|
+
if (f) {
|
344
|
+
$.each(c.cache[0].normalized, function(i, el) {
|
345
|
+
p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
|
346
|
+
});
|
347
|
+
p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
|
348
|
+
}
|
329
349
|
if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
|
330
350
|
t = (p.size * p.page > p.filteredRows);
|
331
351
|
p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
|
@@ -579,9 +599,9 @@ tsp = ts.pager = {
|
|
579
599
|
}
|
580
600
|
tsp.renderAjax(data, table, c);
|
581
601
|
$doc.unbind('ajaxError.pager');
|
582
|
-
|
583
|
-
|
584
|
-
|
602
|
+
if (typeof p.oldAjaxSuccess === 'function') {
|
603
|
+
p.oldAjaxSuccess(data);
|
604
|
+
}
|
585
605
|
};
|
586
606
|
if (c.debug) {
|
587
607
|
ts.log('ajax initialized', wo.pager_ajaxObject);
|
@@ -632,13 +652,14 @@ tsp = ts.pager = {
|
|
632
652
|
},
|
633
653
|
|
634
654
|
renderTable: function(table, rows) {
|
635
|
-
var
|
655
|
+
var $tb, index, count, added,
|
636
656
|
c = table.config,
|
637
657
|
p = c.pager,
|
638
658
|
wo = c.widgetOptions,
|
659
|
+
f = c.$table.hasClass('hasFilters'),
|
639
660
|
l = rows && rows.length || 0, // rows may be undefined
|
640
661
|
s = ( p.page * p.size ),
|
641
|
-
e =
|
662
|
+
e = p.size;
|
642
663
|
if ( l < 1 ) { return; } // empty table, abort!
|
643
664
|
if ( p.page >= p.totalPages ) {
|
644
665
|
// lets not render the table more than once
|
@@ -650,13 +671,22 @@ tsp = ts.pager = {
|
|
650
671
|
if ( !wo.pager_removeRows ) {
|
651
672
|
tsp.hideRows(table, c);
|
652
673
|
} else {
|
653
|
-
if ( e > rows.length ) {
|
654
|
-
e = rows.length;
|
655
|
-
}
|
656
674
|
ts.clearTableBody(table);
|
657
675
|
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
|
658
|
-
|
659
|
-
|
676
|
+
// not filtered, start from the calculated starting point (s)
|
677
|
+
// if filtered, start from zero
|
678
|
+
index = f ? 0 : s;
|
679
|
+
count = f ? 0 : s;
|
680
|
+
added = 0;
|
681
|
+
while (added < e && index < rows.length) {
|
682
|
+
if (!f || !/filtered/.test(rows[index][0].className)){
|
683
|
+
count++;
|
684
|
+
if (count > s && added <= e) {
|
685
|
+
added++;
|
686
|
+
$tb.append(rows[index]);
|
687
|
+
}
|
688
|
+
}
|
689
|
+
index++;
|
660
690
|
}
|
661
691
|
ts.processTbody(table, $tb, false);
|
662
692
|
}
|
@@ -785,6 +815,7 @@ tsp = ts.pager = {
|
|
785
815
|
p.$container.hide(); // hide pager
|
786
816
|
c.appender = null; // remove pager appender function
|
787
817
|
p.initialized = false;
|
818
|
+
delete table.config.rowsCopy;
|
788
819
|
c.$table.unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
|
789
820
|
if (ts.storage) {
|
790
821
|
ts.storage(table, c.widgetOptions.pager_storageKey, '');
|
@@ -0,0 +1,179 @@
|
|
1
|
+
/* table reflow widget (beta) for TableSorter 3/22/2014 (v2.16.0)
|
2
|
+
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
|
+
* Also, this widget requires the following default css (modify as desired)
|
4
|
+
|
5
|
+
/ * REQUIRED CSS: change your reflow breakpoint here (35em below) * /
|
6
|
+
@media ( max-width: 35em ) {
|
7
|
+
.ui-table-reflow td,
|
8
|
+
.ui-table-reflow th {
|
9
|
+
-webkit-box-sizing: border-box;
|
10
|
+
-moz-box-sizing: border-box;
|
11
|
+
box-sizing: border-box;
|
12
|
+
float: right;
|
13
|
+
/ * if not using the stickyHeaders widget (not the css3 version)
|
14
|
+
* the "!important" flag, and "height: auto" can be removed * /
|
15
|
+
width: 100% !important;
|
16
|
+
height: auto !important;
|
17
|
+
}
|
18
|
+
/ * reflow widget * /
|
19
|
+
.ui-table-reflow tbody td[data-title]:before {
|
20
|
+
color: #469;
|
21
|
+
font-size: .9em;
|
22
|
+
content: attr(data-title);
|
23
|
+
float: left;
|
24
|
+
width: 50%;
|
25
|
+
white-space: pre-wrap;
|
26
|
+
text-align: bottom;
|
27
|
+
display: inline-block;
|
28
|
+
}
|
29
|
+
/ * reflow2 widget * /
|
30
|
+
table.ui-table-reflow .ui-table-cell-label.ui-table-cell-label-top {
|
31
|
+
display: block;
|
32
|
+
padding: .4em 0;
|
33
|
+
margin: .4em 0;
|
34
|
+
text-transform: uppercase;
|
35
|
+
font-size: .9em;
|
36
|
+
font-weight: 400;
|
37
|
+
}
|
38
|
+
table.ui-table-reflow .ui-table-cell-label {
|
39
|
+
padding: .4em;
|
40
|
+
min-width: 30%;
|
41
|
+
display: inline-block;
|
42
|
+
margin: -.4em 1em -.4em -.4em;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
.ui-table-reflow .ui-table-cell-label {
|
46
|
+
display: none;
|
47
|
+
}
|
48
|
+
|
49
|
+
*/
|
50
|
+
/*jshint browser:true, jquery:true, unused:false */
|
51
|
+
/*global jQuery: false */
|
52
|
+
;(function($){
|
53
|
+
"use strict";
|
54
|
+
|
55
|
+
var ts = $.tablesorter,
|
56
|
+
|
57
|
+
tablereflow = {
|
58
|
+
// simple reflow
|
59
|
+
// add data-attribute to each cell which shows when media query is active
|
60
|
+
// this widget DOES NOT WORK on a table with multiple thead rows
|
61
|
+
init : function(table, c, wo) {
|
62
|
+
var $this,
|
63
|
+
title = wo.reflow_dataAttrib,
|
64
|
+
header = wo.reflow_headerAttrib,
|
65
|
+
headers = [];
|
66
|
+
c.$table
|
67
|
+
.addClass(wo.reflow_className)
|
68
|
+
.off('refresh.tsreflow updateComplete.tsreflow2')
|
69
|
+
// emulate jQuery Mobile refresh
|
70
|
+
// https://api.jquerymobile.com/table-reflow/#method-refresh
|
71
|
+
.on('refresh.tsreflow updateComplete.tsreflow2', function(){
|
72
|
+
tablereflow.init(table, c, wo);
|
73
|
+
});
|
74
|
+
c.$headers.each(function(){
|
75
|
+
$this = $(this);
|
76
|
+
headers.push( $this.attr(header) || $this.text() );
|
77
|
+
});
|
78
|
+
c.$tbodies.children().each(function(){
|
79
|
+
$(this).children().each(function(i){
|
80
|
+
$(this).attr(title, headers[i]);
|
81
|
+
});
|
82
|
+
});
|
83
|
+
},
|
84
|
+
init2: function(table, c, wo) {
|
85
|
+
var $this, $tbody, i, $hdr, txt, len,
|
86
|
+
cols = c.columns,
|
87
|
+
header = wo.reflow2_headerAttrib,
|
88
|
+
headers = [];
|
89
|
+
c.$table
|
90
|
+
.addClass(wo.reflow2_className)
|
91
|
+
.off('refresh.tsreflow2 updateComplete.tsreflow2')
|
92
|
+
// emulate jQuery Mobile refresh
|
93
|
+
// https://api.jquerymobile.com/table-reflow/#method-refresh
|
94
|
+
.on('refresh.tsreflow2 updateComplete.tsreflow2', function(){
|
95
|
+
tablereflow.init2(table, c, wo);
|
96
|
+
});
|
97
|
+
|
98
|
+
// add <b> to every table cell with thead cell contents
|
99
|
+
for (i = 0; i < cols; i++) {
|
100
|
+
$hdr = c.$headers.filter('[data-column="' + i + '"]');
|
101
|
+
if ($hdr.length > 1) {
|
102
|
+
txt = [];
|
103
|
+
$hdr.each(function(){
|
104
|
+
$this = $(this);
|
105
|
+
if (!$this.hasClass(wo.reflow2_classIgnore)) {
|
106
|
+
txt.push( $this.attr(header) || $this.text() );
|
107
|
+
}
|
108
|
+
});
|
109
|
+
} else {
|
110
|
+
txt = [ $hdr.attr(header) || $hdr.text() ];
|
111
|
+
}
|
112
|
+
headers.push( txt );
|
113
|
+
}
|
114
|
+
// include "remove-me" class so these additional elements are removed before updating
|
115
|
+
txt = '<b class="' + c.selectorRemove.slice(1) + ' ' + wo.reflow2_labelClass;
|
116
|
+
c.$tbodies.children().each(function(){
|
117
|
+
$tbody = ts.processTbody(table, $(this), true);
|
118
|
+
$tbody.children().each(function(j){
|
119
|
+
$this = $(this);
|
120
|
+
len = headers[j].length
|
121
|
+
i = len - 1;
|
122
|
+
while (i >= 0) {
|
123
|
+
$this.prepend(txt + (i === 0 && len > 1 ? ' ' + wo.reflow2_labelTop : '') + '">' + headers[j][i] + '</b>');
|
124
|
+
i--;
|
125
|
+
}
|
126
|
+
});
|
127
|
+
ts.processTbody(table, $tbody, false);
|
128
|
+
});
|
129
|
+
},
|
130
|
+
remove : function(table, c, wo) {
|
131
|
+
c.$table.removeClass(wo.reflow_className);
|
132
|
+
},
|
133
|
+
remove2 : function(table, c, wo) {
|
134
|
+
c.$table.removeClass(wo.reflow2_className);
|
135
|
+
}
|
136
|
+
};
|
137
|
+
|
138
|
+
ts.addWidget({
|
139
|
+
id: "reflow",
|
140
|
+
options: {
|
141
|
+
// class name added to make it responsive (class name within media query)
|
142
|
+
reflow_className : 'ui-table-reflow',
|
143
|
+
// header attribute containing modified header name
|
144
|
+
reflow_headerAttrib : 'data-name',
|
145
|
+
// data attribute added to each tbody cell
|
146
|
+
reflow_dataAttrib : 'data-title'
|
147
|
+
},
|
148
|
+
init: function(table, thisWidget, c, wo) {
|
149
|
+
tablereflow.init(table, c, wo);
|
150
|
+
},
|
151
|
+
remove: function(table, c, wo){
|
152
|
+
tablereflow.remove(table, c, wo);
|
153
|
+
}
|
154
|
+
});
|
155
|
+
|
156
|
+
ts.addWidget({
|
157
|
+
id: "reflow2",
|
158
|
+
options: {
|
159
|
+
// class name added to make it responsive (class name within media query)
|
160
|
+
reflow2_className : 'ui-table-reflow',
|
161
|
+
// ignore header cell content with this class name
|
162
|
+
reflow2_classIgnore : 'ui-table-reflow-ignore',
|
163
|
+
// header attribute containing modified header name
|
164
|
+
reflow2_headerAttrib : 'data-name',
|
165
|
+
// class name applied to thead labels
|
166
|
+
reflow2_labelClass : 'ui-table-cell-label',
|
167
|
+
// class name applied to first row thead label
|
168
|
+
reflow2_labelTop : 'ui-table-cell-label-top'
|
169
|
+
},
|
170
|
+
init: function(table, thisWidget, c, wo) {
|
171
|
+
tablereflow.init2(table, c, wo);
|
172
|
+
},
|
173
|
+
remove: function(table, c, wo){
|
174
|
+
tablereflow.remove2(table, c, wo);
|
175
|
+
}
|
176
|
+
});
|
177
|
+
|
178
|
+
|
179
|
+
})(jQuery);
|