datatables.net-select 1.6.2 → 2.0.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.
- package/js/dataTables.select.js +733 -539
- package/js/dataTables.select.min.js +2 -2
- package/js/dataTables.select.min.mjs +2 -2
- package/js/dataTables.select.mjs +736 -539
- package/package.json +2 -2
- package/types/types.d.ts +4 -4
package/js/dataTables.select.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Select for DataTables
|
|
1
|
+
/*! Select for DataTables 2.0.0
|
|
2
2
|
* © SpryMedia Ltd - datatables.net/license/mit
|
|
3
3
|
*/
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
if (typeof window
|
|
21
|
+
if (typeof window === 'undefined') {
|
|
22
22
|
module.exports = function (root, $) {
|
|
23
23
|
if ( ! root ) {
|
|
24
24
|
// CommonJS environments without a window global must pass a
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
// Browser
|
|
44
44
|
factory( jQuery, window, document );
|
|
45
45
|
}
|
|
46
|
-
}(function( $, window, document
|
|
46
|
+
}(function( $, window, document ) {
|
|
47
47
|
'use strict';
|
|
48
48
|
var DataTable = $.fn.dataTable;
|
|
49
49
|
|
|
@@ -52,69 +52,70 @@ var DataTable = $.fn.dataTable;
|
|
|
52
52
|
// Version information for debugger
|
|
53
53
|
DataTable.select = {};
|
|
54
54
|
|
|
55
|
-
DataTable.select.version = '
|
|
55
|
+
DataTable.select.version = '2.0.0';
|
|
56
56
|
|
|
57
|
-
DataTable.select.init = function (
|
|
57
|
+
DataTable.select.init = function (dt) {
|
|
58
58
|
var ctx = dt.settings()[0];
|
|
59
59
|
|
|
60
|
+
if (!DataTable.versionCheck('2')) {
|
|
61
|
+
throw 'Warning: Select requires DataTables 2 or newer';
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
if (ctx._select) {
|
|
61
65
|
return;
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
var savedSelected = dt.state.loaded();
|
|
65
69
|
|
|
66
|
-
var selectAndSave = function(e, settings, data) {
|
|
67
|
-
if(data === null || data.select === undefined) {
|
|
70
|
+
var selectAndSave = function (e, settings, data) {
|
|
71
|
+
if (data === null || data.select === undefined) {
|
|
68
72
|
return;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
// Clear any currently selected rows, before restoring state
|
|
72
76
|
// None will be selected on first initialisation
|
|
73
|
-
if (dt.rows({selected: true}).any()) {
|
|
77
|
+
if (dt.rows({ selected: true }).any()) {
|
|
74
78
|
dt.rows().deselect();
|
|
75
79
|
}
|
|
76
80
|
if (data.select.rows !== undefined) {
|
|
77
81
|
dt.rows(data.select.rows).select();
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
if (dt.columns({selected: true}).any()) {
|
|
84
|
+
if (dt.columns({ selected: true }).any()) {
|
|
81
85
|
dt.columns().deselect();
|
|
82
86
|
}
|
|
83
87
|
if (data.select.columns !== undefined) {
|
|
84
88
|
dt.columns(data.select.columns).select();
|
|
85
89
|
}
|
|
86
90
|
|
|
87
|
-
if (dt.cells({selected: true}).any()) {
|
|
91
|
+
if (dt.cells({ selected: true }).any()) {
|
|
88
92
|
dt.cells().deselect();
|
|
89
93
|
}
|
|
90
94
|
if (data.select.cells !== undefined) {
|
|
91
|
-
for(var i = 0; i < data.select.cells.length; i++) {
|
|
95
|
+
for (var i = 0; i < data.select.cells.length; i++) {
|
|
92
96
|
dt.cell(data.select.cells[i].row, data.select.cells[i].column).select();
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
dt.state.save();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
dt
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
})
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
dt.on('stateSaveParams', function (e, settings, data) {
|
|
104
|
+
data.select = {};
|
|
105
|
+
data.select.rows = dt.rows({ selected: true }).ids(true).toArray();
|
|
106
|
+
data.select.columns = dt.columns({ selected: true })[0];
|
|
107
|
+
data.select.cells = dt.cells({ selected: true })[0].map(function (coords) {
|
|
108
|
+
return { row: dt.row(coords.row).id(true), column: coords.column };
|
|
109
|
+
});
|
|
110
|
+
})
|
|
108
111
|
.on('stateLoadParams', selectAndSave)
|
|
109
|
-
.one('init', function() {
|
|
112
|
+
.one('init', function () {
|
|
110
113
|
selectAndSave(undefined, undefined, savedSelected);
|
|
111
114
|
});
|
|
112
115
|
|
|
113
116
|
var init = ctx.oInit.select;
|
|
114
117
|
var defaults = DataTable.defaults.select;
|
|
115
|
-
var opts = init === undefined ?
|
|
116
|
-
defaults :
|
|
117
|
-
init;
|
|
118
|
+
var opts = init === undefined ? defaults : init;
|
|
118
119
|
|
|
119
120
|
// Set defaults
|
|
120
121
|
var items = 'row';
|
|
@@ -124,37 +125,40 @@ DataTable.select.init = function ( dt ) {
|
|
|
124
125
|
var info = true;
|
|
125
126
|
var selector = 'td, th';
|
|
126
127
|
var className = 'selected';
|
|
128
|
+
var headerCheckbox = true;
|
|
127
129
|
var setStyle = false;
|
|
128
130
|
|
|
129
|
-
ctx._select = {
|
|
131
|
+
ctx._select = {
|
|
132
|
+
infoEls: []
|
|
133
|
+
};
|
|
130
134
|
|
|
131
135
|
// Initialisation customisations
|
|
132
|
-
if (
|
|
136
|
+
if (opts === true) {
|
|
133
137
|
style = 'os';
|
|
134
138
|
setStyle = true;
|
|
135
139
|
}
|
|
136
|
-
else if (
|
|
140
|
+
else if (typeof opts === 'string') {
|
|
137
141
|
style = opts;
|
|
138
142
|
setStyle = true;
|
|
139
143
|
}
|
|
140
|
-
else if (
|
|
141
|
-
if (
|
|
144
|
+
else if ($.isPlainObject(opts)) {
|
|
145
|
+
if (opts.blurable !== undefined) {
|
|
142
146
|
blurable = opts.blurable;
|
|
143
147
|
}
|
|
144
|
-
|
|
145
|
-
if (
|
|
148
|
+
|
|
149
|
+
if (opts.toggleable !== undefined) {
|
|
146
150
|
toggleable = opts.toggleable;
|
|
147
151
|
}
|
|
148
152
|
|
|
149
|
-
if (
|
|
153
|
+
if (opts.info !== undefined) {
|
|
150
154
|
info = opts.info;
|
|
151
155
|
}
|
|
152
156
|
|
|
153
|
-
if (
|
|
157
|
+
if (opts.items !== undefined) {
|
|
154
158
|
items = opts.items;
|
|
155
159
|
}
|
|
156
160
|
|
|
157
|
-
if (
|
|
161
|
+
if (opts.style !== undefined) {
|
|
158
162
|
style = opts.style;
|
|
159
163
|
setStyle = true;
|
|
160
164
|
}
|
|
@@ -163,40 +167,41 @@ DataTable.select.init = function ( dt ) {
|
|
|
163
167
|
setStyle = true;
|
|
164
168
|
}
|
|
165
169
|
|
|
166
|
-
if (
|
|
170
|
+
if (opts.selector !== undefined) {
|
|
167
171
|
selector = opts.selector;
|
|
168
172
|
}
|
|
169
173
|
|
|
170
|
-
if (
|
|
174
|
+
if (opts.className !== undefined) {
|
|
171
175
|
className = opts.className;
|
|
172
176
|
}
|
|
177
|
+
|
|
178
|
+
if (opts.headerCheckbox !== undefined) {
|
|
179
|
+
headerCheckbox = opts.headerCheckbox;
|
|
180
|
+
}
|
|
173
181
|
}
|
|
174
182
|
|
|
175
|
-
dt.select.selector(
|
|
176
|
-
dt.select.items(
|
|
177
|
-
dt.select.style(
|
|
178
|
-
dt.select.blurable(
|
|
179
|
-
dt.select.toggleable(
|
|
180
|
-
dt.select.info(
|
|
183
|
+
dt.select.selector(selector);
|
|
184
|
+
dt.select.items(items);
|
|
185
|
+
dt.select.style(style);
|
|
186
|
+
dt.select.blurable(blurable);
|
|
187
|
+
dt.select.toggleable(toggleable);
|
|
188
|
+
dt.select.info(info);
|
|
181
189
|
ctx._select.className = className;
|
|
182
190
|
|
|
183
|
-
|
|
184
|
-
// Sort table based on selected rows. Requires Select Datatables extension
|
|
185
|
-
$.fn.dataTable.ext.order['select-checkbox'] = function ( settings, col ) {
|
|
186
|
-
return this.api().column( col, {order: 'index'} ).nodes().map( function ( td ) {
|
|
187
|
-
if ( settings._select.items === 'row' ) {
|
|
188
|
-
return $( td ).parent().hasClass( settings._select.className );
|
|
189
|
-
} else if ( settings._select.items === 'cell' ) {
|
|
190
|
-
return $( td ).hasClass( settings._select.className );
|
|
191
|
-
}
|
|
192
|
-
return false;
|
|
193
|
-
});
|
|
194
|
-
};
|
|
195
|
-
|
|
196
191
|
// If the init options haven't enabled select, but there is a selectable
|
|
197
192
|
// class name, then enable
|
|
198
|
-
if (
|
|
199
|
-
dt.select.style(
|
|
193
|
+
if (!setStyle && $(dt.table().node()).hasClass('selectable')) {
|
|
194
|
+
dt.select.style('os');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Insert a checkbox into the header if needed - might need to wait
|
|
198
|
+
// for init complete, or it might already be done
|
|
199
|
+
if (headerCheckbox) {
|
|
200
|
+
initCheckboxHeader(dt);
|
|
201
|
+
|
|
202
|
+
dt.on('init', function () {
|
|
203
|
+
initCheckboxHeader(dt);
|
|
204
|
+
});
|
|
200
205
|
}
|
|
201
206
|
};
|
|
202
207
|
|
|
@@ -249,6 +254,7 @@ The `_select` object contains the following properties:
|
|
|
249
254
|
on the row
|
|
250
255
|
info:boolean - If the selection summary should be shown in the table
|
|
251
256
|
information elements
|
|
257
|
+
infoEls:element[] - List of HTML elements with info elements for a table
|
|
252
258
|
}
|
|
253
259
|
```
|
|
254
260
|
|
|
@@ -264,7 +270,6 @@ handler that will select the items using the API methods.
|
|
|
264
270
|
|
|
265
271
|
*/
|
|
266
272
|
|
|
267
|
-
|
|
268
273
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
269
274
|
* Local functions
|
|
270
275
|
*/
|
|
@@ -277,84 +282,87 @@ handler that will select the items using the API methods.
|
|
|
277
282
|
* in the visible grid rather than by index in sequence. For example, if you
|
|
278
283
|
* click first in cell 1-1 and then shift click in 2-2 - cells 1-2 and 2-1
|
|
279
284
|
* should also be selected (and not 1-3, 1-4. etc)
|
|
280
|
-
*
|
|
285
|
+
*
|
|
281
286
|
* @param {DataTable.Api} dt DataTable
|
|
282
287
|
* @param {object} idx Cell index to select to
|
|
283
288
|
* @param {object} last Cell index to select from
|
|
284
289
|
* @private
|
|
285
290
|
*/
|
|
286
|
-
function cellRange(
|
|
287
|
-
{
|
|
291
|
+
function cellRange(dt, idx, last) {
|
|
288
292
|
var indexes;
|
|
289
293
|
var columnIndexes;
|
|
290
294
|
var rowIndexes;
|
|
291
|
-
var selectColumns = function (
|
|
292
|
-
if (
|
|
295
|
+
var selectColumns = function (start, end) {
|
|
296
|
+
if (start > end) {
|
|
293
297
|
var tmp = end;
|
|
294
298
|
end = start;
|
|
295
299
|
start = tmp;
|
|
296
300
|
}
|
|
297
|
-
|
|
301
|
+
|
|
298
302
|
var record = false;
|
|
299
|
-
return dt
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return true;
|
|
307
|
-
}
|
|
303
|
+
return dt
|
|
304
|
+
.columns(':visible')
|
|
305
|
+
.indexes()
|
|
306
|
+
.filter(function (i) {
|
|
307
|
+
if (i === start) {
|
|
308
|
+
record = true;
|
|
309
|
+
}
|
|
308
310
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
if (i === end) {
|
|
312
|
+
// not else if, as start might === end
|
|
313
|
+
record = false;
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return record;
|
|
318
|
+
});
|
|
311
319
|
};
|
|
312
320
|
|
|
313
|
-
var selectRows = function (
|
|
314
|
-
var indexes = dt.rows(
|
|
321
|
+
var selectRows = function (start, end) {
|
|
322
|
+
var indexes = dt.rows({ search: 'applied' }).indexes();
|
|
315
323
|
|
|
316
324
|
// Which comes first - might need to swap
|
|
317
|
-
if (
|
|
325
|
+
if (indexes.indexOf(start) > indexes.indexOf(end)) {
|
|
318
326
|
var tmp = end;
|
|
319
327
|
end = start;
|
|
320
328
|
start = tmp;
|
|
321
329
|
}
|
|
322
330
|
|
|
323
331
|
var record = false;
|
|
324
|
-
return indexes.filter(
|
|
325
|
-
if (
|
|
332
|
+
return indexes.filter(function (i) {
|
|
333
|
+
if (i === start) {
|
|
326
334
|
record = true;
|
|
327
335
|
}
|
|
328
|
-
|
|
329
|
-
if (
|
|
336
|
+
|
|
337
|
+
if (i === end) {
|
|
330
338
|
record = false;
|
|
331
339
|
return true;
|
|
332
340
|
}
|
|
333
341
|
|
|
334
342
|
return record;
|
|
335
|
-
}
|
|
343
|
+
});
|
|
336
344
|
};
|
|
337
345
|
|
|
338
|
-
if (
|
|
346
|
+
if (!dt.cells({ selected: true }).any() && !last) {
|
|
339
347
|
// select from the top left cell to this one
|
|
340
|
-
columnIndexes = selectColumns(
|
|
341
|
-
rowIndexes = selectRows(
|
|
348
|
+
columnIndexes = selectColumns(0, idx.column);
|
|
349
|
+
rowIndexes = selectRows(0, idx.row);
|
|
342
350
|
}
|
|
343
351
|
else {
|
|
344
352
|
// Get column indexes between old and new
|
|
345
|
-
columnIndexes = selectColumns(
|
|
346
|
-
rowIndexes = selectRows(
|
|
353
|
+
columnIndexes = selectColumns(last.column, idx.column);
|
|
354
|
+
rowIndexes = selectRows(last.row, idx.row);
|
|
347
355
|
}
|
|
348
356
|
|
|
349
|
-
indexes = dt.cells(
|
|
357
|
+
indexes = dt.cells(rowIndexes, columnIndexes).flatten();
|
|
350
358
|
|
|
351
|
-
if (
|
|
359
|
+
if (!dt.cells(idx, { selected: true }).any()) {
|
|
352
360
|
// Select range
|
|
353
|
-
dt.cells(
|
|
361
|
+
dt.cells(indexes).select();
|
|
354
362
|
}
|
|
355
363
|
else {
|
|
356
364
|
// Deselect range
|
|
357
|
-
dt.cells(
|
|
365
|
+
dt.cells(indexes).deselect();
|
|
358
366
|
}
|
|
359
367
|
}
|
|
360
368
|
|
|
@@ -364,17 +372,16 @@ function cellRange( dt, idx, last )
|
|
|
364
372
|
* @param {DataTable.Api} dt DataTable to remove events from
|
|
365
373
|
* @private
|
|
366
374
|
*/
|
|
367
|
-
function disableMouseSelection(
|
|
368
|
-
{
|
|
375
|
+
function disableMouseSelection(dt) {
|
|
369
376
|
var ctx = dt.settings()[0];
|
|
370
377
|
var selector = ctx._select.selector;
|
|
371
378
|
|
|
372
|
-
$(
|
|
373
|
-
.off(
|
|
374
|
-
.off(
|
|
375
|
-
.off(
|
|
379
|
+
$(dt.table().container())
|
|
380
|
+
.off('mousedown.dtSelect', selector)
|
|
381
|
+
.off('mouseup.dtSelect', selector)
|
|
382
|
+
.off('click.dtSelect', selector);
|
|
376
383
|
|
|
377
|
-
$('body').off(
|
|
384
|
+
$('body').off('click.dtSelect' + _safeId(dt.table().node()));
|
|
378
385
|
}
|
|
379
386
|
|
|
380
387
|
/**
|
|
@@ -383,121 +390,123 @@ function disableMouseSelection( dt )
|
|
|
383
390
|
* @param {DataTable.Api} dt DataTable to remove events from
|
|
384
391
|
* @private
|
|
385
392
|
*/
|
|
386
|
-
function enableMouseSelection
|
|
387
|
-
|
|
388
|
-
var container = $( dt.table().container() );
|
|
393
|
+
function enableMouseSelection(dt) {
|
|
394
|
+
var container = $(dt.table().container());
|
|
389
395
|
var ctx = dt.settings()[0];
|
|
390
396
|
var selector = ctx._select.selector;
|
|
391
397
|
var matchSelection;
|
|
392
398
|
|
|
393
399
|
container
|
|
394
|
-
.on(
|
|
400
|
+
.on('mousedown.dtSelect', selector, function (e) {
|
|
395
401
|
// Disallow text selection for shift clicking on the table so multi
|
|
396
402
|
// element selection doesn't look terrible!
|
|
397
|
-
if (
|
|
403
|
+
if (e.shiftKey || e.metaKey || e.ctrlKey) {
|
|
398
404
|
container
|
|
399
|
-
.css(
|
|
405
|
+
.css('-moz-user-select', 'none')
|
|
400
406
|
.one('selectstart.dtSelect', selector, function () {
|
|
401
407
|
return false;
|
|
402
|
-
}
|
|
408
|
+
});
|
|
403
409
|
}
|
|
404
410
|
|
|
405
|
-
if (
|
|
411
|
+
if (window.getSelection) {
|
|
406
412
|
matchSelection = window.getSelection();
|
|
407
413
|
}
|
|
408
|
-
}
|
|
409
|
-
.on(
|
|
414
|
+
})
|
|
415
|
+
.on('mouseup.dtSelect', selector, function () {
|
|
410
416
|
// Allow text selection to occur again, Mozilla style (tested in FF
|
|
411
417
|
// 35.0.1 - still required)
|
|
412
|
-
container.css(
|
|
413
|
-
}
|
|
414
|
-
.on(
|
|
418
|
+
container.css('-moz-user-select', '');
|
|
419
|
+
})
|
|
420
|
+
.on('click.dtSelect', selector, function (e) {
|
|
415
421
|
var items = dt.select.items();
|
|
416
422
|
var idx;
|
|
417
423
|
|
|
418
424
|
// If text was selected (click and drag), then we shouldn't change
|
|
419
425
|
// the row's selected state
|
|
420
|
-
if (
|
|
426
|
+
if (matchSelection) {
|
|
421
427
|
var selection = window.getSelection();
|
|
422
428
|
|
|
423
429
|
// If the element that contains the selection is not in the table, we can ignore it
|
|
424
430
|
// This can happen if the developer selects text from the click event
|
|
425
|
-
if (
|
|
426
|
-
|
|
431
|
+
if (
|
|
432
|
+
!selection.anchorNode ||
|
|
433
|
+
$(selection.anchorNode).closest('table')[0] === dt.table().node()
|
|
434
|
+
) {
|
|
435
|
+
if (selection !== matchSelection) {
|
|
427
436
|
return;
|
|
428
437
|
}
|
|
429
438
|
}
|
|
430
439
|
}
|
|
431
440
|
|
|
432
441
|
var ctx = dt.settings()[0];
|
|
433
|
-
var
|
|
442
|
+
var container = dt.table().container();
|
|
434
443
|
|
|
435
444
|
// Ignore clicks inside a sub-table
|
|
436
|
-
if (
|
|
445
|
+
if ($(e.target).closest('div.dt-container')[0] != container) {
|
|
437
446
|
return;
|
|
438
447
|
}
|
|
439
448
|
|
|
440
|
-
var cell = dt.cell(
|
|
449
|
+
var cell = dt.cell($(e.target).closest('td, th'));
|
|
441
450
|
|
|
442
451
|
// Check the cell actually belongs to the host DataTable (so child
|
|
443
452
|
// rows, etc, are ignored)
|
|
444
|
-
if (
|
|
453
|
+
if (!cell.any()) {
|
|
445
454
|
return;
|
|
446
455
|
}
|
|
447
456
|
|
|
448
457
|
var event = $.Event('user-select.dt');
|
|
449
|
-
eventTrigger(
|
|
458
|
+
eventTrigger(dt, event, [items, cell, e]);
|
|
450
459
|
|
|
451
|
-
if (
|
|
460
|
+
if (event.isDefaultPrevented()) {
|
|
452
461
|
return;
|
|
453
462
|
}
|
|
454
463
|
|
|
455
464
|
var cellIndex = cell.index();
|
|
456
|
-
if (
|
|
465
|
+
if (items === 'row') {
|
|
457
466
|
idx = cellIndex.row;
|
|
458
|
-
typeSelect(
|
|
467
|
+
typeSelect(e, dt, ctx, 'row', idx);
|
|
459
468
|
}
|
|
460
|
-
else if (
|
|
469
|
+
else if (items === 'column') {
|
|
461
470
|
idx = cell.index().column;
|
|
462
|
-
typeSelect(
|
|
471
|
+
typeSelect(e, dt, ctx, 'column', idx);
|
|
463
472
|
}
|
|
464
|
-
else if (
|
|
473
|
+
else if (items === 'cell') {
|
|
465
474
|
idx = cell.index();
|
|
466
|
-
typeSelect(
|
|
475
|
+
typeSelect(e, dt, ctx, 'cell', idx);
|
|
467
476
|
}
|
|
468
477
|
|
|
469
478
|
ctx._select_lastCell = cellIndex;
|
|
470
|
-
}
|
|
479
|
+
});
|
|
471
480
|
|
|
472
481
|
// Blurable
|
|
473
|
-
$('body').on(
|
|
474
|
-
if (
|
|
482
|
+
$('body').on('click.dtSelect' + _safeId(dt.table().node()), function (e) {
|
|
483
|
+
if (ctx._select.blurable) {
|
|
475
484
|
// If the click was inside the DataTables container, don't blur
|
|
476
|
-
if (
|
|
485
|
+
if ($(e.target).parents().filter(dt.table().container()).length) {
|
|
477
486
|
return;
|
|
478
487
|
}
|
|
479
488
|
|
|
480
489
|
// Ignore elements which have been removed from the DOM (i.e. paging
|
|
481
490
|
// buttons)
|
|
482
|
-
if (
|
|
483
|
-
|
|
491
|
+
if ($(e.target).parents('html').length === 0) {
|
|
492
|
+
return;
|
|
484
493
|
}
|
|
485
494
|
|
|
486
495
|
// Don't blur in Editor form
|
|
487
|
-
if (
|
|
496
|
+
if ($(e.target).parents('div.DTE').length) {
|
|
488
497
|
return;
|
|
489
498
|
}
|
|
490
499
|
|
|
491
500
|
var event = $.Event('select-blur.dt');
|
|
492
|
-
eventTrigger(
|
|
501
|
+
eventTrigger(dt, event, [e.target, e]);
|
|
493
502
|
|
|
494
|
-
if (
|
|
503
|
+
if (event.isDefaultPrevented()) {
|
|
495
504
|
return;
|
|
496
505
|
}
|
|
497
506
|
|
|
498
|
-
clear(
|
|
507
|
+
clear(ctx, true);
|
|
499
508
|
}
|
|
500
|
-
}
|
|
509
|
+
});
|
|
501
510
|
}
|
|
502
511
|
|
|
503
512
|
/**
|
|
@@ -510,70 +519,125 @@ function enableMouseSelection ( dt )
|
|
|
510
519
|
* triggering
|
|
511
520
|
* @private
|
|
512
521
|
*/
|
|
513
|
-
function eventTrigger
|
|
514
|
-
{
|
|
515
|
-
if ( any && ! api.flatten().length ) {
|
|
522
|
+
function eventTrigger(api, type, args, any) {
|
|
523
|
+
if (any && !api.flatten().length) {
|
|
516
524
|
return;
|
|
517
525
|
}
|
|
518
526
|
|
|
519
|
-
if (
|
|
520
|
-
type = type +'.dt';
|
|
527
|
+
if (typeof type === 'string') {
|
|
528
|
+
type = type + '.dt';
|
|
521
529
|
}
|
|
522
530
|
|
|
523
|
-
args.unshift(
|
|
531
|
+
args.unshift(api);
|
|
524
532
|
|
|
525
|
-
$(api.table().node()).trigger(
|
|
533
|
+
$(api.table().node()).trigger(type, args);
|
|
526
534
|
}
|
|
527
535
|
|
|
528
536
|
/**
|
|
529
537
|
* Update the information element of the DataTable showing information about the
|
|
530
538
|
* items selected. This is done by adding tags to the existing text
|
|
531
|
-
*
|
|
539
|
+
*
|
|
532
540
|
* @param {DataTable.Api} api DataTable to update
|
|
533
541
|
* @private
|
|
534
542
|
*/
|
|
535
|
-
function info
|
|
536
|
-
{
|
|
537
|
-
var ctx = api.settings()[0];
|
|
538
|
-
|
|
539
|
-
if ( ! ctx._select.info || ! ctx.aanFeatures.i ) {
|
|
543
|
+
function info(api, node) {
|
|
544
|
+
if (api.select.style() === 'api' || api.select.info() === false) {
|
|
540
545
|
return;
|
|
541
546
|
}
|
|
542
547
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
548
|
+
var rows = api.rows({ selected: true }).flatten().length;
|
|
549
|
+
var columns = api.columns({ selected: true }).flatten().length;
|
|
550
|
+
var cells = api.cells({ selected: true }).flatten().length;
|
|
551
|
+
|
|
552
|
+
var add = function (el, name, num) {
|
|
553
|
+
el.append(
|
|
554
|
+
$('<span class="select-item"/>').append(
|
|
555
|
+
api.i18n(
|
|
556
|
+
'select.' + name + 's',
|
|
557
|
+
{ _: '%d ' + name + 's selected', 0: '', 1: '1 ' + name + ' selected' },
|
|
558
|
+
num
|
|
559
|
+
)
|
|
560
|
+
)
|
|
561
|
+
);
|
|
562
|
+
};
|
|
546
563
|
|
|
547
|
-
var
|
|
548
|
-
var
|
|
549
|
-
var cells = api.cells( { selected: true } ).flatten().length;
|
|
564
|
+
var el = $(node);
|
|
565
|
+
var output = $('<span class="select-info"/>');
|
|
550
566
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
{ _: '%d '+name+'s selected', 0: '', 1: '1 '+name+' selected' },
|
|
555
|
-
num
|
|
556
|
-
) ) );
|
|
557
|
-
};
|
|
567
|
+
add(output, 'row', rows);
|
|
568
|
+
add(output, 'column', columns);
|
|
569
|
+
add(output, 'cell', cells);
|
|
558
570
|
|
|
559
|
-
|
|
560
|
-
$.each( ctx.aanFeatures.i, function ( i, el ) {
|
|
561
|
-
el = $(el);
|
|
571
|
+
var existing = el.children('span.select-info');
|
|
562
572
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
add( output, 'cell', cells );
|
|
573
|
+
if (existing.length) {
|
|
574
|
+
existing.remove();
|
|
575
|
+
}
|
|
567
576
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
577
|
+
if (output.text() !== '') {
|
|
578
|
+
el.append(output);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
572
581
|
|
|
573
|
-
|
|
574
|
-
|
|
582
|
+
/**
|
|
583
|
+
* Add a checkbox to the header for checkbox columns, allowing all rows to
|
|
584
|
+
* be selected, deselected or just to show the state.
|
|
585
|
+
*
|
|
586
|
+
* @param {*} dt API
|
|
587
|
+
*/
|
|
588
|
+
function initCheckboxHeader( dt ) {
|
|
589
|
+
// Find any checkbox column(s)
|
|
590
|
+
dt.columns('.dt-select').every(function () {
|
|
591
|
+
var header = this.header();
|
|
592
|
+
|
|
593
|
+
if (! $('input', header).length) {
|
|
594
|
+
// If no checkbox yet, insert one
|
|
595
|
+
var input = $('<input>')
|
|
596
|
+
.attr({
|
|
597
|
+
class: 'dt-select-checkbox',
|
|
598
|
+
type: 'checkbox',
|
|
599
|
+
'aria-label': dt.i18n('select.aria.headerCheckbox') || 'Select all rows'
|
|
600
|
+
})
|
|
601
|
+
.appendTo(header)
|
|
602
|
+
.on('change', function () {
|
|
603
|
+
if (this.checked) {
|
|
604
|
+
dt.rows({search: 'applied'}).select();
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
dt.rows({selected: true}).deselect();
|
|
608
|
+
}
|
|
609
|
+
})
|
|
610
|
+
.on('click', function (e) {
|
|
611
|
+
e.stopPropagation();
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
// Update the header checkbox's state when the selection in the
|
|
615
|
+
// table changes
|
|
616
|
+
dt.on('draw select deselect', function (e, pass, type) {
|
|
617
|
+
if (type === 'row' || ! type) {
|
|
618
|
+
var count = dt.rows({selected: true}).count();
|
|
619
|
+
var search = dt.rows({search: 'applied', selected: true}).count();
|
|
620
|
+
var available = dt.rows({search: 'applied'}).count();
|
|
621
|
+
|
|
622
|
+
if (search && search <= count && search === available) {
|
|
623
|
+
input
|
|
624
|
+
.prop('checked', true)
|
|
625
|
+
.prop('indeterminate', false);
|
|
626
|
+
}
|
|
627
|
+
else if (search === 0 && count === 0) {
|
|
628
|
+
input
|
|
629
|
+
.prop('checked', false)
|
|
630
|
+
.prop('indeterminate', false);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
input
|
|
634
|
+
.prop('checked', false)
|
|
635
|
+
.prop('indeterminate', true);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
});
|
|
575
639
|
}
|
|
576
|
-
}
|
|
640
|
+
});
|
|
577
641
|
}
|
|
578
642
|
|
|
579
643
|
/**
|
|
@@ -586,41 +650,42 @@ function info ( api )
|
|
|
586
650
|
* @param {DataTable.settings} ctx Settings object to operate on
|
|
587
651
|
* @private
|
|
588
652
|
*/
|
|
589
|
-
function init
|
|
590
|
-
var api = new DataTable.Api(
|
|
653
|
+
function init(ctx) {
|
|
654
|
+
var api = new DataTable.Api(ctx);
|
|
591
655
|
ctx._select_init = true;
|
|
592
656
|
|
|
593
657
|
// Row callback so that classes can be added to rows and cells if the item
|
|
594
658
|
// was selected before the element was created. This will happen with the
|
|
595
659
|
// `deferRender` option enabled.
|
|
596
|
-
//
|
|
660
|
+
//
|
|
597
661
|
// This method of attaching to `aoRowCreatedCallback` is a hack until
|
|
598
662
|
// DataTables has proper events for row manipulation If you are reviewing
|
|
599
663
|
// this code to create your own plug-ins, please do not do this!
|
|
600
|
-
ctx.aoRowCreatedCallback.push( {
|
|
601
|
-
fn: function ( row, data, index ) {
|
|
664
|
+
ctx.aoRowCreatedCallback.push(function (row, data, index) {
|
|
602
665
|
var i, ien;
|
|
603
|
-
var d = ctx.aoData[
|
|
666
|
+
var d = ctx.aoData[index];
|
|
604
667
|
|
|
605
668
|
// Row
|
|
606
|
-
if (
|
|
607
|
-
$(
|
|
669
|
+
if (d._select_selected) {
|
|
670
|
+
$(row).addClass(ctx._select.className);
|
|
608
671
|
}
|
|
609
672
|
|
|
610
673
|
// Cells and columns - if separated out, we would need to do two
|
|
611
674
|
// loops, so it makes sense to combine them into a single one
|
|
612
|
-
for (
|
|
613
|
-
if (
|
|
614
|
-
|
|
675
|
+
for (i = 0, ien = ctx.aoColumns.length; i < ien; i++) {
|
|
676
|
+
if (
|
|
677
|
+
ctx.aoColumns[i]._select_selected ||
|
|
678
|
+
(d._selected_cells && d._selected_cells[i])
|
|
679
|
+
) {
|
|
680
|
+
$(d.anCells[i]).addClass(ctx._select.className);
|
|
615
681
|
}
|
|
616
682
|
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
} );
|
|
683
|
+
}
|
|
684
|
+
);
|
|
620
685
|
|
|
621
686
|
// On Ajax reload we want to reselect all rows which are currently selected,
|
|
622
687
|
// if there is an rowId (i.e. a unique value to identify each row with)
|
|
623
|
-
api.on(
|
|
688
|
+
api.on('preXhr.dt.dtSelect', function (e, settings) {
|
|
624
689
|
if (settings !== api.settings()[0]) {
|
|
625
690
|
// Not triggered by our DataTable!
|
|
626
691
|
return;
|
|
@@ -628,47 +693,64 @@ function init ( ctx ) {
|
|
|
628
693
|
|
|
629
694
|
// note that column selection doesn't need to be cached and then
|
|
630
695
|
// reselected, as they are already selected
|
|
631
|
-
var rows = api
|
|
632
|
-
|
|
633
|
-
|
|
696
|
+
var rows = api
|
|
697
|
+
.rows({ selected: true })
|
|
698
|
+
.ids(true)
|
|
699
|
+
.filter(function (d) {
|
|
700
|
+
return d !== undefined;
|
|
701
|
+
});
|
|
634
702
|
|
|
635
|
-
var cells = api
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
703
|
+
var cells = api
|
|
704
|
+
.cells({ selected: true })
|
|
705
|
+
.eq(0)
|
|
706
|
+
.map(function (cellIdx) {
|
|
707
|
+
var id = api.row(cellIdx.row).id(true);
|
|
708
|
+
return id ? { row: id, column: cellIdx.column } : undefined;
|
|
709
|
+
})
|
|
710
|
+
.filter(function (d) {
|
|
711
|
+
return d !== undefined;
|
|
712
|
+
});
|
|
643
713
|
|
|
644
714
|
// On the next draw, reselect the currently selected items
|
|
645
|
-
api.one(
|
|
646
|
-
api.rows(
|
|
715
|
+
api.one('draw.dt.dtSelect', function () {
|
|
716
|
+
api.rows(rows).select();
|
|
647
717
|
|
|
648
718
|
// `cells` is not a cell index selector, so it needs a loop
|
|
649
|
-
if (
|
|
650
|
-
cells.each(
|
|
651
|
-
api.cells(
|
|
652
|
-
}
|
|
719
|
+
if (cells.any()) {
|
|
720
|
+
cells.each(function (id) {
|
|
721
|
+
api.cells(id.row, id.column).select();
|
|
722
|
+
});
|
|
653
723
|
}
|
|
654
|
-
}
|
|
655
|
-
}
|
|
724
|
+
});
|
|
725
|
+
});
|
|
656
726
|
|
|
657
727
|
// Update the table information element with selected item summary
|
|
658
|
-
api.on(
|
|
659
|
-
info
|
|
728
|
+
api.on('info.dt', function (e, ctx, node) {
|
|
729
|
+
// Store the info node for updating on select / deselect
|
|
730
|
+
if (!ctx._select.infoEls.includes(node)) {
|
|
731
|
+
ctx._select.infoEls.push(node);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
info(api, node);
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
api.on('select.dtSelect.dt deselect.dtSelect.dt', function () {
|
|
738
|
+
ctx._select.infoEls.forEach(function (el) {
|
|
739
|
+
info(api, el);
|
|
740
|
+
});
|
|
741
|
+
|
|
660
742
|
api.state.save();
|
|
661
|
-
}
|
|
743
|
+
});
|
|
662
744
|
|
|
663
745
|
// Clean up and release
|
|
664
|
-
api.on(
|
|
746
|
+
api.on('destroy.dtSelect', function () {
|
|
665
747
|
// Remove class directly rather than calling deselect - which would trigger events
|
|
666
|
-
$(api.rows({selected: true}).nodes()).removeClass(api.settings()[0]._select.className);
|
|
748
|
+
$(api.rows({ selected: true }).nodes()).removeClass(api.settings()[0]._select.className);
|
|
667
749
|
|
|
668
|
-
disableMouseSelection(
|
|
669
|
-
api.off(
|
|
750
|
+
disableMouseSelection(api);
|
|
751
|
+
api.off('.dtSelect');
|
|
670
752
|
$('body').off('.dtSelect' + _safeId(api.table().node()));
|
|
671
|
-
}
|
|
753
|
+
});
|
|
672
754
|
}
|
|
673
755
|
|
|
674
756
|
/**
|
|
@@ -681,38 +763,37 @@ function init ( ctx ) {
|
|
|
681
763
|
* @param {object} last Item index to select from
|
|
682
764
|
* @private
|
|
683
765
|
*/
|
|
684
|
-
function rowColumnRange(
|
|
685
|
-
{
|
|
766
|
+
function rowColumnRange(dt, type, idx, last) {
|
|
686
767
|
// Add a range of rows from the last selected row to this one
|
|
687
|
-
var indexes = dt[type+'s'](
|
|
688
|
-
var idx1 =
|
|
689
|
-
var idx2 =
|
|
768
|
+
var indexes = dt[type + 's']({ search: 'applied' }).indexes();
|
|
769
|
+
var idx1 = indexes.indexOf(last);
|
|
770
|
+
var idx2 = indexes.indexOf(idx);
|
|
690
771
|
|
|
691
|
-
if (
|
|
772
|
+
if (!dt[type + 's']({ selected: true }).any() && idx1 === -1) {
|
|
692
773
|
// select from top to here - slightly odd, but both Windows and Mac OS
|
|
693
774
|
// do this
|
|
694
|
-
indexes.splice(
|
|
775
|
+
indexes.splice(indexes.indexOf(idx) + 1, indexes.length);
|
|
695
776
|
}
|
|
696
777
|
else {
|
|
697
778
|
// reverse so we can shift click 'up' as well as down
|
|
698
|
-
if (
|
|
779
|
+
if (idx1 > idx2) {
|
|
699
780
|
var tmp = idx2;
|
|
700
781
|
idx2 = idx1;
|
|
701
782
|
idx1 = tmp;
|
|
702
783
|
}
|
|
703
784
|
|
|
704
|
-
indexes.splice(
|
|
705
|
-
indexes.splice(
|
|
785
|
+
indexes.splice(idx2 + 1, indexes.length);
|
|
786
|
+
indexes.splice(0, idx1);
|
|
706
787
|
}
|
|
707
788
|
|
|
708
|
-
if (
|
|
789
|
+
if (!dt[type](idx, { selected: true }).any()) {
|
|
709
790
|
// Select range
|
|
710
|
-
dt[type+'s'](
|
|
791
|
+
dt[type + 's'](indexes).select();
|
|
711
792
|
}
|
|
712
793
|
else {
|
|
713
794
|
// Deselect range - need to keep the clicked on row selected
|
|
714
|
-
indexes.splice(
|
|
715
|
-
dt[type+'s'](
|
|
795
|
+
indexes.splice(indexes.indexOf(idx), 1);
|
|
796
|
+
dt[type + 's'](indexes).deselect();
|
|
716
797
|
}
|
|
717
798
|
}
|
|
718
799
|
|
|
@@ -724,14 +805,13 @@ function rowColumnRange( dt, type, idx, last )
|
|
|
724
805
|
* of selection style
|
|
725
806
|
* @private
|
|
726
807
|
*/
|
|
727
|
-
function clear(
|
|
728
|
-
{
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
api.
|
|
733
|
-
api.
|
|
734
|
-
api.cells( { selected: true } ).deselect();
|
|
808
|
+
function clear(ctx, force) {
|
|
809
|
+
if (force || ctx._select.style === 'single') {
|
|
810
|
+
var api = new DataTable.Api(ctx);
|
|
811
|
+
|
|
812
|
+
api.rows({ selected: true }).deselect();
|
|
813
|
+
api.columns({ selected: true }).deselect();
|
|
814
|
+
api.cells({ selected: true }).deselect();
|
|
735
815
|
}
|
|
736
816
|
}
|
|
737
817
|
|
|
@@ -745,72 +825,74 @@ function clear( ctx, force )
|
|
|
745
825
|
* @param {int|object} idx Index of the item to select
|
|
746
826
|
* @private
|
|
747
827
|
*/
|
|
748
|
-
function typeSelect
|
|
749
|
-
{
|
|
828
|
+
function typeSelect(e, dt, ctx, type, idx) {
|
|
750
829
|
var style = dt.select.style();
|
|
751
830
|
var toggleable = dt.select.toggleable();
|
|
752
|
-
var isSelected = dt[type](
|
|
753
|
-
|
|
754
|
-
if (
|
|
831
|
+
var isSelected = dt[type](idx, { selected: true }).any();
|
|
832
|
+
|
|
833
|
+
if (isSelected && !toggleable) {
|
|
755
834
|
return;
|
|
756
835
|
}
|
|
757
836
|
|
|
758
|
-
if (
|
|
759
|
-
if (
|
|
837
|
+
if (style === 'os') {
|
|
838
|
+
if (e.ctrlKey || e.metaKey) {
|
|
760
839
|
// Add or remove from the selection
|
|
761
|
-
dt[type](
|
|
840
|
+
dt[type](idx).select(!isSelected);
|
|
762
841
|
}
|
|
763
|
-
else if (
|
|
764
|
-
if (
|
|
765
|
-
cellRange(
|
|
842
|
+
else if (e.shiftKey) {
|
|
843
|
+
if (type === 'cell') {
|
|
844
|
+
cellRange(dt, idx, ctx._select_lastCell || null);
|
|
766
845
|
}
|
|
767
846
|
else {
|
|
768
|
-
rowColumnRange(
|
|
769
|
-
|
|
770
|
-
|
|
847
|
+
rowColumnRange(
|
|
848
|
+
dt,
|
|
849
|
+
type,
|
|
850
|
+
idx,
|
|
851
|
+
ctx._select_lastCell ? ctx._select_lastCell[type] : null
|
|
771
852
|
);
|
|
772
853
|
}
|
|
773
854
|
}
|
|
774
855
|
else {
|
|
775
856
|
// No cmd or shift click - deselect if selected, or select
|
|
776
857
|
// this row only
|
|
777
|
-
var selected = dt[type+'s'](
|
|
858
|
+
var selected = dt[type + 's']({ selected: true });
|
|
778
859
|
|
|
779
|
-
if (
|
|
780
|
-
dt[type](
|
|
860
|
+
if (isSelected && selected.flatten().length === 1) {
|
|
861
|
+
dt[type](idx).deselect();
|
|
781
862
|
}
|
|
782
863
|
else {
|
|
783
864
|
selected.deselect();
|
|
784
|
-
dt[type](
|
|
865
|
+
dt[type](idx).select();
|
|
785
866
|
}
|
|
786
867
|
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
868
|
+
}
|
|
869
|
+
else if (style == 'multi+shift') {
|
|
870
|
+
if (e.shiftKey) {
|
|
871
|
+
if (type === 'cell') {
|
|
872
|
+
cellRange(dt, idx, ctx._select_lastCell || null);
|
|
791
873
|
}
|
|
792
874
|
else {
|
|
793
|
-
rowColumnRange(
|
|
794
|
-
|
|
795
|
-
|
|
875
|
+
rowColumnRange(
|
|
876
|
+
dt,
|
|
877
|
+
type,
|
|
878
|
+
idx,
|
|
879
|
+
ctx._select_lastCell ? ctx._select_lastCell[type] : null
|
|
796
880
|
);
|
|
797
881
|
}
|
|
798
882
|
}
|
|
799
883
|
else {
|
|
800
|
-
dt[
|
|
884
|
+
dt[type](idx).select(!isSelected);
|
|
801
885
|
}
|
|
802
886
|
}
|
|
803
887
|
else {
|
|
804
|
-
dt[
|
|
888
|
+
dt[type](idx).select(!isSelected);
|
|
805
889
|
}
|
|
806
890
|
}
|
|
807
891
|
|
|
808
|
-
function _safeId(
|
|
892
|
+
function _safeId(node) {
|
|
809
893
|
return node.id.replace(/[^a-zA-Z0-9\-\_]/g, '-');
|
|
810
894
|
}
|
|
811
895
|
|
|
812
|
-
|
|
813
|
-
|
|
814
896
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
815
897
|
* DataTables selectors
|
|
816
898
|
*/
|
|
@@ -818,56 +900,66 @@ function _safeId( node ) {
|
|
|
818
900
|
// row and column are basically identical just assigned to different properties
|
|
819
901
|
// and checking a different array, so we can dynamically create the functions to
|
|
820
902
|
// reduce the code size
|
|
821
|
-
$.each(
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
903
|
+
$.each(
|
|
904
|
+
[
|
|
905
|
+
{ type: 'row', prop: 'aoData' },
|
|
906
|
+
{ type: 'column', prop: 'aoColumns' }
|
|
907
|
+
],
|
|
908
|
+
function (i, o) {
|
|
909
|
+
DataTable.ext.selector[o.type].push(function (settings, opts, indexes) {
|
|
910
|
+
var selected = opts.selected;
|
|
911
|
+
var data;
|
|
912
|
+
var out = [];
|
|
913
|
+
|
|
914
|
+
if (selected !== true && selected !== false) {
|
|
915
|
+
return indexes;
|
|
916
|
+
}
|
|
833
917
|
|
|
834
|
-
|
|
835
|
-
|
|
918
|
+
for (var i = 0, ien = indexes.length; i < ien; i++) {
|
|
919
|
+
data = settings[o.prop][indexes[i]];
|
|
836
920
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
921
|
+
if (
|
|
922
|
+
data && (
|
|
923
|
+
(selected === true && data._select_selected === true) ||
|
|
924
|
+
(selected === false && !data._select_selected)
|
|
925
|
+
)
|
|
926
|
+
) {
|
|
927
|
+
out.push(indexes[i]);
|
|
928
|
+
}
|
|
841
929
|
}
|
|
842
|
-
}
|
|
843
930
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}
|
|
931
|
+
return out;
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
);
|
|
847
935
|
|
|
848
|
-
DataTable.ext.selector.cell.push(
|
|
936
|
+
DataTable.ext.selector.cell.push(function (settings, opts, cells) {
|
|
849
937
|
var selected = opts.selected;
|
|
850
938
|
var rowData;
|
|
851
939
|
var out = [];
|
|
852
940
|
|
|
853
|
-
if (
|
|
941
|
+
if (selected === undefined) {
|
|
854
942
|
return cells;
|
|
855
943
|
}
|
|
856
944
|
|
|
857
|
-
for (
|
|
858
|
-
rowData = settings.aoData[
|
|
859
|
-
|
|
860
|
-
if (
|
|
861
|
-
|
|
945
|
+
for (var i = 0, ien = cells.length; i < ien; i++) {
|
|
946
|
+
rowData = settings.aoData[cells[i].row];
|
|
947
|
+
|
|
948
|
+
if (
|
|
949
|
+
rowData && (
|
|
950
|
+
(selected === true &&
|
|
951
|
+
rowData._selected_cells &&
|
|
952
|
+
rowData._selected_cells[cells[i].column] === true) ||
|
|
953
|
+
(selected === false &&
|
|
954
|
+
(!rowData._selected_cells || !rowData._selected_cells[cells[i].column]))
|
|
955
|
+
)
|
|
862
956
|
) {
|
|
863
|
-
out.push(
|
|
957
|
+
out.push(cells[i]);
|
|
864
958
|
}
|
|
865
959
|
}
|
|
866
960
|
|
|
867
961
|
return out;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
|
|
962
|
+
});
|
|
871
963
|
|
|
872
964
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
873
965
|
* DataTables API
|
|
@@ -880,67 +972,67 @@ DataTable.ext.selector.cell.push( function ( settings, opts, cells ) {
|
|
|
880
972
|
var apiRegister = DataTable.Api.register;
|
|
881
973
|
var apiRegisterPlural = DataTable.Api.registerPlural;
|
|
882
974
|
|
|
883
|
-
apiRegister(
|
|
884
|
-
return this.iterator(
|
|
885
|
-
DataTable.select.init(
|
|
886
|
-
}
|
|
887
|
-
}
|
|
975
|
+
apiRegister('select()', function () {
|
|
976
|
+
return this.iterator('table', function (ctx) {
|
|
977
|
+
DataTable.select.init(new DataTable.Api(ctx));
|
|
978
|
+
});
|
|
979
|
+
});
|
|
888
980
|
|
|
889
|
-
apiRegister(
|
|
890
|
-
if (
|
|
981
|
+
apiRegister('select.blurable()', function (flag) {
|
|
982
|
+
if (flag === undefined) {
|
|
891
983
|
return this.context[0]._select.blurable;
|
|
892
984
|
}
|
|
893
985
|
|
|
894
|
-
return this.iterator(
|
|
986
|
+
return this.iterator('table', function (ctx) {
|
|
895
987
|
ctx._select.blurable = flag;
|
|
896
|
-
}
|
|
897
|
-
}
|
|
988
|
+
});
|
|
989
|
+
});
|
|
898
990
|
|
|
899
|
-
apiRegister(
|
|
900
|
-
if (
|
|
991
|
+
apiRegister('select.toggleable()', function (flag) {
|
|
992
|
+
if (flag === undefined) {
|
|
901
993
|
return this.context[0]._select.toggleable;
|
|
902
994
|
}
|
|
903
995
|
|
|
904
|
-
return this.iterator(
|
|
996
|
+
return this.iterator('table', function (ctx) {
|
|
905
997
|
ctx._select.toggleable = flag;
|
|
906
|
-
}
|
|
907
|
-
}
|
|
998
|
+
});
|
|
999
|
+
});
|
|
908
1000
|
|
|
909
|
-
apiRegister(
|
|
910
|
-
if (
|
|
1001
|
+
apiRegister('select.info()', function (flag) {
|
|
1002
|
+
if (flag === undefined) {
|
|
911
1003
|
return this.context[0]._select.info;
|
|
912
1004
|
}
|
|
913
1005
|
|
|
914
|
-
return this.iterator(
|
|
1006
|
+
return this.iterator('table', function (ctx) {
|
|
915
1007
|
ctx._select.info = flag;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
1008
|
+
});
|
|
1009
|
+
});
|
|
918
1010
|
|
|
919
|
-
apiRegister(
|
|
920
|
-
if (
|
|
1011
|
+
apiRegister('select.items()', function (items) {
|
|
1012
|
+
if (items === undefined) {
|
|
921
1013
|
return this.context[0]._select.items;
|
|
922
1014
|
}
|
|
923
1015
|
|
|
924
|
-
return this.iterator(
|
|
1016
|
+
return this.iterator('table', function (ctx) {
|
|
925
1017
|
ctx._select.items = items;
|
|
926
1018
|
|
|
927
|
-
eventTrigger(
|
|
928
|
-
}
|
|
929
|
-
}
|
|
1019
|
+
eventTrigger(new DataTable.Api(ctx), 'selectItems', [items]);
|
|
1020
|
+
});
|
|
1021
|
+
});
|
|
930
1022
|
|
|
931
1023
|
// Takes effect from the _next_ selection. None disables future selection, but
|
|
932
1024
|
// does not clear the current selection. Use the `deselect` methods for that
|
|
933
|
-
apiRegister(
|
|
934
|
-
if (
|
|
1025
|
+
apiRegister('select.style()', function (style) {
|
|
1026
|
+
if (style === undefined) {
|
|
935
1027
|
return this.context[0]._select.style;
|
|
936
1028
|
}
|
|
937
1029
|
|
|
938
|
-
return this.iterator(
|
|
939
|
-
if (
|
|
940
|
-
DataTable.select.init(
|
|
1030
|
+
return this.iterator('table', function (ctx) {
|
|
1031
|
+
if (!ctx._select) {
|
|
1032
|
+
DataTable.select.init(new DataTable.Api(ctx));
|
|
941
1033
|
}
|
|
942
1034
|
|
|
943
|
-
if (
|
|
1035
|
+
if (!ctx._select_init) {
|
|
944
1036
|
init(ctx);
|
|
945
1037
|
}
|
|
946
1038
|
|
|
@@ -948,144 +1040,161 @@ apiRegister( 'select.style()', function ( style ) {
|
|
|
948
1040
|
|
|
949
1041
|
// Add / remove mouse event handlers. They aren't required when only
|
|
950
1042
|
// API selection is available
|
|
951
|
-
var dt = new DataTable.Api(
|
|
952
|
-
disableMouseSelection(
|
|
953
|
-
|
|
954
|
-
if (
|
|
955
|
-
enableMouseSelection(
|
|
1043
|
+
var dt = new DataTable.Api(ctx);
|
|
1044
|
+
disableMouseSelection(dt);
|
|
1045
|
+
|
|
1046
|
+
if (style !== 'api') {
|
|
1047
|
+
enableMouseSelection(dt);
|
|
956
1048
|
}
|
|
957
1049
|
|
|
958
|
-
eventTrigger(
|
|
959
|
-
}
|
|
960
|
-
}
|
|
1050
|
+
eventTrigger(new DataTable.Api(ctx), 'selectStyle', [style]);
|
|
1051
|
+
});
|
|
1052
|
+
});
|
|
961
1053
|
|
|
962
|
-
apiRegister(
|
|
963
|
-
if (
|
|
1054
|
+
apiRegister('select.selector()', function (selector) {
|
|
1055
|
+
if (selector === undefined) {
|
|
964
1056
|
return this.context[0]._select.selector;
|
|
965
1057
|
}
|
|
966
1058
|
|
|
967
|
-
return this.iterator(
|
|
968
|
-
disableMouseSelection(
|
|
1059
|
+
return this.iterator('table', function (ctx) {
|
|
1060
|
+
disableMouseSelection(new DataTable.Api(ctx));
|
|
969
1061
|
|
|
970
1062
|
ctx._select.selector = selector;
|
|
971
1063
|
|
|
972
|
-
if (
|
|
973
|
-
enableMouseSelection(
|
|
1064
|
+
if (ctx._select.style !== 'api') {
|
|
1065
|
+
enableMouseSelection(new DataTable.Api(ctx));
|
|
974
1066
|
}
|
|
975
|
-
}
|
|
976
|
-
}
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
|
|
1070
|
+
apiRegister('select.last()', function (set) {
|
|
1071
|
+
let ctx = this.context[0];
|
|
977
1072
|
|
|
1073
|
+
if (set) {
|
|
1074
|
+
ctx._select_lastCell = set;
|
|
1075
|
+
return this;
|
|
1076
|
+
}
|
|
978
1077
|
|
|
1078
|
+
return ctx._select_lastCell;
|
|
1079
|
+
});
|
|
979
1080
|
|
|
980
|
-
apiRegisterPlural(
|
|
1081
|
+
apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
981
1082
|
var api = this;
|
|
982
1083
|
|
|
983
|
-
if (
|
|
1084
|
+
if (select === false) {
|
|
984
1085
|
return this.deselect();
|
|
985
1086
|
}
|
|
986
1087
|
|
|
987
|
-
this.iterator(
|
|
988
|
-
clear(
|
|
1088
|
+
this.iterator('row', function (ctx, idx) {
|
|
1089
|
+
clear(ctx);
|
|
1090
|
+
|
|
1091
|
+
// There is a good amount of knowledge of DataTables internals in
|
|
1092
|
+
// this function. It _could_ be done without that, but it would hurt
|
|
1093
|
+
// performance (or DT would need new APIs for this work)
|
|
1094
|
+
var dtData = ctx.aoData[idx];
|
|
1095
|
+
var dtColumns = ctx.aoColumns;
|
|
1096
|
+
|
|
1097
|
+
$(dtData.nTr).addClass(ctx._select.className);
|
|
1098
|
+
dtData._select_selected = true;
|
|
1099
|
+
|
|
1100
|
+
for (var i=0 ; i<dtColumns.length ; i++) {
|
|
1101
|
+
var col = dtColumns[i];
|
|
1102
|
+
|
|
1103
|
+
if (col.sType === 'select-checkbox') {
|
|
1104
|
+
// Make sure the checkbox shows the right state
|
|
1105
|
+
$('input.dt-select-checkbox', dtData.anCells[i]).prop('checked', true);
|
|
989
1106
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1107
|
+
// Invalidate the sort data for this column
|
|
1108
|
+
dtData._aSortData[i] = null;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
993
1112
|
|
|
994
|
-
this.iterator(
|
|
995
|
-
eventTrigger(
|
|
996
|
-
}
|
|
1113
|
+
this.iterator('table', function (ctx, i) {
|
|
1114
|
+
eventTrigger(api, 'select', ['row', api[i]], true);
|
|
1115
|
+
});
|
|
997
1116
|
|
|
998
1117
|
return this;
|
|
999
|
-
}
|
|
1118
|
+
});
|
|
1000
1119
|
|
|
1001
|
-
apiRegister(
|
|
1120
|
+
apiRegister('row().selected()', function () {
|
|
1002
1121
|
var ctx = this.context[0];
|
|
1003
1122
|
|
|
1004
|
-
if (
|
|
1005
|
-
ctx &&
|
|
1006
|
-
this.length &&
|
|
1007
|
-
ctx.aoData[this[0]] &&
|
|
1008
|
-
ctx.aoData[this[0]]._select_selected
|
|
1009
|
-
) {
|
|
1123
|
+
if (ctx && this.length && ctx.aoData[this[0]] && ctx.aoData[this[0]]._select_selected) {
|
|
1010
1124
|
return true;
|
|
1011
1125
|
}
|
|
1012
1126
|
|
|
1013
1127
|
return false;
|
|
1014
|
-
}
|
|
1128
|
+
});
|
|
1015
1129
|
|
|
1016
|
-
apiRegisterPlural(
|
|
1130
|
+
apiRegisterPlural('columns().select()', 'column().select()', function (select) {
|
|
1017
1131
|
var api = this;
|
|
1018
1132
|
|
|
1019
|
-
if (
|
|
1133
|
+
if (select === false) {
|
|
1020
1134
|
return this.deselect();
|
|
1021
1135
|
}
|
|
1022
1136
|
|
|
1023
|
-
this.iterator(
|
|
1024
|
-
clear(
|
|
1137
|
+
this.iterator('column', function (ctx, idx) {
|
|
1138
|
+
clear(ctx);
|
|
1025
1139
|
|
|
1026
|
-
ctx.aoColumns[
|
|
1140
|
+
ctx.aoColumns[idx]._select_selected = true;
|
|
1027
1141
|
|
|
1028
|
-
var column = new DataTable.Api(
|
|
1142
|
+
var column = new DataTable.Api(ctx).column(idx);
|
|
1029
1143
|
|
|
1030
|
-
$(
|
|
1031
|
-
$(
|
|
1144
|
+
$(column.header()).addClass(ctx._select.className);
|
|
1145
|
+
$(column.footer()).addClass(ctx._select.className);
|
|
1032
1146
|
|
|
1033
|
-
column.nodes().to$().addClass(
|
|
1034
|
-
}
|
|
1147
|
+
column.nodes().to$().addClass(ctx._select.className);
|
|
1148
|
+
});
|
|
1035
1149
|
|
|
1036
|
-
this.iterator(
|
|
1037
|
-
eventTrigger(
|
|
1038
|
-
}
|
|
1150
|
+
this.iterator('table', function (ctx, i) {
|
|
1151
|
+
eventTrigger(api, 'select', ['column', api[i]], true);
|
|
1152
|
+
});
|
|
1039
1153
|
|
|
1040
1154
|
return this;
|
|
1041
|
-
}
|
|
1155
|
+
});
|
|
1042
1156
|
|
|
1043
|
-
apiRegister(
|
|
1157
|
+
apiRegister('column().selected()', function () {
|
|
1044
1158
|
var ctx = this.context[0];
|
|
1045
1159
|
|
|
1046
|
-
if (
|
|
1047
|
-
ctx &&
|
|
1048
|
-
this.length &&
|
|
1049
|
-
ctx.aoColumns[this[0]] &&
|
|
1050
|
-
ctx.aoColumns[this[0]]._select_selected
|
|
1051
|
-
) {
|
|
1160
|
+
if (ctx && this.length && ctx.aoColumns[this[0]] && ctx.aoColumns[this[0]]._select_selected) {
|
|
1052
1161
|
return true;
|
|
1053
1162
|
}
|
|
1054
1163
|
|
|
1055
1164
|
return false;
|
|
1056
|
-
}
|
|
1165
|
+
});
|
|
1057
1166
|
|
|
1058
|
-
apiRegisterPlural(
|
|
1167
|
+
apiRegisterPlural('cells().select()', 'cell().select()', function (select) {
|
|
1059
1168
|
var api = this;
|
|
1060
1169
|
|
|
1061
|
-
if (
|
|
1170
|
+
if (select === false) {
|
|
1062
1171
|
return this.deselect();
|
|
1063
1172
|
}
|
|
1064
1173
|
|
|
1065
|
-
this.iterator(
|
|
1066
|
-
clear(
|
|
1174
|
+
this.iterator('cell', function (ctx, rowIdx, colIdx) {
|
|
1175
|
+
clear(ctx);
|
|
1067
1176
|
|
|
1068
|
-
var data = ctx.aoData[
|
|
1177
|
+
var data = ctx.aoData[rowIdx];
|
|
1069
1178
|
|
|
1070
|
-
if (
|
|
1179
|
+
if (data._selected_cells === undefined) {
|
|
1071
1180
|
data._selected_cells = [];
|
|
1072
1181
|
}
|
|
1073
1182
|
|
|
1074
|
-
data._selected_cells[
|
|
1183
|
+
data._selected_cells[colIdx] = true;
|
|
1075
1184
|
|
|
1076
|
-
if (
|
|
1077
|
-
$(
|
|
1185
|
+
if (data.anCells) {
|
|
1186
|
+
$(data.anCells[colIdx]).addClass(ctx._select.className);
|
|
1078
1187
|
}
|
|
1079
|
-
}
|
|
1188
|
+
});
|
|
1080
1189
|
|
|
1081
|
-
this.iterator(
|
|
1082
|
-
eventTrigger(
|
|
1083
|
-
}
|
|
1190
|
+
this.iterator('table', function (ctx, i) {
|
|
1191
|
+
eventTrigger(api, 'select', ['cell', api.cells(api[i]).indexes().toArray()], true);
|
|
1192
|
+
});
|
|
1084
1193
|
|
|
1085
1194
|
return this;
|
|
1086
|
-
}
|
|
1195
|
+
});
|
|
1087
1196
|
|
|
1088
|
-
apiRegister(
|
|
1197
|
+
apiRegister('cell().selected()', function () {
|
|
1089
1198
|
var ctx = this.context[0];
|
|
1090
1199
|
|
|
1091
1200
|
if (ctx && this.length) {
|
|
@@ -1097,110 +1206,125 @@ apiRegister( 'cell().selected()', function () {
|
|
|
1097
1206
|
}
|
|
1098
1207
|
|
|
1099
1208
|
return false;
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1209
|
+
});
|
|
1102
1210
|
|
|
1103
|
-
apiRegisterPlural(
|
|
1211
|
+
apiRegisterPlural('rows().deselect()', 'row().deselect()', function () {
|
|
1104
1212
|
var api = this;
|
|
1105
1213
|
|
|
1106
|
-
this.iterator(
|
|
1107
|
-
|
|
1214
|
+
this.iterator('row', function (ctx, idx) {
|
|
1215
|
+
// Like the select action, this has a lot of knowledge about DT internally
|
|
1216
|
+
var dtData = ctx.aoData[idx];
|
|
1217
|
+
var dtColumns = ctx.aoColumns;
|
|
1218
|
+
|
|
1219
|
+
$(dtData.nTr).removeClass(ctx._select.className);
|
|
1220
|
+
dtData._select_selected = false;
|
|
1108
1221
|
ctx._select_lastCell = null;
|
|
1109
|
-
$( ctx.aoData[ idx ].nTr ).removeClass( ctx._select.className );
|
|
1110
|
-
} );
|
|
1111
1222
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1223
|
+
for (var i=0 ; i<dtColumns.length ; i++) {
|
|
1224
|
+
var col = dtColumns[i];
|
|
1225
|
+
|
|
1226
|
+
if (col.sType === 'select-checkbox') {
|
|
1227
|
+
// Make sure the checkbox shows the right state
|
|
1228
|
+
$('input.dt-select-checkbox', dtData.anCells[i]).prop('checked', false);
|
|
1229
|
+
|
|
1230
|
+
// Invalidate the sort data for this column
|
|
1231
|
+
dtData._aSortData[i] = null;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
this.iterator('table', function (ctx, i) {
|
|
1237
|
+
eventTrigger(api, 'deselect', ['row', api[i]], true);
|
|
1238
|
+
});
|
|
1115
1239
|
|
|
1116
1240
|
return this;
|
|
1117
|
-
}
|
|
1241
|
+
});
|
|
1118
1242
|
|
|
1119
|
-
apiRegisterPlural(
|
|
1243
|
+
apiRegisterPlural('columns().deselect()', 'column().deselect()', function () {
|
|
1120
1244
|
var api = this;
|
|
1121
1245
|
|
|
1122
|
-
this.iterator(
|
|
1123
|
-
ctx.aoColumns[
|
|
1246
|
+
this.iterator('column', function (ctx, idx) {
|
|
1247
|
+
ctx.aoColumns[idx]._select_selected = false;
|
|
1124
1248
|
|
|
1125
|
-
var api = new DataTable.Api(
|
|
1126
|
-
var column = api.column(
|
|
1249
|
+
var api = new DataTable.Api(ctx);
|
|
1250
|
+
var column = api.column(idx);
|
|
1127
1251
|
|
|
1128
|
-
$(
|
|
1129
|
-
$(
|
|
1252
|
+
$(column.header()).removeClass(ctx._select.className);
|
|
1253
|
+
$(column.footer()).removeClass(ctx._select.className);
|
|
1130
1254
|
|
|
1131
1255
|
// Need to loop over each cell, rather than just using
|
|
1132
1256
|
// `column().nodes()` as cells which are individually selected should
|
|
1133
1257
|
// not have the `selected` class removed from them
|
|
1134
|
-
api.cells(
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1258
|
+
api.cells(null, idx)
|
|
1259
|
+
.indexes()
|
|
1260
|
+
.each(function (cellIdx) {
|
|
1261
|
+
var data = ctx.aoData[cellIdx.row];
|
|
1262
|
+
var cellSelected = data._selected_cells;
|
|
1263
|
+
|
|
1264
|
+
if (data.anCells && (!cellSelected || !cellSelected[cellIdx.column])) {
|
|
1265
|
+
$(data.anCells[cellIdx.column]).removeClass(ctx._select.className);
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1268
|
+
});
|
|
1143
1269
|
|
|
1144
|
-
this.iterator(
|
|
1145
|
-
eventTrigger(
|
|
1146
|
-
}
|
|
1270
|
+
this.iterator('table', function (ctx, i) {
|
|
1271
|
+
eventTrigger(api, 'deselect', ['column', api[i]], true);
|
|
1272
|
+
});
|
|
1147
1273
|
|
|
1148
1274
|
return this;
|
|
1149
|
-
}
|
|
1275
|
+
});
|
|
1150
1276
|
|
|
1151
|
-
apiRegisterPlural(
|
|
1277
|
+
apiRegisterPlural('cells().deselect()', 'cell().deselect()', function () {
|
|
1152
1278
|
var api = this;
|
|
1153
1279
|
|
|
1154
|
-
this.iterator(
|
|
1155
|
-
var data = ctx.aoData[
|
|
1280
|
+
this.iterator('cell', function (ctx, rowIdx, colIdx) {
|
|
1281
|
+
var data = ctx.aoData[rowIdx];
|
|
1156
1282
|
|
|
1157
|
-
if(data._selected_cells !== undefined) {
|
|
1158
|
-
data._selected_cells[
|
|
1283
|
+
if (data._selected_cells !== undefined) {
|
|
1284
|
+
data._selected_cells[colIdx] = false;
|
|
1159
1285
|
}
|
|
1160
1286
|
|
|
1161
1287
|
// Remove class only if the cells exist, and the cell is not column
|
|
1162
1288
|
// selected, in which case the class should remain (since it is selected
|
|
1163
1289
|
// in the column)
|
|
1164
|
-
if (
|
|
1165
|
-
$(
|
|
1290
|
+
if (data.anCells && !ctx.aoColumns[colIdx]._select_selected) {
|
|
1291
|
+
$(data.anCells[colIdx]).removeClass(ctx._select.className);
|
|
1166
1292
|
}
|
|
1167
|
-
}
|
|
1293
|
+
});
|
|
1168
1294
|
|
|
1169
|
-
this.iterator(
|
|
1170
|
-
eventTrigger(
|
|
1171
|
-
}
|
|
1295
|
+
this.iterator('table', function (ctx, i) {
|
|
1296
|
+
eventTrigger(api, 'deselect', ['cell', api[i]], true);
|
|
1297
|
+
});
|
|
1172
1298
|
|
|
1173
1299
|
return this;
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1300
|
+
});
|
|
1177
1301
|
|
|
1178
1302
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
1179
1303
|
* Buttons
|
|
1180
1304
|
*/
|
|
1181
|
-
function i18n(
|
|
1305
|
+
function i18n(label, def) {
|
|
1182
1306
|
return function (dt) {
|
|
1183
|
-
return dt.i18n(
|
|
1307
|
+
return dt.i18n('buttons.' + label, def);
|
|
1184
1308
|
};
|
|
1185
1309
|
}
|
|
1186
1310
|
|
|
1187
1311
|
// Common events with suitable namespaces
|
|
1188
|
-
function namespacedEvents
|
|
1312
|
+
function namespacedEvents(config) {
|
|
1189
1313
|
var unique = config._eventNamespace;
|
|
1190
1314
|
|
|
1191
|
-
return 'draw.dt.DT'+unique+' select.dt.DT'+unique+' deselect.dt.DT'+unique;
|
|
1315
|
+
return 'draw.dt.DT' + unique + ' select.dt.DT' + unique + ' deselect.dt.DT' + unique;
|
|
1192
1316
|
}
|
|
1193
1317
|
|
|
1194
|
-
function enabled
|
|
1195
|
-
if (
|
|
1318
|
+
function enabled(dt, config) {
|
|
1319
|
+
if (config.limitTo.indexOf('rows') !== -1 && dt.rows({ selected: true }).any()) {
|
|
1196
1320
|
return true;
|
|
1197
1321
|
}
|
|
1198
1322
|
|
|
1199
|
-
if (
|
|
1323
|
+
if (config.limitTo.indexOf('columns') !== -1 && dt.columns({ selected: true }).any()) {
|
|
1200
1324
|
return true;
|
|
1201
1325
|
}
|
|
1202
1326
|
|
|
1203
|
-
if (
|
|
1327
|
+
if (config.limitTo.indexOf('cells') !== -1 && dt.cells({ selected: true }).any()) {
|
|
1204
1328
|
return true;
|
|
1205
1329
|
}
|
|
1206
1330
|
|
|
@@ -1209,111 +1333,114 @@ function enabled ( dt, config ) {
|
|
|
1209
1333
|
|
|
1210
1334
|
var _buttonNamespace = 0;
|
|
1211
1335
|
|
|
1212
|
-
$.extend(
|
|
1336
|
+
$.extend(DataTable.ext.buttons, {
|
|
1213
1337
|
selected: {
|
|
1214
|
-
text: i18n(
|
|
1338
|
+
text: i18n('selected', 'Selected'),
|
|
1215
1339
|
className: 'buttons-selected',
|
|
1216
|
-
limitTo: [
|
|
1217
|
-
init: function (
|
|
1340
|
+
limitTo: ['rows', 'columns', 'cells'],
|
|
1341
|
+
init: function (dt, node, config) {
|
|
1218
1342
|
var that = this;
|
|
1219
|
-
config._eventNamespace = '.select'+
|
|
1343
|
+
config._eventNamespace = '.select' + _buttonNamespace++;
|
|
1220
1344
|
|
|
1221
1345
|
// .DT namespace listeners are removed by DataTables automatically
|
|
1222
1346
|
// on table destroy
|
|
1223
|
-
dt.on(
|
|
1224
|
-
that.enable(
|
|
1225
|
-
}
|
|
1347
|
+
dt.on(namespacedEvents(config), function () {
|
|
1348
|
+
that.enable(enabled(dt, config));
|
|
1349
|
+
});
|
|
1226
1350
|
|
|
1227
1351
|
this.disable();
|
|
1228
1352
|
},
|
|
1229
|
-
destroy: function (
|
|
1230
|
-
dt.off(
|
|
1353
|
+
destroy: function (dt, node, config) {
|
|
1354
|
+
dt.off(config._eventNamespace);
|
|
1231
1355
|
}
|
|
1232
1356
|
},
|
|
1233
1357
|
selectedSingle: {
|
|
1234
|
-
text: i18n(
|
|
1358
|
+
text: i18n('selectedSingle', 'Selected single'),
|
|
1235
1359
|
className: 'buttons-selected-single',
|
|
1236
|
-
init: function (
|
|
1360
|
+
init: function (dt, node, config) {
|
|
1237
1361
|
var that = this;
|
|
1238
|
-
config._eventNamespace = '.select'+
|
|
1362
|
+
config._eventNamespace = '.select' + _buttonNamespace++;
|
|
1239
1363
|
|
|
1240
|
-
dt.on(
|
|
1241
|
-
var count =
|
|
1242
|
-
|
|
1243
|
-
|
|
1364
|
+
dt.on(namespacedEvents(config), function () {
|
|
1365
|
+
var count =
|
|
1366
|
+
dt.rows({ selected: true }).flatten().length +
|
|
1367
|
+
dt.columns({ selected: true }).flatten().length +
|
|
1368
|
+
dt.cells({ selected: true }).flatten().length;
|
|
1244
1369
|
|
|
1245
|
-
that.enable(
|
|
1246
|
-
}
|
|
1370
|
+
that.enable(count === 1);
|
|
1371
|
+
});
|
|
1247
1372
|
|
|
1248
1373
|
this.disable();
|
|
1249
1374
|
},
|
|
1250
|
-
destroy: function (
|
|
1251
|
-
dt.off(
|
|
1375
|
+
destroy: function (dt, node, config) {
|
|
1376
|
+
dt.off(config._eventNamespace);
|
|
1252
1377
|
}
|
|
1253
1378
|
},
|
|
1254
1379
|
selectAll: {
|
|
1255
|
-
text: i18n(
|
|
1380
|
+
text: i18n('selectAll', 'Select all'),
|
|
1256
1381
|
className: 'buttons-select-all',
|
|
1257
|
-
action: function () {
|
|
1382
|
+
action: function (e, dt, node, config) {
|
|
1258
1383
|
var items = this.select.items();
|
|
1259
|
-
|
|
1384
|
+
var mod = config.selectorModifier;
|
|
1385
|
+
|
|
1386
|
+
if (mod) {
|
|
1387
|
+
if (typeof mod === 'function') {
|
|
1388
|
+
mod = mod.call(dt, e, dt, node, config);
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
this[items + 's'](mod).select();
|
|
1392
|
+
}
|
|
1393
|
+
else {
|
|
1394
|
+
this[items + 's']().select();
|
|
1395
|
+
}
|
|
1260
1396
|
}
|
|
1397
|
+
// selectorModifier can be specified
|
|
1261
1398
|
},
|
|
1262
1399
|
selectNone: {
|
|
1263
|
-
text: i18n(
|
|
1400
|
+
text: i18n('selectNone', 'Deselect all'),
|
|
1264
1401
|
className: 'buttons-select-none',
|
|
1265
1402
|
action: function () {
|
|
1266
|
-
clear(
|
|
1403
|
+
clear(this.settings()[0], true);
|
|
1267
1404
|
},
|
|
1268
|
-
init: function (
|
|
1405
|
+
init: function (dt, node, config) {
|
|
1269
1406
|
var that = this;
|
|
1270
|
-
config._eventNamespace = '.select'+
|
|
1407
|
+
config._eventNamespace = '.select' + _buttonNamespace++;
|
|
1271
1408
|
|
|
1272
|
-
dt.on(
|
|
1273
|
-
var count =
|
|
1274
|
-
|
|
1275
|
-
|
|
1409
|
+
dt.on(namespacedEvents(config), function () {
|
|
1410
|
+
var count =
|
|
1411
|
+
dt.rows({ selected: true }).flatten().length +
|
|
1412
|
+
dt.columns({ selected: true }).flatten().length +
|
|
1413
|
+
dt.cells({ selected: true }).flatten().length;
|
|
1276
1414
|
|
|
1277
|
-
that.enable(
|
|
1278
|
-
}
|
|
1415
|
+
that.enable(count > 0);
|
|
1416
|
+
});
|
|
1279
1417
|
|
|
1280
1418
|
this.disable();
|
|
1281
1419
|
},
|
|
1282
|
-
destroy: function (
|
|
1283
|
-
dt.off(
|
|
1420
|
+
destroy: function (dt, node, config) {
|
|
1421
|
+
dt.off(config._eventNamespace);
|
|
1284
1422
|
}
|
|
1285
1423
|
},
|
|
1286
1424
|
showSelected: {
|
|
1287
|
-
text: i18n(
|
|
1425
|
+
text: i18n('showSelected', 'Show only selected'),
|
|
1288
1426
|
className: 'buttons-show-selected',
|
|
1289
|
-
action: function (e, dt
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
if (conf._filter) {
|
|
1294
|
-
var idx = DataTable.ext.search.indexOf(conf._filter);
|
|
1295
|
-
|
|
1296
|
-
if (idx !== -1) {
|
|
1297
|
-
DataTable.ext.search.splice(idx, 1);
|
|
1298
|
-
conf._filter = null;
|
|
1299
|
-
}
|
|
1427
|
+
action: function (e, dt) {
|
|
1428
|
+
if (dt.search.fixed('dt-select')) {
|
|
1429
|
+
// Remove existing function
|
|
1430
|
+
dt.search.fixed('dt-select', null);
|
|
1300
1431
|
|
|
1301
1432
|
this.active(false);
|
|
1302
1433
|
}
|
|
1303
1434
|
else {
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
let row = s.aoData[idx];
|
|
1311
|
-
|
|
1312
|
-
return row._select_selected;
|
|
1313
|
-
}
|
|
1435
|
+
// Use a fixed filtering function to match on selected rows
|
|
1436
|
+
// This needs to reference the internal aoData since that is
|
|
1437
|
+
// where Select stores its reference for the selected state
|
|
1438
|
+
var dataSrc = dt.settings()[0].aoData;
|
|
1314
1439
|
|
|
1315
|
-
|
|
1316
|
-
|
|
1440
|
+
dt.search.fixed('dt-select', function (text, data, idx) {
|
|
1441
|
+
// _select_selected is set by Select on the data object for the row
|
|
1442
|
+
return dataSrc[idx]._select_selected;
|
|
1443
|
+
});
|
|
1317
1444
|
|
|
1318
1445
|
this.active(true);
|
|
1319
1446
|
}
|
|
@@ -1321,27 +1448,94 @@ $.extend( DataTable.ext.buttons, {
|
|
|
1321
1448
|
dt.draw();
|
|
1322
1449
|
}
|
|
1323
1450
|
}
|
|
1324
|
-
}
|
|
1451
|
+
});
|
|
1325
1452
|
|
|
1326
|
-
$.each(
|
|
1453
|
+
$.each(['Row', 'Column', 'Cell'], function (i, item) {
|
|
1327
1454
|
var lc = item.toLowerCase();
|
|
1328
1455
|
|
|
1329
|
-
DataTable.ext.buttons[
|
|
1330
|
-
text: i18n(
|
|
1331
|
-
className: 'buttons-select-'+lc+'s',
|
|
1456
|
+
DataTable.ext.buttons['select' + item + 's'] = {
|
|
1457
|
+
text: i18n('select' + item + 's', 'Select ' + lc + 's'),
|
|
1458
|
+
className: 'buttons-select-' + lc + 's',
|
|
1332
1459
|
action: function () {
|
|
1333
|
-
this.select.items(
|
|
1460
|
+
this.select.items(lc);
|
|
1334
1461
|
},
|
|
1335
|
-
init: function (
|
|
1462
|
+
init: function (dt) {
|
|
1336
1463
|
var that = this;
|
|
1337
1464
|
|
|
1338
|
-
dt.on(
|
|
1339
|
-
that.active(
|
|
1340
|
-
}
|
|
1465
|
+
dt.on('selectItems.dt.DT', function (e, ctx, items) {
|
|
1466
|
+
that.active(items === lc);
|
|
1467
|
+
});
|
|
1341
1468
|
}
|
|
1342
1469
|
};
|
|
1343
|
-
}
|
|
1470
|
+
});
|
|
1471
|
+
|
|
1472
|
+
DataTable.type('select-checkbox', {
|
|
1473
|
+
className: 'dt-select',
|
|
1474
|
+
detect: function (data) {
|
|
1475
|
+
// Rendering function will tell us if it is a checkbox type
|
|
1476
|
+
return data === 'select-checkbox' ? data : false;
|
|
1477
|
+
},
|
|
1478
|
+
order: {
|
|
1479
|
+
pre: function (d) {
|
|
1480
|
+
return d === 'X' ? -1 : 0;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1484
|
+
|
|
1485
|
+
$.extend(true, DataTable.defaults.oLanguage, {
|
|
1486
|
+
select: {
|
|
1487
|
+
aria: {
|
|
1488
|
+
rowCheckbox: 'Select row'
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
});
|
|
1492
|
+
|
|
1493
|
+
DataTable.render.select = function (valueProp, nameProp) {
|
|
1494
|
+
var valueFn = valueProp ? DataTable.util.get(valueProp) : null;
|
|
1495
|
+
var nameFn = nameProp ? DataTable.util.get(nameProp) : null;
|
|
1496
|
+
|
|
1497
|
+
return function (data, type, row, meta) {
|
|
1498
|
+
var dtRow = meta.settings.aoData[meta.row];
|
|
1499
|
+
var selected = dtRow._select_selected;
|
|
1500
|
+
var ariaLabel = meta.settings.oLanguage.select.aria.rowCheckbox;
|
|
1501
|
+
|
|
1502
|
+
if (type === 'display') {
|
|
1503
|
+
return $('<input>')
|
|
1504
|
+
.attr({
|
|
1505
|
+
'aria-label': ariaLabel,
|
|
1506
|
+
class: 'dt-select-checkbox',
|
|
1507
|
+
name: nameFn ? nameFn(row) : null,
|
|
1508
|
+
type: 'checkbox',
|
|
1509
|
+
value: valueFn ? valueFn(row) : null,
|
|
1510
|
+
checked: selected
|
|
1511
|
+
})[0];
|
|
1512
|
+
}
|
|
1513
|
+
else if (type === 'type') {
|
|
1514
|
+
return 'select-checkbox';
|
|
1515
|
+
}
|
|
1516
|
+
else if (type === 'filter') {
|
|
1517
|
+
return '';
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
return selected ? 'X' : '';
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1344
1523
|
|
|
1524
|
+
// Legacy checkbox ordering
|
|
1525
|
+
DataTable.ext.order['select-checkbox'] = function (settings, col) {
|
|
1526
|
+
return this.api()
|
|
1527
|
+
.column(col, { order: 'index' })
|
|
1528
|
+
.nodes()
|
|
1529
|
+
.map(function (td) {
|
|
1530
|
+
if (settings._select.items === 'row') {
|
|
1531
|
+
return $(td).parent().hasClass(settings._select.className);
|
|
1532
|
+
}
|
|
1533
|
+
else if (settings._select.items === 'cell') {
|
|
1534
|
+
return $(td).hasClass(settings._select.className);
|
|
1535
|
+
}
|
|
1536
|
+
return false;
|
|
1537
|
+
});
|
|
1538
|
+
};
|
|
1345
1539
|
|
|
1346
1540
|
$.fn.DataTable.select = DataTable.select;
|
|
1347
1541
|
|
|
@@ -1353,13 +1547,13 @@ $.fn.DataTable.select = DataTable.select;
|
|
|
1353
1547
|
// this required that the table be in the document! If it isn't then something
|
|
1354
1548
|
// needs to trigger this method unfortunately. The next major release of
|
|
1355
1549
|
// DataTables will rework the events and address this.
|
|
1356
|
-
$(document).on(
|
|
1357
|
-
if (
|
|
1550
|
+
$(document).on('preInit.dt.dtSelect', function (e, ctx) {
|
|
1551
|
+
if (e.namespace !== 'dt') {
|
|
1358
1552
|
return;
|
|
1359
1553
|
}
|
|
1360
1554
|
|
|
1361
|
-
DataTable.select.init(
|
|
1362
|
-
}
|
|
1555
|
+
DataTable.select.init(new DataTable.Api(ctx));
|
|
1556
|
+
});
|
|
1363
1557
|
|
|
1364
1558
|
|
|
1365
1559
|
return DataTable;
|