jquery-tablesorter 1.16.5 → 1.17.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 +2 -2
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +38 -27
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +1104 -839
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +167 -123
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +938 -717
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +5 -5
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +46 -0
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +96 -72
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +6 -5
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-network.js +26 -17
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columns.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +95 -42
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +921 -700
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +5 -3
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +22 -20
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +7 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +40 -29
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +6 -6
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +53 -31
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +1 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +8 -6
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +1 -1
- metadata +3 -2
@@ -2,12 +2,12 @@
|
|
2
2
|
/* Extract dates using popular natural language date parsers */
|
3
3
|
/*jshint jquery:true */
|
4
4
|
;(function($){
|
5
|
-
|
5
|
+
'use strict';
|
6
6
|
|
7
7
|
/*! Sugar (http://sugarjs.com/dates#comparing_dates) */
|
8
8
|
/* demo: http://jsfiddle.net/Mottie/abkNM/4163/ */
|
9
9
|
$.tablesorter.addParser({
|
10
|
-
id:
|
10
|
+
id: 'sugar',
|
11
11
|
is: function() {
|
12
12
|
return false;
|
13
13
|
},
|
@@ -15,13 +15,13 @@
|
|
15
15
|
var date = Date.create ? Date.create(s) : s ? new Date(s) : s;
|
16
16
|
return date instanceof Date && isFinite(date) ? date.getTime() : s;
|
17
17
|
},
|
18
|
-
type:
|
18
|
+
type: 'numeric'
|
19
19
|
});
|
20
20
|
|
21
21
|
/*! Datejs (http://www.datejs.com/) */
|
22
22
|
/* demo: http://jsfiddle.net/Mottie/abkNM/4164/ */
|
23
23
|
$.tablesorter.addParser({
|
24
|
-
id:
|
24
|
+
id: 'datejs',
|
25
25
|
is: function() {
|
26
26
|
return false;
|
27
27
|
},
|
@@ -29,7 +29,7 @@
|
|
29
29
|
var date = Date.parse ? Date.parse(s) : s ? new Date(s) : s;
|
30
30
|
return date instanceof Date && isFinite(date) ? date.getTime() : s;
|
31
31
|
},
|
32
|
-
type:
|
32
|
+
type: 'numeric'
|
33
33
|
});
|
34
34
|
|
35
35
|
})(jQuery);
|
@@ -0,0 +1,46 @@
|
|
1
|
+
/*! Parser: jQuery Globalize - updated 5/17/2015 (v2.22.0) */
|
2
|
+
/* Extract localized data using jQuery's Globalize parsers; set
|
3
|
+
Globalize.locale( 'xx' ) prior to initializing tablesorter! */
|
4
|
+
/*jshint jquery:true */
|
5
|
+
;( function( $ ) {
|
6
|
+
'use strict';
|
7
|
+
|
8
|
+
/*! jQuery Globalize date parser (https://github.com/jquery/globalize#date-module) */
|
9
|
+
/* demo: http://jsfiddle.net/Mottie/0j18Lw8r/ */
|
10
|
+
$.tablesorter.addParser({
|
11
|
+
id: 'globalize-date',
|
12
|
+
is: function () {
|
13
|
+
return false;
|
14
|
+
},
|
15
|
+
format: function ( str, table, cell, cellIndex ) {
|
16
|
+
var c = table.config,
|
17
|
+
// add options to 'config.globalize' for all columns --> globalize : { skeleton: 'GyMMMd' }
|
18
|
+
// or per column by using the column index --> globalize : { 0 : { datetime: 'medium' } }
|
19
|
+
options = c.globalize && ( c.globalize[ cellIndex ] || c.globalize ) || {},
|
20
|
+
date = Globalize && Globalize.dateParser ? Globalize.dateParser( options )( str ) :
|
21
|
+
str ? new Date( str ) : str;
|
22
|
+
return date instanceof Date && isFinite( date ) ? date.getTime() : str;
|
23
|
+
},
|
24
|
+
type: 'numeric'
|
25
|
+
});
|
26
|
+
|
27
|
+
/*! jQuery Globalize number parser (https://github.com/jquery/globalize#number-module) */
|
28
|
+
/* demo: http://jsfiddle.net/Mottie/0j18Lw8r/ */
|
29
|
+
$.tablesorter.addParser({
|
30
|
+
id: 'globalize-number',
|
31
|
+
is: function () {
|
32
|
+
return false;
|
33
|
+
},
|
34
|
+
format: function ( str, table, cell, cellIndex ) {
|
35
|
+
var c = table.config,
|
36
|
+
// add options to 'config.globalize' for all columns --> globalize : { skeleton: 'GyMMMd' }
|
37
|
+
// or per column by using the column index --> globalize : { 0 : { datetime: 'medium' } }
|
38
|
+
options = c.globalize && ( c.globalize[ cellIndex ] || c.globalize ) || {},
|
39
|
+
num = Globalize && Globalize.numberParser ? Globalize.numberParser( options )( str ) :
|
40
|
+
str ? $.tablesorter.formatFloat( ( str || '' ).replace( /[^\w,. \-()]/g, '' ), table ) : str;
|
41
|
+
return str && typeof num === 'number' ? num : str;
|
42
|
+
},
|
43
|
+
type: 'numeric'
|
44
|
+
});
|
45
|
+
|
46
|
+
})( jQuery );
|
@@ -1,12 +1,12 @@
|
|
1
|
-
/*! Parser: input & select - updated
|
1
|
+
/*! Parser: input & select - updated 5/17/2015 (v2.22.0) *//*
|
2
2
|
* for jQuery 1.7+ & tablesorter 2.7.11+
|
3
3
|
* Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html
|
4
4
|
*/
|
5
5
|
/*jshint browser: true, jquery:true, unused:false */
|
6
|
-
;(function($){
|
7
|
-
|
6
|
+
;( function( $ ) {
|
7
|
+
'use strict';
|
8
8
|
|
9
|
-
var updateServer = function(event, $table, $input){
|
9
|
+
var updateServer = function( event, $table, $input ) {
|
10
10
|
// do something here to update your server, if needed
|
11
11
|
// event = change event object
|
12
12
|
// $table = jQuery object of the table that was just updated
|
@@ -14,140 +14,164 @@
|
|
14
14
|
};
|
15
15
|
|
16
16
|
// Custom parser for parsing input values
|
17
|
-
// updated dynamically using the
|
17
|
+
// updated dynamically using the 'change' function below
|
18
18
|
$.tablesorter.addParser({
|
19
|
-
id:
|
20
|
-
is: function(){
|
19
|
+
id : 'inputs',
|
20
|
+
is : function() {
|
21
21
|
return false;
|
22
22
|
},
|
23
|
-
format: function(
|
24
|
-
|
23
|
+
format : function( txt, table, cell ) {
|
24
|
+
var $input = $( cell ).find( 'input' );
|
25
|
+
return $input.length ? $input.val() : txt;
|
25
26
|
},
|
26
27
|
parsed : true, // filter widget flag
|
27
|
-
type:
|
28
|
+
type : 'text'
|
29
|
+
});
|
30
|
+
|
31
|
+
$.tablesorter.addParser({
|
32
|
+
id : 'inputs-numeric',
|
33
|
+
is : function() {
|
34
|
+
return false;
|
35
|
+
},
|
36
|
+
format : function( txt, table, cell ) {
|
37
|
+
var $input = $( cell ).find( 'input' );
|
38
|
+
var val = $input.length ? $input.val() : txt,
|
39
|
+
num = $.tablesorter.formatFloat( ( val || '' ).replace( /[^\w,. \-()]/g, '' ), table );
|
40
|
+
return txt && typeof num === 'number' ? num :
|
41
|
+
txt ? $.trim( txt && table.config.ignoreCase ? txt.toLocaleLowerCase() : txt ) : txt;
|
42
|
+
},
|
43
|
+
parsed : true, // filter widget flag
|
44
|
+
type : 'numeric'
|
28
45
|
});
|
29
46
|
|
30
47
|
// Custom parser for including checkbox status if using the grouping widget
|
31
|
-
// updated dynamically using the
|
48
|
+
// updated dynamically using the 'change' function below
|
32
49
|
$.tablesorter.addParser({
|
33
|
-
id:
|
34
|
-
is: function(){
|
50
|
+
id : 'checkbox',
|
51
|
+
is : function() {
|
35
52
|
return false;
|
36
53
|
},
|
37
|
-
format: function(
|
38
|
-
var $
|
54
|
+
format : function( txt, table, cell, cellIndex ) {
|
55
|
+
var $cell = $( cell ),
|
39
56
|
wo = table.config.widgetOptions,
|
40
57
|
// returning plain language here because this is what is shown in the
|
41
58
|
// group headers - change it as desired
|
42
|
-
|
43
|
-
$input = $
|
44
|
-
isChecked = $input.length ? $input[0].checked : '';
|
59
|
+
status = wo.group_checkbox ? wo.group_checkbox : [ 'checked', 'unchecked' ],
|
60
|
+
$input = $cell.find( 'input[type="checkbox"]' ),
|
61
|
+
isChecked = $input.length ? $input[ 0 ].checked : '';
|
45
62
|
// adding class to row, indicating that a checkbox is checked; includes
|
46
63
|
// a column index in case more than one checkbox happens to be in a row
|
47
|
-
$
|
48
|
-
return $input.length ?
|
64
|
+
$cell.closest( 'tr' ).toggleClass( 'checked checked-' + cellIndex, isChecked );
|
65
|
+
return $input.length ? status[ isChecked ? 0 : 1 ] : txt;
|
49
66
|
},
|
50
67
|
parsed : true, // filter widget flag
|
51
|
-
type:
|
68
|
+
type : 'text'
|
52
69
|
});
|
53
70
|
|
54
71
|
// Custom parser which returns the currently selected options
|
55
|
-
// updated dynamically using the
|
72
|
+
// updated dynamically using the 'change' function below
|
56
73
|
$.tablesorter.addParser({
|
57
|
-
id:
|
58
|
-
is: function(){
|
74
|
+
id : 'select',
|
75
|
+
is : function() {
|
59
76
|
return false;
|
60
77
|
},
|
61
|
-
format: function(
|
62
|
-
|
78
|
+
format : function( txt, table, cell ) {
|
79
|
+
var $select = $( cell ).find( 'select' );
|
80
|
+
return $select.length ? $select.val() : txt;
|
63
81
|
},
|
64
82
|
parsed : true, // filter widget flag
|
65
|
-
type:
|
83
|
+
type : 'text'
|
66
84
|
});
|
67
85
|
|
68
86
|
// Select parser to get the selected text
|
69
87
|
$.tablesorter.addParser({
|
70
|
-
id:
|
71
|
-
is: function(){
|
88
|
+
id : 'select-text',
|
89
|
+
is : function() {
|
72
90
|
return false;
|
73
91
|
},
|
74
|
-
format: function(
|
75
|
-
var $
|
76
|
-
return $
|
92
|
+
format : function( txt, table, cell ) {
|
93
|
+
var $select = $( cell ).find( 'select' );
|
94
|
+
return $select.length ? $select.find( 'option:selected' ).text() || '' : txt;
|
77
95
|
},
|
78
96
|
parsed : true, // filter widget flag
|
79
|
-
type:
|
97
|
+
type : 'text'
|
80
98
|
});
|
81
99
|
|
82
100
|
// Custom parser for parsing textarea values
|
83
|
-
// updated dynamically using the
|
101
|
+
// updated dynamically using the 'change' function below
|
84
102
|
$.tablesorter.addParser({
|
85
|
-
id:
|
86
|
-
is: function(){
|
103
|
+
id : 'textarea',
|
104
|
+
is : function() {
|
87
105
|
return false;
|
88
106
|
},
|
89
|
-
format: function(
|
90
|
-
|
107
|
+
format : function( txt, table, cell ) {
|
108
|
+
var $textarea = $( cell ).find( 'textarea' );
|
109
|
+
return $textarea.length ? $textarea.val() : txt;
|
91
110
|
},
|
92
111
|
parsed : true, // filter widget flag
|
93
|
-
type:
|
112
|
+
type : 'text'
|
94
113
|
});
|
95
114
|
|
96
115
|
// update select and all input types in the tablesorter cache when the change event fires.
|
97
116
|
// This method only works with jQuery 1.7+
|
98
117
|
// you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired
|
99
118
|
// if this code interferes somehow, target the specific table $('#mytable'), instead of $('table')
|
100
|
-
$(function(){
|
101
|
-
$('table').on('tablesorter-initialized', function(){
|
102
|
-
var
|
119
|
+
$( function() {
|
120
|
+
$( 'table' ).on( 'tablesorter-initialized updateComplete', function() {
|
121
|
+
var namespace = '.parser-forms',
|
122
|
+
restoreValue = function( isTbody ) {
|
103
123
|
// make sure we restore original values (trigger blur)
|
104
124
|
// isTbody is needed to prevent the select from closing in IE
|
105
125
|
// see https://connect.microsoft.com/IE/feedbackdetail/view/962618/
|
106
|
-
if (isTbody) {
|
107
|
-
$(':focus').blur();
|
126
|
+
if ( isTbody ) {
|
127
|
+
$( ':focus' ).blur();
|
108
128
|
}
|
109
129
|
return;
|
110
130
|
};
|
111
131
|
// bind to .tablesorter (default class name)
|
112
|
-
$(this).children('tbody')
|
113
|
-
.
|
114
|
-
|
132
|
+
$( this ).children( 'tbody' )
|
133
|
+
.off( namespace )
|
134
|
+
.on( 'mouseleave' + namespace, function( event ) {
|
135
|
+
restoreValue( event.target.nodeName === 'TBODY' );
|
115
136
|
})
|
116
|
-
.on('focus', 'select, input, textarea', function(){
|
117
|
-
$(this).data('ts-original-value', this.value);
|
137
|
+
.on( 'focus' + namespace, 'select, input, textarea', function() {
|
138
|
+
$( this ).data( 'ts-original-value', this.value );
|
118
139
|
})
|
119
|
-
.on('blur', 'input, textarea', function(){
|
140
|
+
.on( 'blur' + namespace, 'input, textarea', function() {
|
120
141
|
// restore input value;
|
121
|
-
//
|
122
|
-
this.value = $(this).data('ts-original-value');
|
142
|
+
// 'change' is triggered before 'blur' so this doesn't replace the new update with the original
|
143
|
+
this.value = $( this ).data( 'ts-original-value' );
|
123
144
|
})
|
124
|
-
.on('change keyup', 'select, input, textarea', function(
|
125
|
-
if (
|
145
|
+
.on( 'change keyup '.split( ' ' ).join( namespace + ' ' ), 'select, input, textarea', function( event ) {
|
146
|
+
if ( event.which === 27 ) {
|
126
147
|
// escape: restore original value
|
127
|
-
this.value = $(this).data('ts-original-value');
|
148
|
+
this.value = $( this ).data( 'ts-original-value' );
|
128
149
|
return;
|
129
150
|
}
|
130
151
|
// Update cell cache using... select: change, input: enter or textarea: alt + enter
|
131
|
-
if (
|
132
|
-
(
|
152
|
+
if ( event.type === 'change' ||
|
153
|
+
( event.type === 'keyup' && event.which === 13 &&
|
154
|
+
( event.target.nodeName === 'INPUT' || event.target.nodeName === 'TEXTAREA' && event.altKey ) ) ) {
|
133
155
|
var undef,
|
134
|
-
$
|
135
|
-
$cell = $
|
136
|
-
$table = $cell.closest('table'),
|
137
|
-
indx = $cell[0].cellIndex,
|
138
|
-
c = $table[0].config || false,
|
139
|
-
$hdr = c && c.$
|
140
|
-
|
141
|
-
//
|
142
|
-
|
143
|
-
|
156
|
+
$target = $( event.target ),
|
157
|
+
$cell = $target.closest( 'td' ),
|
158
|
+
$table = $cell.closest( 'table' ),
|
159
|
+
indx = $cell[ 0 ].cellIndex,
|
160
|
+
c = $table[ 0 ].config || false,
|
161
|
+
$hdr = c && c.$headerIndexed && c.$headerIndexed[ indx ] || [],
|
162
|
+
val = $target.val();
|
163
|
+
// abort if not a tablesorter table, or don't use updateCell if column is set
|
164
|
+
// to 'sorter-false' and 'filter-false', or column is set to 'parser-false'
|
165
|
+
if ( $hdr.length && ( $hdr.hasClass( 'parser-false' ) ||
|
166
|
+
( $hdr.hasClass( 'sorter-false' ) && $hdr.hasClass( 'filter-false' ) ) ) ) {
|
167
|
+
return;
|
144
168
|
}
|
145
169
|
// ignore change event if nothing changed
|
146
|
-
if (
|
147
|
-
$
|
170
|
+
if ( val !== $target.data( 'ts-original-value' ) || event.target.type === 'checkbox' ) {
|
171
|
+
$target.data( 'ts-original-value', val );
|
148
172
|
// pass undefined resort value so it falls back to config.resort setting
|
149
|
-
$table.trigger('updateCell', [ $
|
150
|
-
updateServer(
|
173
|
+
$table.trigger( 'updateCell', [ $cell, undef, function() {
|
174
|
+
updateServer( event, $table, $target );
|
151
175
|
} ]);
|
152
176
|
}
|
153
177
|
}
|
@@ -155,4 +179,4 @@
|
|
155
179
|
});
|
156
180
|
});
|
157
181
|
|
158
|
-
})(jQuery);
|
182
|
+
})( jQuery );
|
@@ -81,12 +81,13 @@
|
|
81
81
|
},
|
82
82
|
result, group,
|
83
83
|
negativeRegex = new RegExp('(' + named.negative.join('|') + ')'),
|
84
|
-
calc = function (
|
85
|
-
|
84
|
+
calc = function ( rawWord, table ) {
|
85
|
+
// remove extra characters that might be next to the word
|
86
|
+
var word = rawWord.replace( /[,."']/g, '' ),
|
87
|
+
// formatFloat will deal with the commas & decimals in the number format
|
88
|
+
num = $.tablesorter.formatFloat( rawWord || '', table ),
|
86
89
|
power = named.powers.hasOwnProperty( word ) ? named.powers[ word ] : null;
|
87
|
-
|
88
|
-
num = $.tablesorter.formatFloat( word || '', table );
|
89
|
-
}
|
90
|
+
num = typeof num === 'number' ? num : named.numbers.hasOwnProperty( word ) ? named.numbers[ word ] : null;
|
90
91
|
if ( num !== null ) {
|
91
92
|
group += num;
|
92
93
|
} else if ( word === named.hundred ) {
|
@@ -1,8 +1,8 @@
|
|
1
|
-
/*! Parser: network - updated
|
1
|
+
/*! Parser: network - updated 5/17/2015 (v2.22.0) */
|
2
2
|
/* IPv4, IPv6 and MAC Addresses */
|
3
3
|
/*global jQuery: false */
|
4
4
|
;(function($){
|
5
|
-
|
5
|
+
'use strict';
|
6
6
|
|
7
7
|
var ts = $.tablesorter,
|
8
8
|
ipv4Format,
|
@@ -10,8 +10,8 @@
|
|
10
10
|
|
11
11
|
/*! IPv6 Address parser (WIP) *//*
|
12
12
|
* IPv6 Address (ffff:0000:0000:0000:0000:0000:0000:0000)
|
13
|
-
* needs to support short versions like
|
14
|
-
* and
|
13
|
+
* needs to support short versions like '::8' or '1:2::7:8'
|
14
|
+
* and '::00:192.168.10.184' (embedded IPv4 address)
|
15
15
|
* see http://www.intermapper.com/support/tools/IPV6-Validator.aspx
|
16
16
|
*/
|
17
17
|
$.extend( ts.regex, {}, {
|
@@ -93,7 +93,7 @@
|
|
93
93
|
};
|
94
94
|
|
95
95
|
/*! Parser: ipv4Address (a.k.a. ipAddress) */
|
96
|
-
// duplicate
|
96
|
+
// duplicate 'ipAddress' as 'ipv4Address' (to maintain backwards compatility)
|
97
97
|
ts.addParser({
|
98
98
|
id: 'ipAddress',
|
99
99
|
is: ipv4Is,
|
@@ -108,21 +108,30 @@
|
|
108
108
|
});
|
109
109
|
|
110
110
|
/*! Parser: MAC address */
|
111
|
+
/* MAC examples: 12:34:56:78:9A:BC, 1234.5678.9ABC, 12-34-56-78-9A-BC, and 123456789ABC
|
112
|
+
*/
|
111
113
|
ts.addParser({
|
112
|
-
id: 'MAC',
|
113
|
-
is: function(
|
114
|
-
return
|
114
|
+
id : 'MAC',
|
115
|
+
is : function( str ) {
|
116
|
+
return false;
|
115
117
|
},
|
116
|
-
format: function(
|
117
|
-
var
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
format : function( str ) {
|
119
|
+
var indx, len,
|
120
|
+
mac = '',
|
121
|
+
val = ( str || '' ).replace( /[:.-]/g, '' ).match( /\w{2}/g );
|
122
|
+
if ( val ) {
|
123
|
+
// not assuming all mac addresses in the column will end up with six
|
124
|
+
// groups of two to process, so it's not actually validating the address
|
125
|
+
len = val.length;
|
126
|
+
for ( indx = 0; indx < len; indx++ ) {
|
127
|
+
mac += ( '000' + parseInt( val[ indx ], 16 ) ).slice( -3 );
|
128
|
+
}
|
129
|
+
return mac;
|
130
|
+
}
|
131
|
+
return str;
|
123
132
|
},
|
124
133
|
// uses natural sort hex compare
|
125
|
-
type: 'numeric'
|
134
|
+
type : 'numeric'
|
126
135
|
});
|
127
136
|
|
128
|
-
})(jQuery);
|
137
|
+
})( jQuery );
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Widget: editable - updated
|
1
|
+
/*! Widget: editable - updated 5/17/2015 (v2.22.0) *//*
|
2
2
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
3
|
* by Rob Garrison
|
4
4
|
*/
|
@@ -8,10 +8,13 @@
|
|
8
8
|
'use strict';
|
9
9
|
|
10
10
|
var tse = $.tablesorter.editable = {
|
11
|
+
namespace : '.tseditable',
|
12
|
+
// last edited class name
|
13
|
+
lastEdited: 'tseditable-last-edited-cell',
|
11
14
|
|
12
15
|
editComplete: function( c, wo, $cell, refocus ) {
|
13
16
|
$cell
|
14
|
-
.removeClass(
|
17
|
+
.removeClass( tse.lastEdited )
|
15
18
|
.trigger( wo.editable_editComplete, [ c ] );
|
16
19
|
// restore focus last cell after updating
|
17
20
|
if ( refocus ) {
|
@@ -25,16 +28,23 @@ var tse = $.tablesorter.editable = {
|
|
25
28
|
setTimeout( function() {
|
26
29
|
// select all text in contenteditable
|
27
30
|
// see http://stackoverflow.com/a/6150060/145346
|
28
|
-
var
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
var range, selection;
|
32
|
+
if ( document.body.createTextRange ) {
|
33
|
+
range = document.body.createTextRange();
|
34
|
+
range.moveToElementText( cell );
|
35
|
+
range.select();
|
36
|
+
} else if ( window.getSelection ) {
|
37
|
+
selection = window.getSelection();
|
38
|
+
range = document.createRange();
|
39
|
+
range.selectNodeContents( cell );
|
40
|
+
selection.removeAllRanges();
|
41
|
+
selection.addRange( range );
|
42
|
+
}
|
33
43
|
}, 100 );
|
34
44
|
},
|
35
45
|
|
36
|
-
|
37
|
-
var indx, tmp,
|
46
|
+
getColumns : function( c, wo ) {
|
47
|
+
var indx, tmp,
|
38
48
|
colIndex = [],
|
39
49
|
cols = [];
|
40
50
|
if ( !wo.editable_columnsArray && $.type( wo.editable_columns ) === 'string' && wo.editable_columns.indexOf( '-' ) >= 0 ) {
|
@@ -61,22 +71,33 @@ var tse = $.tablesorter.editable = {
|
|
61
71
|
wo.editable_columnsArray = colIndex;
|
62
72
|
wo.editable_columnsArray.sort(function(a,b){ return a - b; });
|
63
73
|
}
|
64
|
-
|
74
|
+
return cols;
|
75
|
+
},
|
76
|
+
|
77
|
+
update: function( c, wo ) {
|
78
|
+
var $t,
|
79
|
+
tmp = $( '<div>' ).wrapInner( wo.editable_wrapContent ).children().length || $.isFunction( wo.editable_wrapContent ),
|
80
|
+
cols = tse.getColumns( c, wo ).join( ',' );
|
81
|
+
|
82
|
+
// turn off contenteditable to allow dynamically setting the wo.editable_noEdit
|
83
|
+
// class on table cells - see issue #900
|
84
|
+
c.$tbodies.find( cols ).find( '[contenteditable]' ).prop( 'contenteditable', false );
|
85
|
+
|
65
86
|
// IE does not allow making TR/TH/TD cells directly editable ( issue #404 )
|
66
87
|
// so add a div or span inside ( it's faster than using wrapInner() )
|
67
|
-
c.$tbodies.find( cols
|
88
|
+
c.$tbodies.find( cols ).not( '.' + wo.editable_noEdit ).each( function() {
|
68
89
|
// test for children, if they exist, then make the children editable
|
69
90
|
$t = $( this );
|
70
91
|
|
71
|
-
if ( tmp && $t.children().length === 0 ) {
|
92
|
+
if ( tmp && $t.children( 'div, span' ).length === 0 ) {
|
72
93
|
$t.wrapInner( wo.editable_wrapContent );
|
73
94
|
}
|
74
|
-
if ( $t.children().length ) {
|
75
|
-
// make
|
76
|
-
$t.children().not( '.' + wo.editable_noEdit ).each( function() {
|
95
|
+
if ( $t.children( 'div, span' ).length ) {
|
96
|
+
// make div/span children content editable
|
97
|
+
$t.children( 'div, span' ).not( '.' + wo.editable_noEdit ).each( function() {
|
77
98
|
var $this = $( this );
|
78
99
|
if ( wo.editable_trimContent ) {
|
79
|
-
$this.
|
100
|
+
$this.html( function( i, txt ) {
|
80
101
|
return $.trim( txt );
|
81
102
|
});
|
82
103
|
}
|
@@ -84,7 +105,7 @@ var tse = $.tablesorter.editable = {
|
|
84
105
|
});
|
85
106
|
} else {
|
86
107
|
if ( wo.editable_trimContent ) {
|
87
|
-
$t.
|
108
|
+
$t.html( function( i, txt ) {
|
88
109
|
return $.trim( txt );
|
89
110
|
});
|
90
111
|
}
|
@@ -94,36 +115,45 @@ var tse = $.tablesorter.editable = {
|
|
94
115
|
},
|
95
116
|
|
96
117
|
bindEvents: function( c, wo ) {
|
118
|
+
var namespace = tse.namespace;
|
97
119
|
c.$table
|
98
|
-
.off( ( 'updateComplete pagerComplete '.split( ' ' ).join( '
|
99
|
-
.on( 'updateComplete pagerComplete '.split( ' ' ).join( '
|
120
|
+
.off( ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
|
121
|
+
.on( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ), function() {
|
100
122
|
tse.update( c, c.widgetOptions );
|
101
|
-
})
|
102
|
-
|
103
|
-
|
104
|
-
.
|
105
|
-
.
|
123
|
+
})
|
124
|
+
// prevent sort initialized by user click on the header from changing the row indexing before
|
125
|
+
// updateCell can finish processing the change
|
126
|
+
.children( 'thead' )
|
127
|
+
.add( $( c.namespace + '_extra_table' ).children( 'thead' ) )
|
128
|
+
.off( 'mouseenter' + namespace )
|
129
|
+
.on( 'mouseenter' + namespace, function() {
|
106
130
|
if ( c.$table.data( 'contentFocused' ) ) {
|
107
131
|
// change to 'true' instead of element to allow focusout to process
|
108
132
|
c.$table.data( 'contentFocused', true );
|
109
133
|
$( ':focus' ).trigger( 'focusout' );
|
110
134
|
}
|
111
|
-
})
|
112
|
-
|
135
|
+
});
|
136
|
+
|
137
|
+
c.$tbodies
|
138
|
+
.off( ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
|
139
|
+
.on( 'focus' + namespace, '[contenteditable]', function( e ) {
|
113
140
|
clearTimeout( $( this ).data( 'timer' ) );
|
114
141
|
c.$table.data( 'contentFocused', e.target );
|
115
142
|
var $this = $( this ),
|
116
143
|
selAll = wo.editable_selectAll,
|
117
144
|
column = $this.closest( 'td' ).index(),
|
118
|
-
txt =
|
119
|
-
if ( wo.
|
120
|
-
|
121
|
-
|
122
|
-
|
145
|
+
txt = $this.html();
|
146
|
+
if ( wo.editable_trimContent ) {
|
147
|
+
txt = $.trim( txt );
|
148
|
+
}
|
149
|
+
// prevent enter from adding into the content
|
150
|
+
$this
|
151
|
+
.off( 'keydown' + namespace )
|
152
|
+
.on( 'keydown' + namespace, function( e ){
|
153
|
+
if ( wo.editable_enterToAccept && e.which === 13 ) {
|
123
154
|
e.preventDefault();
|
124
155
|
}
|
125
156
|
});
|
126
|
-
}
|
127
157
|
$this.data({ before : txt, original: txt });
|
128
158
|
|
129
159
|
if ( typeof wo.editable_focused === 'function' ) {
|
@@ -140,16 +170,19 @@ var tse = $.tablesorter.editable = {
|
|
140
170
|
}
|
141
171
|
}
|
142
172
|
})
|
143
|
-
.on( 'blur focusout keydown '.split( ' ' ).join( '
|
173
|
+
.on( 'blur focusout keydown '.split( ' ' ).join( namespace + ' ' ), '[contenteditable]', function( e ) {
|
144
174
|
if ( !c.$table.data( 'contentFocused' ) ) { return; }
|
145
175
|
var t, validate,
|
146
176
|
valid = false,
|
147
177
|
$this = $( e.target ),
|
148
|
-
txt =
|
178
|
+
txt = $this.html(),
|
149
179
|
column = $this.closest( 'td' ).index();
|
180
|
+
if ( wo.editable_trimContent ) {
|
181
|
+
txt = $.trim( txt );
|
182
|
+
}
|
150
183
|
if ( e.which === 27 ) {
|
151
184
|
// user cancelled
|
152
|
-
$this.html(
|
185
|
+
$this.html( $this.data( 'original' ) ).trigger( 'blur' + namespace );
|
153
186
|
c.$table.data( 'contentFocused', false );
|
154
187
|
return false;
|
155
188
|
}
|
@@ -168,10 +201,10 @@ var tse = $.tablesorter.editable = {
|
|
168
201
|
}
|
169
202
|
|
170
203
|
if ( t && valid !== false ) {
|
171
|
-
c.$table.find( '.
|
204
|
+
c.$table.find( '.' + tse.lastEdited ).removeClass( tse.lastEdited );
|
172
205
|
$this
|
173
|
-
.addClass(
|
174
|
-
.html(
|
206
|
+
.addClass( tse.lastEdited )
|
207
|
+
.html( valid )
|
175
208
|
.data( 'before', valid )
|
176
209
|
.data( 'original', valid )
|
177
210
|
.trigger( 'change' );
|
@@ -179,11 +212,11 @@ var tse = $.tablesorter.editable = {
|
|
179
212
|
if ( wo.editable_autoResort ) {
|
180
213
|
setTimeout( function() {
|
181
214
|
c.$table.trigger( 'sorton', [ c.sortList, function() {
|
182
|
-
tse.editComplete( c, wo, c.$table.find( '.
|
215
|
+
tse.editComplete( c, wo, c.$table.find( '.' + tse.lastEdited ), true );
|
183
216
|
}, true ] );
|
184
217
|
}, 10 );
|
185
218
|
} else {
|
186
|
-
tse.editComplete( c, wo, c.$table.find( '.
|
219
|
+
tse.editComplete( c, wo, c.$table.find( '.' + tse.lastEdited ) );
|
187
220
|
}
|
188
221
|
} ] );
|
189
222
|
return false;
|
@@ -192,13 +225,28 @@ var tse = $.tablesorter.editable = {
|
|
192
225
|
clearTimeout( $this.data( 'timer' ) );
|
193
226
|
$this.data( 'timer', setTimeout( function() {
|
194
227
|
if ( $.isFunction( wo.editable_blur ) ) {
|
195
|
-
|
228
|
+
txt = $this.html();
|
229
|
+
wo.editable_blur( wo.editable_trimContent ? $.trim( txt ) : txt, column, $this );
|
196
230
|
}
|
197
231
|
}, 100 ) );
|
198
232
|
// restore original content on blur
|
199
|
-
$this.html(
|
233
|
+
$this.html( $this.data( 'original' ) );
|
200
234
|
}
|
201
235
|
});
|
236
|
+
},
|
237
|
+
destroy : function( c, wo ) {
|
238
|
+
var namespace = tse.namespace,
|
239
|
+
cols = tse.getColumns( c, wo ),
|
240
|
+
|
241
|
+
tmp = ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
|
242
|
+
c.$table.off( tmp );
|
243
|
+
|
244
|
+
tmp = ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
|
245
|
+
c.$tbodies
|
246
|
+
.off( tmp )
|
247
|
+
.find( cols.join( ',' ) )
|
248
|
+
.find( '[contenteditable]' )
|
249
|
+
.prop( 'contenteditable', false );
|
202
250
|
}
|
203
251
|
|
204
252
|
};
|
@@ -223,6 +271,11 @@ var tse = $.tablesorter.editable = {
|
|
223
271
|
if ( !wo.editable_columns.length ) { return; }
|
224
272
|
tse.update( c, wo );
|
225
273
|
tse.bindEvents( c, wo );
|
274
|
+
},
|
275
|
+
remove : function( table, c, wo, refreshing ) {
|
276
|
+
if ( !refreshing ) {
|
277
|
+
tse.destroy( c, wo ) ;
|
278
|
+
}
|
226
279
|
}
|
227
280
|
});
|
228
281
|
|