jquery-tablesorter 1.12.8 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +115 -67
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +62 -40
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +251 -118
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +48 -24
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-iso8601.js +5 -4
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +16 -10
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-two-digit-year.js +26 -19
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +16 -10
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +7 -4
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +121 -0
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/{parser-ipv6.js → parser-network.js} +66 -17
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +10 -7
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +62 -35
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +197 -174
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +3 -6
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +145 -62
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-repeatheaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +16 -14
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +2 -2
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +4 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.metro-dark.css +4 -4
- metadata +4 -3
data/vendor/assets/javascripts/jquery-tablesorter/parsers/{parser-ipv6.js → parser-network.js}
RENAMED
@@ -1,15 +1,18 @@
|
|
1
|
-
|
2
|
-
* IPv6 Address (ffff:0000:0000:0000:0000:0000:0000:0000)
|
3
|
-
* needs to support short versions like "::8" or "1:2::7:8"
|
4
|
-
* and "::00:192.168.10.184" (embedded IPv4 address)
|
5
|
-
* see http://www.intermapper.com/support/tools/IPV6-Validator.aspx
|
6
|
-
*/
|
1
|
+
/*! Network parsers - IPv4, IPv6 and MAC Addresses - 10/26/2014 (v2.18.0) */
|
7
2
|
/*global jQuery: false */
|
8
3
|
;(function($){
|
9
4
|
"use strict";
|
10
5
|
|
11
|
-
var ts = $.tablesorter
|
6
|
+
var ts = $.tablesorter,
|
7
|
+
ipv4Format,
|
8
|
+
ipv4Is;
|
12
9
|
|
10
|
+
/*! IPv6 Address parser (WIP)
|
11
|
+
* IPv6 Address (ffff:0000:0000:0000:0000:0000:0000:0000)
|
12
|
+
* needs to support short versions like "::8" or "1:2::7:8"
|
13
|
+
* and "::00:192.168.10.184" (embedded IPv4 address)
|
14
|
+
* see http://www.intermapper.com/support/tools/IPV6-Validator.aspx
|
15
|
+
*/
|
13
16
|
$.extend( ts.regex, {}, {
|
14
17
|
ipv4Validate : /((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})/,
|
15
18
|
ipv4Extract : /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/,
|
@@ -20,14 +23,14 @@
|
|
20
23
|
});
|
21
24
|
|
22
25
|
ts.addParser({
|
23
|
-
id:
|
26
|
+
id: 'ipv6Address',
|
24
27
|
is: function(s) {
|
25
28
|
return ts.regex.ipv6Validate.test(s);
|
26
29
|
},
|
27
30
|
format: function(address, table) {
|
28
31
|
// code modified from http://forrst.com/posts/JS_Expand_Abbreviated_IPv6_Addresses-1OR
|
29
32
|
var i, t, sides, groups, groupsPresent,
|
30
|
-
hex = table ? (typeof table ===
|
33
|
+
hex = table ? (typeof table === 'boolean' ? table : table && table.config.ipv6HexFormat || false) : false,
|
31
34
|
fullAddress = '',
|
32
35
|
expandedAddress = '',
|
33
36
|
validGroupCount = 8,
|
@@ -44,23 +47,23 @@
|
|
44
47
|
address = address.replace( ts.regex.ipv4Extract, t );
|
45
48
|
}
|
46
49
|
|
47
|
-
if (address.indexOf(
|
50
|
+
if (address.indexOf('::') == -1) {
|
48
51
|
// All eight groups are present
|
49
52
|
fullAddress = address;
|
50
53
|
} else {
|
51
|
-
// Consecutive groups of zeroes have been collapsed with
|
52
|
-
sides = address.split(
|
54
|
+
// Consecutive groups of zeroes have been collapsed with '::'.
|
55
|
+
sides = address.split('::');
|
53
56
|
groupsPresent = 0;
|
54
57
|
for (i = 0; i < sides.length; i++) {
|
55
|
-
groupsPresent += sides[i].split(
|
58
|
+
groupsPresent += sides[i].split(':').length;
|
56
59
|
}
|
57
|
-
fullAddress += sides[0] +
|
60
|
+
fullAddress += sides[0] + ':';
|
58
61
|
for (i = 0; i < validGroupCount - groupsPresent; i++) {
|
59
|
-
fullAddress +=
|
62
|
+
fullAddress += '0000:';
|
60
63
|
}
|
61
64
|
fullAddress += sides[1];
|
62
65
|
}
|
63
|
-
groups = fullAddress.split(
|
66
|
+
groups = fullAddress.split(':');
|
64
67
|
for (i = 0; i < validGroupCount; i++) {
|
65
68
|
// it's fastest & easiest for tablesorter to sort decimal values (vs hex)
|
66
69
|
groups[i] = hex ? ('0000' + groups[i]).slice(-4) :
|
@@ -70,7 +73,53 @@
|
|
70
73
|
return hex ? expandedAddress : expandedAddress.replace(/:/g, '');
|
71
74
|
},
|
72
75
|
// uses natural sort hex compare
|
73
|
-
type:
|
76
|
+
type: 'numeric'
|
77
|
+
});
|
78
|
+
|
79
|
+
// ipv4 address
|
80
|
+
// moved here from jquery.tablesorter.js (core file)
|
81
|
+
ipv4Is = function(s) {
|
82
|
+
return (/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/).test(s);
|
83
|
+
};
|
84
|
+
ipv4Format = function(s, table) {
|
85
|
+
var i, a = s ? s.split('.') : '',
|
86
|
+
r = '',
|
87
|
+
l = a.length;
|
88
|
+
for (i = 0; i < l; i++) {
|
89
|
+
r += ('000' + a[i]).slice(-3);
|
90
|
+
}
|
91
|
+
return s ? ts.formatFloat(r, table) : s;
|
92
|
+
};
|
93
|
+
|
94
|
+
// duplicate "ipAddress" as "ipv4Address" (to maintain backwards compatility)
|
95
|
+
ts.addParser({
|
96
|
+
id: 'ipAddress',
|
97
|
+
is: ipv4Is,
|
98
|
+
format: ipv4Format,
|
99
|
+
type: 'numeric'
|
100
|
+
});
|
101
|
+
ts.addParser({
|
102
|
+
id: 'ipv4Address',
|
103
|
+
is: ipv4Is,
|
104
|
+
format: ipv4Format,
|
105
|
+
type: 'numeric'
|
106
|
+
});
|
107
|
+
|
108
|
+
ts.addParser({
|
109
|
+
id: 'MAC',
|
110
|
+
is: function(s) {
|
111
|
+
return ts.regex.ipv6Validate.test(s);
|
112
|
+
},
|
113
|
+
format: function(s) {
|
114
|
+
var t = '',
|
115
|
+
val = s.replace(/[:.-]/g, '').match(/\w{2}/g);
|
116
|
+
$.each(val, function(i, v){
|
117
|
+
t += ( '000' + parseInt(v, 16) ).slice(-3);
|
118
|
+
});
|
119
|
+
return t;
|
120
|
+
},
|
121
|
+
// uses natural sort hex compare
|
122
|
+
type: 'numeric'
|
74
123
|
});
|
75
124
|
|
76
125
|
})(jQuery);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Column Selector/Responsive table widget (beta) for TableSorter
|
1
|
+
/* Column Selector/Responsive table widget (beta) for TableSorter - 10/26/2014 (v2.18.0)
|
2
2
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
3
|
* by Justin Hallett & Rob Garrison
|
4
4
|
*/
|
@@ -11,8 +11,8 @@ var ts = $.tablesorter,
|
|
11
11
|
namespace = '.tscolsel',
|
12
12
|
tsColSel = ts.columnSelector = {
|
13
13
|
|
14
|
-
queryAll : '@media only all { [columns] { display: none; } }',
|
15
|
-
queryBreak : '@media all and (min-width: [size]) { [columns] { display: table-cell; } }',
|
14
|
+
queryAll : '@media only all { [columns] { display: none; } } ',
|
15
|
+
queryBreak : '@media all and (min-width: [size]) { [columns] { display: table-cell; } } ',
|
16
16
|
|
17
17
|
init: function(table, c, wo) {
|
18
18
|
var $t, colSel;
|
@@ -81,7 +81,6 @@ tsColSel = ts.columnSelector = {
|
|
81
81
|
colId = $this.attr('data-column'),
|
82
82
|
state = ts.getData(this, c.headers[colId], 'columnSelector');
|
83
83
|
|
84
|
-
|
85
84
|
// if this column not hidable at all
|
86
85
|
// include getData check (includes "columnSelector-false" class, data attribute, etc)
|
87
86
|
if ( isNaN(priority) && priority.length > 0 || state === 'disable' ||
|
@@ -191,6 +190,7 @@ tsColSel = ts.columnSelector = {
|
|
191
190
|
breaks = [];
|
192
191
|
c.$headers.filter('[' + wo.columnSelector_priority + '=' + (priority + 1) + ']').each(function(){
|
193
192
|
column = parseInt($(this).attr('data-column'), 10) + 1;
|
193
|
+
breaks.push(prefix + ' col:nth-child(' + column + ')');
|
194
194
|
breaks.push(prefix + ' tr th:nth-child(' + column + ')');
|
195
195
|
breaks.push(prefix + ' tr td:nth-child(' + column + ')');
|
196
196
|
});
|
@@ -204,9 +204,11 @@ tsColSel = ts.columnSelector = {
|
|
204
204
|
if (colSel.$style) {
|
205
205
|
colSel.$style.prop('disabled', true);
|
206
206
|
}
|
207
|
-
|
208
|
-
|
209
|
-
|
207
|
+
if (mediaAll.length) {
|
208
|
+
colSel.$breakpoints
|
209
|
+
.prop('disabled', false)
|
210
|
+
.html( tsColSel.queryAll.replace(/\[columns\]/g, mediaAll.join(',')) + breakpts );
|
211
|
+
}
|
210
212
|
},
|
211
213
|
|
212
214
|
updateCols: function(c, wo) {
|
@@ -220,6 +222,7 @@ tsColSel = ts.columnSelector = {
|
|
220
222
|
colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
|
221
223
|
if (!this.checked) {
|
222
224
|
column = parseInt( $(this).attr('data-column'), 10 ) + 1;
|
225
|
+
styles.push(prefix + ' col:nth-child(' + column + ')');
|
223
226
|
styles.push(prefix + ' tr th:nth-child(' + column + ')');
|
224
227
|
styles.push(prefix + ' tr td:nth-child(' + column + ')');
|
225
228
|
}
|
@@ -1,68 +1,95 @@
|
|
1
|
-
/*! tablesorter CSS Sticky Headers widget - updated
|
1
|
+
/*! tablesorter CSS Sticky Headers widget - updated 10/26/2014 (v2.18.0)
|
2
2
|
* Requires a modern browser, tablesorter v2.8+
|
3
3
|
*/
|
4
4
|
/*jshint jquery:true, unused:false */
|
5
5
|
;(function($){
|
6
|
-
|
6
|
+
'use strict';
|
7
7
|
|
8
|
-
$.tablesorter
|
9
|
-
|
8
|
+
var ts = $.tablesorter;
|
9
|
+
|
10
|
+
ts.addWidget({
|
11
|
+
id: 'cssStickyHeaders',
|
10
12
|
priority: 10,
|
11
13
|
options: {
|
12
14
|
cssStickyHeaders_offset : 0,
|
13
15
|
cssStickyHeaders_addCaption : false,
|
16
|
+
// jQuery selector or object to attach sticky header to
|
14
17
|
cssStickyHeaders_attachTo : null,
|
15
|
-
cssStickyHeaders_filteredToTop : true
|
16
|
-
cssStickyHeaders_zIndex : 10
|
18
|
+
cssStickyHeaders_filteredToTop : true
|
17
19
|
},
|
18
20
|
init : function(table, thisWidget, c, wo) {
|
19
|
-
var
|
20
|
-
|
21
|
-
$
|
22
|
-
|
23
|
-
$
|
24
|
-
|
21
|
+
var isIE = 'ActiveXObject' in window, // target all versions of IE
|
22
|
+
$table = c.$table,
|
23
|
+
$attach = $(wo.cssStickyHeaders_attachTo),
|
24
|
+
namespace = c.namespace + 'cssstickyheader ',
|
25
|
+
$thead = $table.children('thead'),
|
26
|
+
$caption = $table.children('caption'),
|
27
|
+
$win = $attach.length ? $attach : $(window),
|
28
|
+
$parent = $table.parent().closest('table.' + ts.css.table),
|
29
|
+
$parentThead = $parent.length && ts.hasWidget($parent[0], 'cssStickyHeaders') ? $parent.children('thead') : [];
|
30
|
+
|
31
|
+
$win
|
32
|
+
.unbind('scroll resize '.split(' ').join(namespace))
|
33
|
+
.bind('scroll resize '.split(' ').join(namespace), function() {
|
25
34
|
var top = $attach.length ? $attach.offset().top : $win.scrollTop(),
|
26
35
|
// add caption height; include table padding top & border-spacing or text may be above the fold (jQuery UI themes)
|
27
36
|
// border-spacing needed in Firefox, but not webkit... not sure if I should account for that
|
28
|
-
|
29
|
-
(parseInt(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
captionHeight = wo.cssStickyHeaders_addCaption ? ( $caption.outerHeight(true) || 0 ) +
|
38
|
+
( parseInt( $table.css('padding-top'), 10 ) || 0 ) + ( parseInt( $table.css('border-spacing'), 10 ) || 0 ) : 0,
|
39
|
+
|
40
|
+
bottom = $table.height() - $thead.height() - ( $table.children('tfoot').height() || 0 ) - captionHeight,
|
41
|
+
// get bottom of nested sticky headers
|
42
|
+
nestedStickyTop = $parentThead.length ? ( isIE ? $parent.data('cssStickyHeaderTop') : $parentThead.offset().top ) +
|
43
|
+
$parentThead.height() - $win.scrollTop() : 0,
|
44
|
+
|
45
|
+
// Detect nested tables - fixes #724
|
46
|
+
deltaY = top - $table.offset().top + nestedStickyTop + ( parseInt( $table.css('border-top-width'), 10 ) || 0 ) +
|
47
|
+
// Again, I dislike browser sniffing... but I have no idea why I need to include a captionHeight
|
48
|
+
// for Firefox here and not for Chrome. Even IE behaves, sorta!
|
49
|
+
( wo.cssStickyHeaders_offset || 0 ) + ( navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ? captionHeight : 0 ),
|
50
|
+
|
51
|
+
finalY = deltaY > 0 && deltaY <= bottom ? deltaY : 0,
|
52
|
+
|
53
|
+
// All IE (even IE11) can only transform header cells - fixes #447 thanks to @gakreol!
|
54
|
+
$cells = isIE ? $thead.children().children() : $thead;
|
55
|
+
|
56
|
+
// more crazy IE stuff.. somehow the second nested table is completely ignored
|
57
|
+
if (isIE) {
|
58
|
+
c.$table.data('cssStickyHeaderTop', finalY - ( $parentThead.length ? $parentThead.height() : 0 ));
|
59
|
+
if ($parentThead.length) {
|
60
|
+
top = $parent.data('cssStickyHeaderTop') - $parentThead.height();
|
61
|
+
finalY = top > 0 && top <= bottom ? top : 0;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
36
65
|
if (wo.cssStickyHeaders_addCaption) {
|
37
66
|
$cells = $cells.add($caption);
|
38
67
|
}
|
68
|
+
|
39
69
|
$cells.css({
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
"-ms-transform" : finalY === 0 ? "" : "translate(0px," + finalY + "px)",
|
44
|
-
"-webkit-transform" : finalY === 0 ? "" : "translate(0px," + finalY + "px)"
|
70
|
+
'transform' : finalY === 0 ? '' : 'translate(0px,' + finalY + 'px)',
|
71
|
+
'-ms-transform' : finalY === 0 ? '' : 'translate(0px,' + finalY + 'px)',
|
72
|
+
'-webkit-transform' : finalY === 0 ? '' : 'translate(0px,' + finalY + 'px)'
|
45
73
|
});
|
46
74
|
});
|
47
|
-
|
75
|
+
$table.unbind('filterEnd' + namespace).bind('filterEnd' + namespace, function() {
|
48
76
|
if (wo.cssStickyHeaders_filteredToTop) {
|
49
77
|
// scroll top of table into view
|
50
|
-
window.scrollTo(0,
|
78
|
+
window.scrollTo(0, $table.position().top);
|
51
79
|
}
|
52
80
|
});
|
53
81
|
|
54
82
|
},
|
55
83
|
remove: function(table, c, wo){
|
56
|
-
var namespace = '
|
57
|
-
$(window).unbind('scroll resize '.split(' ').join(namespace
|
84
|
+
var namespace = c.namespace + 'cssstickyheader ';
|
85
|
+
$(window).unbind('scroll resize '.split(' ').join(namespace));
|
58
86
|
c.$table
|
59
|
-
.unbind('
|
87
|
+
.unbind('filterEnd scroll resize '.split(' ').join(namespace))
|
88
|
+
.add( c.$table.children('thead').children().children() )
|
60
89
|
.children('thead, caption').css({
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
"-ms-transform" : "",
|
65
|
-
"-webkit-transform" : ""
|
90
|
+
'transform' : '',
|
91
|
+
'-ms-transform' : '',
|
92
|
+
'-webkit-transform' : ''
|
66
93
|
});
|
67
94
|
}
|
68
95
|
});
|
@@ -1,200 +1,223 @@
|
|
1
|
-
|
1
|
+
/*! tablesorter Editable Content widget - updated 10/26/2014 (v2.18.0)
|
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
|
/*global jQuery: false */
|
7
|
-
;(function($){
|
8
|
-
|
7
|
+
;( function( $ ){
|
8
|
+
'use strict';
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
var
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
tmp = wo.editable_columns.split('-');
|
56
|
-
indx = parseInt(tmp[0],10) || 0;
|
57
|
-
tmp = parseInt(tmp[1],10) || (c.columns - 1);
|
58
|
-
if ( tmp > c.columns ) { tmp = c.columns - 1; }
|
59
|
-
for ( ; indx <= tmp; indx++ ) {
|
60
|
-
cols.push('td:nth-child(' + (indx + 1) + ')');
|
10
|
+
var tse = $.tablesorter.editable = {
|
11
|
+
|
12
|
+
editComplete: function( c, wo, $cell, refocus ) {
|
13
|
+
$cell
|
14
|
+
.removeClass( 'tseditable-last-edited-cell' )
|
15
|
+
.trigger( wo.editable_editComplete, [ c ] );
|
16
|
+
// restore focus last cell after updating
|
17
|
+
if ( refocus ) {
|
18
|
+
setTimeout( function() {
|
19
|
+
$cell.focus();
|
20
|
+
}, 50 );
|
21
|
+
}
|
22
|
+
},
|
23
|
+
|
24
|
+
selectAll: function( cell ) {
|
25
|
+
setTimeout( function() {
|
26
|
+
// select all text in contenteditable
|
27
|
+
// see http://stackoverflow.com/a/6150060/145346
|
28
|
+
var sel, range = document.createRange();
|
29
|
+
range.selectNodeContents( cell );
|
30
|
+
sel = window.getSelection();
|
31
|
+
sel.removeAllRanges();
|
32
|
+
sel.addRange( range );
|
33
|
+
}, 100 );
|
34
|
+
},
|
35
|
+
|
36
|
+
update: function( c, wo ) {
|
37
|
+
var indx, tmp, $t,
|
38
|
+
cols = [];
|
39
|
+
|
40
|
+
if ( $.type( wo.editable_columns ) === 'string' && wo.editable_columns.indexOf( '-' ) >= 0 ) {
|
41
|
+
// editable_columns can contain a range string ( i.e. '2-4' )
|
42
|
+
tmp = wo.editable_columns.split( /\s*-\s*/ );
|
43
|
+
indx = parseInt( tmp[ 0 ], 10 ) || 0;
|
44
|
+
tmp = parseInt( tmp[ 1 ], 10 ) || ( c.columns - 1 );
|
45
|
+
if ( tmp > c.columns ) {
|
46
|
+
tmp = c.columns - 1;
|
47
|
+
}
|
48
|
+
for ( ; indx <= tmp; indx++ ) {
|
49
|
+
cols.push( 'td:nth-child(' + ( indx + 1 ) + ')' );
|
50
|
+
}
|
51
|
+
} else if ( $.isArray( wo.editable_columns ) ) {
|
52
|
+
$.each( wo.editable_columns, function( i, col ) {
|
53
|
+
if ( col < c.columns ) {
|
54
|
+
cols.push( 'td:nth-child(' + ( col + 1 ) + ')' );
|
61
55
|
}
|
62
|
-
}
|
63
|
-
|
64
|
-
|
65
|
-
|
56
|
+
});
|
57
|
+
}
|
58
|
+
tmp = $( '<div>' ).wrapInner( wo.editable_wrapContent ).children().length || $.isFunction( wo.editable_wrapContent );
|
59
|
+
// IE does not allow making TR/TH/TD cells directly editable ( issue #404 )
|
60
|
+
// so add a div or span inside ( it's faster than using wrapInner() )
|
61
|
+
c.$tbodies.find( cols.join( ',' ) ).not( '.' + wo.editable_noEdit ).each( function() {
|
62
|
+
// test for children, if they exist, then make the children editable
|
63
|
+
$t = $( this );
|
64
|
+
|
65
|
+
if ( tmp && $t.children().length === 0 ) {
|
66
|
+
$t.wrapInner( wo.editable_wrapContent );
|
67
|
+
}
|
68
|
+
if ( $t.children().length ) {
|
69
|
+
// make all children content editable
|
70
|
+
$t.children().not( '.' + wo.editable_noEdit ).each( function() {
|
71
|
+
var $this = $( this );
|
72
|
+
if ( wo.editable_trimContent ) {
|
73
|
+
$this.text( function( i, txt ) {
|
74
|
+
return $.trim( txt );
|
75
|
+
});
|
66
76
|
}
|
77
|
+
$this.prop( 'contenteditable', true );
|
67
78
|
});
|
79
|
+
} else {
|
80
|
+
if ( wo.editable_trimContent ) {
|
81
|
+
$t.text( function( i, txt ) {
|
82
|
+
return $.trim( txt );
|
83
|
+
});
|
84
|
+
}
|
85
|
+
$t.prop( 'contenteditable', true );
|
68
86
|
}
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
});
|
88
|
+
},
|
89
|
+
|
90
|
+
bindEvents: function( c, wo ) {
|
91
|
+
c.$table
|
92
|
+
.off( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable' ) )
|
93
|
+
.on( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable' ), function() {
|
94
|
+
tse.update( c, wo );
|
95
|
+
});
|
96
|
+
|
97
|
+
c.$tbodies
|
98
|
+
.off( 'mouseleave focus blur focusout keydown '.split( ' ' ).join( '.tseditable ' ) )
|
99
|
+
.on( 'mouseleave.tseditable', function() {
|
100
|
+
if ( c.$table.data( 'contentFocused' ) ) {
|
101
|
+
// change to 'true' instead of element to allow focusout to process
|
102
|
+
c.$table.data( 'contentFocused', true );
|
103
|
+
$( ':focus' ).trigger( 'focusout' );
|
78
104
|
}
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
105
|
+
})
|
106
|
+
.on( 'focus.tseditable', '[contenteditable]', function( e ) {
|
107
|
+
clearTimeout( $( this ).data( 'timer' ) );
|
108
|
+
c.$table.data( 'contentFocused', e.target );
|
109
|
+
var $this = $( this ),
|
110
|
+
selAll = wo.editable_selectAll,
|
111
|
+
column = $this.closest( 'td' ).index(),
|
112
|
+
txt = $.trim( $this.text() );
|
113
|
+
if ( wo.editable_enterToAccept ) {
|
114
|
+
// prevent enter from adding into the content
|
115
|
+
$this.on( 'keydown.tseditable', function( e ){
|
116
|
+
if ( e.which === 13 ) {
|
117
|
+
e.preventDefault();
|
87
118
|
}
|
88
|
-
$this.prop( 'contenteditable', true );
|
89
119
|
});
|
90
|
-
} else {
|
91
|
-
if (wo.editable_trimContent) {
|
92
|
-
$t.text(function(i, txt){
|
93
|
-
return $.trim(txt);
|
94
|
-
});
|
95
|
-
}
|
96
|
-
$t.prop( 'contenteditable', true );
|
97
120
|
}
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
selAll = wo.editable_selectAll,
|
112
|
-
column = $this.closest('td').index(),
|
113
|
-
txt = $.trim( $this.text() );
|
114
|
-
if (wo.editable_enterToAccept) {
|
115
|
-
// prevent enter from adding into the content
|
116
|
-
$this.on('keydown.tseditable', function(e){
|
117
|
-
if ( e.which === 13 ) {
|
118
|
-
e.preventDefault();
|
119
|
-
}
|
120
|
-
});
|
121
|
+
$this.data({ before : txt, original: txt });
|
122
|
+
|
123
|
+
if ( typeof wo.editable_focused === 'function' ) {
|
124
|
+
wo.editable_focused( txt, column, $this );
|
125
|
+
}
|
126
|
+
|
127
|
+
if ( selAll ) {
|
128
|
+
if ( typeof selAll === 'function' ) {
|
129
|
+
if ( selAll( txt, column, $this ) ) {
|
130
|
+
tse.selectAll( $this[0] );
|
131
|
+
}
|
132
|
+
} else {
|
133
|
+
tse.selectAll( $this[0] );
|
121
134
|
}
|
122
|
-
|
135
|
+
}
|
136
|
+
})
|
137
|
+
.on( 'blur focusout keydown '.split( ' ' ).join( '.tseditable ' ), '[contenteditable]', function( e ) {
|
138
|
+
if ( !c.$table.data( 'contentFocused' ) ) { return; }
|
139
|
+
var t, validate,
|
140
|
+
valid = false,
|
141
|
+
$this = $( e.target ),
|
142
|
+
txt = $.trim( $this.text() ),
|
143
|
+
column = $this.closest( 'td' ).index();
|
144
|
+
if ( e.which === 27 ) {
|
145
|
+
// user cancelled
|
146
|
+
$this.html( $.trim( $this.data( 'original' ) ) ).trigger( 'blur.tseditable' );
|
147
|
+
c.$table.data( 'contentFocused', false );
|
148
|
+
return false;
|
149
|
+
}
|
150
|
+
// accept on enter ( if set ), alt-enter ( always ) or if autoAccept is set and element is blurred or unfocused
|
151
|
+
t = e.which === 13 && ( wo.editable_enterToAccept || e.altKey ) || wo.editable_autoAccept && e.type !== 'keydown';
|
152
|
+
// change if new or user hits enter ( if option set )
|
153
|
+
if ( t && $this.data( 'before' ) !== txt ) {
|
123
154
|
|
124
|
-
|
125
|
-
|
155
|
+
validate = wo.editable_validate;
|
156
|
+
valid = txt;
|
157
|
+
|
158
|
+
if ( typeof( validate ) === 'function' ) {
|
159
|
+
valid = validate( txt, $this.data( 'original' ), column, $this );
|
160
|
+
} else if ( typeof ( validate = $.tablesorter.getColumnData( c.table, validate, column ) ) === 'function' ) {
|
161
|
+
valid = validate( txt, $this.data( 'original' ), column, $this );
|
126
162
|
}
|
127
163
|
|
128
|
-
if (
|
129
|
-
|
130
|
-
|
131
|
-
|
164
|
+
if ( t && valid !== false ) {
|
165
|
+
c.$table.find( '.tseditable-last-edited-cell' ).removeClass( 'tseditable-last-edited-cell' );
|
166
|
+
$this
|
167
|
+
.addClass( 'tseditable-last-edited-cell' )
|
168
|
+
.html( $.trim( valid ) )
|
169
|
+
.data( 'before', valid )
|
170
|
+
.data( 'original', valid )
|
171
|
+
.trigger( 'change' );
|
172
|
+
c.$table.trigger( 'updateCell', [ $this.closest( 'td' ), false, function() {
|
173
|
+
if ( wo.editable_autoResort ) {
|
174
|
+
setTimeout( function() {
|
175
|
+
c.$table.trigger( 'sorton', [ c.sortList, function() {
|
176
|
+
tse.editComplete( c, wo, c.$table.find( '.tseditable-last-edited-cell' ), true );
|
177
|
+
}, true ] );
|
178
|
+
}, 10 );
|
179
|
+
} else {
|
180
|
+
tse.editComplete( c, wo, c.$table.find( '.tseditable-last-edited-cell' ) );
|
132
181
|
}
|
133
|
-
}
|
134
|
-
selectAll($this[0]);
|
135
|
-
}
|
136
|
-
}
|
137
|
-
})
|
138
|
-
.on('blur focusout keydown '.split(' ').join('.tseditable '), '[contenteditable]', function(e){
|
139
|
-
if ( !c.$table.data('contentFocused') ) { return; }
|
140
|
-
var t, validate,
|
141
|
-
valid = false,
|
142
|
-
$this = $(e.target),
|
143
|
-
txt = $.trim( $this.text() ),
|
144
|
-
column = $this.closest('td').index();
|
145
|
-
if ( e.which === 27 ) {
|
146
|
-
// user cancelled
|
147
|
-
$this.html( $.trim( $this.data('original') ) ).trigger('blur.tseditable');
|
148
|
-
c.$table.data( 'contentFocused', false );
|
182
|
+
} ] );
|
149
183
|
return false;
|
150
184
|
}
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
validate = wo.editable_validate;
|
157
|
-
valid = txt;
|
158
|
-
|
159
|
-
if (typeof(validate) === "function") {
|
160
|
-
valid = validate( txt, $this.data('original'), column, $this );
|
161
|
-
} else if (typeof (validate = $.tablesorter.getColumnData( table, validate, column )) === 'function') {
|
162
|
-
valid = validate( txt, $this.data('original'), column, $this );
|
185
|
+
} else if ( !valid && e.type !== 'keydown' ) {
|
186
|
+
clearTimeout( $this.data( 'timer' ) );
|
187
|
+
$this.data( 'timer', setTimeout( function() {
|
188
|
+
if ( $.isFunction( wo.editable_blur ) ) {
|
189
|
+
wo.editable_blur( $.trim( $this.text() ), column, $this );
|
163
190
|
}
|
191
|
+
}, 100 ) );
|
192
|
+
// restore original content on blur
|
193
|
+
$this.html( $.trim( $this.data( 'original' ) ) );
|
194
|
+
}
|
195
|
+
});
|
196
|
+
}
|
164
197
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
clearTimeout( $this.data('timer') );
|
188
|
-
$this.data('timer', setTimeout(function(){
|
189
|
-
if ($.isFunction(wo.editable_blur)) {
|
190
|
-
wo.editable_blur( $.trim( $this.text() ), column, $this );
|
191
|
-
}
|
192
|
-
}, 100));
|
193
|
-
// restore original content on blur
|
194
|
-
$this.html( $.trim( $this.data('original') ) );
|
195
|
-
}
|
196
|
-
});
|
198
|
+
};
|
199
|
+
|
200
|
+
$.tablesorter.addWidget({
|
201
|
+
id: 'editable',
|
202
|
+
options : {
|
203
|
+
editable_columns : [],
|
204
|
+
editable_enterToAccept : true,
|
205
|
+
editable_autoAccept : true,
|
206
|
+
editable_autoResort : false,
|
207
|
+
editable_wrapContent : '<div>', // wrap the cell content... makes this widget work in IE, and with autocomplete
|
208
|
+
editable_trimContent : true, // trim content inside of contenteditable ( remove tabs & carriage returns )
|
209
|
+
editable_validate : null, // function( text, originalText ){ return text; }
|
210
|
+
editable_focused : null, // function( text, columnIndex, $element ) {}
|
211
|
+
editable_blur : null, // function( text, columnIndex, $element ) { }
|
212
|
+
editable_selectAll : false, // true/false or function( text, columnIndex, $element ) { return true; }
|
213
|
+
editable_noEdit : 'no-edit',
|
214
|
+
editable_editComplete : 'editComplete'
|
215
|
+
},
|
216
|
+
init: function( table, thisWidget, c, wo ){
|
217
|
+
if ( !wo.editable_columns.length ) { return; }
|
218
|
+
tse.update( c, wo );
|
219
|
+
tse.bindEvents( c, wo );
|
197
220
|
}
|
198
221
|
});
|
199
222
|
|
200
|
-
})(jQuery);
|
223
|
+
})( jQuery );
|