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