datatables.net-columncontrol 1.0.6 → 1.1.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! ColumnControl 1.0
|
|
1
|
+
/*! ColumnControl 1.1.0
|
|
2
2
|
* Copyright (c) SpryMedia Ltd - datatables.net/license
|
|
3
3
|
*
|
|
4
4
|
* SVG icons: ISC License
|
|
@@ -102,6 +102,14 @@ var icons = {
|
|
|
102
102
|
greater: wrap('<path d="m9 18 6-6-6-6"/>'),
|
|
103
103
|
// Custom
|
|
104
104
|
greaterOrEqual: wrap('<path d="m9 16 6-6-6-6"/><path d="m9 21 6-6"/>'),
|
|
105
|
+
// Custom
|
|
106
|
+
groupAdd: wrap('<path d="M6 21v-7.5m-3.549 3.75H9.75"/><rect width="13.5" height="7.5" x="3" y="3" rx="1.5"/><rect width="7.5" height="7.5" x="13.5" y="13.5" fill="currentColor" rx="1.5"/>'),
|
|
107
|
+
// Custom
|
|
108
|
+
groupClear: wrap('<rect width="13.5" height="7.5" x="3" y="3" rx="1.5"/><rect width="7.5" height="7.5" x="13.5" y="13.5" rx="1.5"/>'),
|
|
109
|
+
// Custom
|
|
110
|
+
groupTop: wrap('<rect width="13.5" height="7.5" x="3" y="3" fill="currentColor" rx="1.5"/><rect width="7.5" height="7.5" x="13.5" y="13.5" rx="1.5"/>'),
|
|
111
|
+
// Custom
|
|
112
|
+
groupRemove: wrap('<path d="M2.451 17.25H9.75"/><rect width="13.5" height="7.5" x="3" y="3" rx="1.5"/><rect width="7.5" height="7.5" x="13.5" y="13.5" rx="1.5"/>'),
|
|
105
113
|
less: wrap('<path d="m15 18-6-6 6-6"/>'),
|
|
106
114
|
// Custom
|
|
107
115
|
lessOrEqual: wrap('<path d="m15 16-6-6 6-6"/><path d="m15 21-6-6"/>'),
|
|
@@ -208,6 +216,7 @@ function attachDropdown(dropdown, dt, btn) {
|
|
|
208
216
|
dropdown._shown = true;
|
|
209
217
|
dtContainer.append(dropdown);
|
|
210
218
|
positionDropdown(dropdown, dt, btn.element());
|
|
219
|
+
btn.element().setAttribute('aria-expanded', 'true');
|
|
211
220
|
// Note that this could be called when the dropdown has already been removed from the document
|
|
212
221
|
// via another dropdown being shown. This will clean up the event on the next body click.
|
|
213
222
|
var removeDropdown = function (e) {
|
|
@@ -220,6 +229,12 @@ function attachDropdown(dropdown, dt, btn) {
|
|
|
220
229
|
if (e.target === dropdown || dropdown.contains(e.target)) {
|
|
221
230
|
return;
|
|
222
231
|
}
|
|
232
|
+
// If there is currently a datetime picker visible on the page, assume that it belongs to
|
|
233
|
+
// this dropdown. Don't want to close while operating on the picker.
|
|
234
|
+
var datetime = document.querySelector('div.dt-datetime');
|
|
235
|
+
if (datetime && (e.target === datetime || datetime.contains(e.target))) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
223
238
|
dropdown._close();
|
|
224
239
|
document.body.removeEventListener('click', removeDropdown);
|
|
225
240
|
};
|
|
@@ -317,6 +332,7 @@ var dropdownContent = {
|
|
|
317
332
|
dropdown._close = function () {
|
|
318
333
|
dropdown.remove();
|
|
319
334
|
dropdown._shown = false;
|
|
335
|
+
btn.element().setAttribute('aria-expanded', 'false');
|
|
320
336
|
};
|
|
321
337
|
dropdown.setAttribute('role', 'dialog');
|
|
322
338
|
dropdown.setAttribute('aria-label', dt.i18n('columnControl.dropdown', config.text));
|
|
@@ -329,7 +345,7 @@ var dropdownContent = {
|
|
|
329
345
|
});
|
|
330
346
|
// A liner element allows more styling options, so the contents go inside this
|
|
331
347
|
var liner = dropdown.childNodes[0];
|
|
332
|
-
var btn = new Button(dt)
|
|
348
|
+
var btn = new Button(dt, this)
|
|
333
349
|
.text(dt.i18n('columnControl.dropdown', config.text))
|
|
334
350
|
.icon(config.icon)
|
|
335
351
|
.className(config.className)
|
|
@@ -348,6 +364,7 @@ var dropdownContent = {
|
|
|
348
364
|
}
|
|
349
365
|
});
|
|
350
366
|
btn.element().setAttribute('aria-haspopup', 'dialog');
|
|
367
|
+
btn.element().setAttribute('aria-expanded', 'false');
|
|
351
368
|
// Add the content for the dropdown
|
|
352
369
|
for (var i = 0; i < config.content.length; i++) {
|
|
353
370
|
var content = this.resolve(config.content[i]);
|
|
@@ -384,18 +401,20 @@ var Button = /** @class */ (function () {
|
|
|
384
401
|
* Create a new button for use in ColumnControl contents. Buttons created by this class can be
|
|
385
402
|
* used at the top level in the header or in a dropdown.
|
|
386
403
|
*/
|
|
387
|
-
function Button(dt) {
|
|
404
|
+
function Button(dt, host) {
|
|
388
405
|
this._s = {
|
|
389
406
|
active: false,
|
|
390
407
|
activeList: [],
|
|
391
408
|
buttonClick: null,
|
|
392
409
|
dt: null,
|
|
393
410
|
enabled: true,
|
|
411
|
+
host: null,
|
|
394
412
|
label: '',
|
|
395
413
|
namespace: '',
|
|
396
414
|
value: null
|
|
397
415
|
};
|
|
398
416
|
this._s.dt = dt;
|
|
417
|
+
this._s.host = host;
|
|
399
418
|
this._dom = {
|
|
400
419
|
button: createElement('button', Button.classes.container),
|
|
401
420
|
dropdownDisplay: null,
|
|
@@ -473,9 +492,7 @@ var Button = /** @class */ (function () {
|
|
|
473
492
|
this._dom.button.removeEventListener('click', this._s.buttonClick);
|
|
474
493
|
this._dom.button.removeEventListener('keypress', this._s.buttonClick);
|
|
475
494
|
}
|
|
476
|
-
|
|
477
|
-
this._s.dt.off('destroy.' + this._s.namespace);
|
|
478
|
-
}
|
|
495
|
+
this._s.host.destroyRemove(this);
|
|
479
496
|
};
|
|
480
497
|
/**
|
|
481
498
|
* Relevant for drop downs only. When a button in a dropdown is hidden, we might want to
|
|
@@ -497,13 +514,10 @@ var Button = /** @class */ (function () {
|
|
|
497
514
|
Button.prototype.element = function () {
|
|
498
515
|
return this._dom.button;
|
|
499
516
|
};
|
|
500
|
-
/**
|
|
501
|
-
* Set if the button should be enabled or not.
|
|
502
|
-
*
|
|
503
|
-
* @param enable Toggle the enable state
|
|
504
|
-
* @returns Button instance
|
|
505
|
-
*/
|
|
506
517
|
Button.prototype.enable = function (enable) {
|
|
518
|
+
if (enable === undefined) {
|
|
519
|
+
return this._s.enabled;
|
|
520
|
+
}
|
|
507
521
|
this._dom.button.classList.toggle('dtcc-button_disabled', !enable);
|
|
508
522
|
this._s.enabled = enable;
|
|
509
523
|
return this;
|
|
@@ -540,10 +554,7 @@ var Button = /** @class */ (function () {
|
|
|
540
554
|
this._s.namespace = 'dtcc-' + _namespace++;
|
|
541
555
|
this._dom.button.addEventListener('click', buttonClick);
|
|
542
556
|
this._dom.button.addEventListener('keypress', buttonClick);
|
|
543
|
-
|
|
544
|
-
this._s.dt.on('destroy.' + this._s.namespace, function () {
|
|
545
|
-
_this.destroy();
|
|
546
|
-
});
|
|
557
|
+
this._s.host.destroyAdd(this);
|
|
547
558
|
return this;
|
|
548
559
|
};
|
|
549
560
|
/**
|
|
@@ -598,19 +609,22 @@ var CheckList = /** @class */ (function () {
|
|
|
598
609
|
/**
|
|
599
610
|
* Container for a list of buttons
|
|
600
611
|
*/
|
|
601
|
-
function CheckList(dt, opts) {
|
|
612
|
+
function CheckList(dt, host, opts) {
|
|
602
613
|
var _this = this;
|
|
603
614
|
this._s = {
|
|
604
615
|
buttons: [],
|
|
605
616
|
dt: null,
|
|
606
617
|
handler: function () { },
|
|
618
|
+
host: null,
|
|
607
619
|
search: ''
|
|
608
620
|
};
|
|
609
621
|
this._s.dt = dt;
|
|
622
|
+
this._s.host = host;
|
|
610
623
|
this._dom = {
|
|
611
624
|
buttons: createElement('div', 'dtcc-list-buttons'),
|
|
612
625
|
container: createElement('div', CheckList.classes.container),
|
|
613
626
|
controls: createElement('div', 'dtcc-list-controls'),
|
|
627
|
+
empty: createElement('div', 'dtcc-list-empty', dt.i18n('columnControl.list.empty', 'No options')),
|
|
614
628
|
title: createElement('div', 'dtcc-list-title'),
|
|
615
629
|
selectAll: createElement('button', 'dtcc-list-selectAll', dt.i18n('columnControl.list.all', 'Select all')),
|
|
616
630
|
selectAllCount: createElement('span'),
|
|
@@ -622,6 +636,7 @@ var CheckList = /** @class */ (function () {
|
|
|
622
636
|
dom.search.setAttribute('type', 'text');
|
|
623
637
|
dom.container.append(dom.title);
|
|
624
638
|
dom.container.append(dom.controls);
|
|
639
|
+
dom.container.append(dom.empty);
|
|
625
640
|
dom.container.append(dom.buttons);
|
|
626
641
|
if (opts.select) {
|
|
627
642
|
dom.controls.append(dom.selectAll);
|
|
@@ -672,7 +687,7 @@ var CheckList = /** @class */ (function () {
|
|
|
672
687
|
}
|
|
673
688
|
var _loop_1 = function (i) {
|
|
674
689
|
var option = options[i];
|
|
675
|
-
var btn = new Button(this_1._s.dt)
|
|
690
|
+
var btn = new Button(this_1._s.dt, this_1._s.host)
|
|
676
691
|
.active(option.active || false)
|
|
677
692
|
.handler(function (e) {
|
|
678
693
|
_this._s.handler(e, btn, _this._s.buttons, true);
|
|
@@ -681,7 +696,7 @@ var CheckList = /** @class */ (function () {
|
|
|
681
696
|
.icon(option.icon || '')
|
|
682
697
|
.text(option.label !== ''
|
|
683
698
|
? option.label
|
|
684
|
-
: this_1._s.dt.i18n('columnControl.list.
|
|
699
|
+
: this_1._s.dt.i18n('columnControl.list.empty', 'Empty'))
|
|
685
700
|
.value(option.value);
|
|
686
701
|
if (option.label === '') {
|
|
687
702
|
btn.className('empty');
|
|
@@ -752,11 +767,11 @@ var CheckList = /** @class */ (function () {
|
|
|
752
767
|
* @param dt DataTable instance
|
|
753
768
|
* @param idx Column index
|
|
754
769
|
*/
|
|
755
|
-
CheckList.prototype.searchListener = function (dt
|
|
770
|
+
CheckList.prototype.searchListener = function (dt) {
|
|
756
771
|
var _this = this;
|
|
757
|
-
// Column control search clearing (column().
|
|
772
|
+
// Column control search clearing (column().columnControl.searchClear() method)
|
|
758
773
|
dt.on('cc-search-clear', function (e, colIdx) {
|
|
759
|
-
if (colIdx ===
|
|
774
|
+
if (colIdx === _this._s.host.idx()) {
|
|
760
775
|
_this.selectNone();
|
|
761
776
|
_this._s.handler(e, null, _this._s.buttons, false);
|
|
762
777
|
_this._s.search = '';
|
|
@@ -844,6 +859,8 @@ var CheckList = /** @class */ (function () {
|
|
|
844
859
|
el.appendChild(btn.element());
|
|
845
860
|
}
|
|
846
861
|
}
|
|
862
|
+
this._dom.empty.style.display = buttons.length === 0 ? 'block' : 'none';
|
|
863
|
+
el.style.display = buttons.length > 0 ? 'block' : 'none';
|
|
847
864
|
};
|
|
848
865
|
CheckList.classes = {
|
|
849
866
|
container: 'dtcc-list',
|
|
@@ -862,7 +879,7 @@ var colVis = {
|
|
|
862
879
|
},
|
|
863
880
|
init: function (config) {
|
|
864
881
|
var dt = this.dt();
|
|
865
|
-
var checkList = new CheckList(dt, {
|
|
882
|
+
var checkList = new CheckList(dt, this, {
|
|
866
883
|
search: config.search,
|
|
867
884
|
select: config.select
|
|
868
885
|
})
|
|
@@ -945,7 +962,7 @@ var reorder = {
|
|
|
945
962
|
init: function (config) {
|
|
946
963
|
var _this = this;
|
|
947
964
|
var dt = this.dt();
|
|
948
|
-
var btn = new Button(dt)
|
|
965
|
+
var btn = new Button(dt, this)
|
|
949
966
|
.text(dt.i18n('columnControl.reorder', config.text))
|
|
950
967
|
.icon(config.icon)
|
|
951
968
|
.className(config.className)
|
|
@@ -978,7 +995,7 @@ var reorderLeft = {
|
|
|
978
995
|
init: function (config) {
|
|
979
996
|
var _this = this;
|
|
980
997
|
var dt = this.dt();
|
|
981
|
-
var btn = new Button(dt)
|
|
998
|
+
var btn = new Button(dt, this)
|
|
982
999
|
.text(dt.i18n('columnControl.reorderLeft', config.text))
|
|
983
1000
|
.icon(config.icon)
|
|
984
1001
|
.className(config.className)
|
|
@@ -1008,7 +1025,7 @@ var reorderRight = {
|
|
|
1008
1025
|
init: function (config) {
|
|
1009
1026
|
var _this = this;
|
|
1010
1027
|
var dt = this.dt();
|
|
1011
|
-
var btn = new Button(dt)
|
|
1028
|
+
var btn = new Button(dt, this)
|
|
1012
1029
|
.text(dt.i18n('columnControl.reorderRight', config.text))
|
|
1013
1030
|
.icon(config.icon)
|
|
1014
1031
|
.className(config.className)
|
|
@@ -1040,7 +1057,7 @@ var order = {
|
|
|
1040
1057
|
init: function (config) {
|
|
1041
1058
|
var _this = this;
|
|
1042
1059
|
var dt = this.dt();
|
|
1043
|
-
var btn = new Button(dt)
|
|
1060
|
+
var btn = new Button(dt, this)
|
|
1044
1061
|
.text(dt.i18n('columnControl.order', config.text))
|
|
1045
1062
|
.icon('orderAsc')
|
|
1046
1063
|
.className(config.className);
|
|
@@ -1072,7 +1089,7 @@ var orderAddAsc = {
|
|
|
1072
1089
|
init: function (config) {
|
|
1073
1090
|
var _this = this;
|
|
1074
1091
|
var dt = this.dt();
|
|
1075
|
-
var btn = new Button(dt)
|
|
1092
|
+
var btn = new Button(dt, this)
|
|
1076
1093
|
.text(dt.i18n('columnControl.orderAddAsc', config.text))
|
|
1077
1094
|
.icon(config.icon)
|
|
1078
1095
|
.className(config.className)
|
|
@@ -1098,7 +1115,7 @@ var orderAddDesc = {
|
|
|
1098
1115
|
init: function (config) {
|
|
1099
1116
|
var _this = this;
|
|
1100
1117
|
var dt = this.dt();
|
|
1101
|
-
var btn = new Button(dt)
|
|
1118
|
+
var btn = new Button(dt, this)
|
|
1102
1119
|
.text(dt.i18n('columnControl.orderAddDesc', config.text))
|
|
1103
1120
|
.icon(config.icon)
|
|
1104
1121
|
.className(config.className)
|
|
@@ -1124,7 +1141,7 @@ var orderAsc = {
|
|
|
1124
1141
|
init: function (config) {
|
|
1125
1142
|
var _this = this;
|
|
1126
1143
|
var dt = this.dt();
|
|
1127
|
-
var btn = new Button(dt)
|
|
1144
|
+
var btn = new Button(dt, this)
|
|
1128
1145
|
.text(dt.i18n('columnControl.orderAsc', config.text))
|
|
1129
1146
|
.icon(config.icon)
|
|
1130
1147
|
.className(config.className)
|
|
@@ -1154,7 +1171,7 @@ var orderClear = {
|
|
|
1154
1171
|
},
|
|
1155
1172
|
init: function (config) {
|
|
1156
1173
|
var dt = this.dt();
|
|
1157
|
-
var btn = new Button(dt)
|
|
1174
|
+
var btn = new Button(dt, this)
|
|
1158
1175
|
.text(dt.i18n('columnControl.orderClear', config.text))
|
|
1159
1176
|
.icon(config.icon)
|
|
1160
1177
|
.className(config.className)
|
|
@@ -1180,7 +1197,7 @@ var orderDesc = {
|
|
|
1180
1197
|
init: function (config) {
|
|
1181
1198
|
var _this = this;
|
|
1182
1199
|
var dt = this.dt();
|
|
1183
|
-
var btn = new Button(dt)
|
|
1200
|
+
var btn = new Button(dt, this)
|
|
1184
1201
|
.text(dt.i18n('columnControl.orderDesc', config.text))
|
|
1185
1202
|
.icon(config.icon)
|
|
1186
1203
|
.className(config.className)
|
|
@@ -1211,7 +1228,7 @@ var orderRemove = {
|
|
|
1211
1228
|
init: function (config) {
|
|
1212
1229
|
var _this = this;
|
|
1213
1230
|
var dt = this.dt();
|
|
1214
|
-
var btn = new Button(dt)
|
|
1231
|
+
var btn = new Button(dt, this)
|
|
1215
1232
|
.text(dt.i18n('columnControl.orderRemove', config.text))
|
|
1216
1233
|
.icon(config.icon)
|
|
1217
1234
|
.className(config.className)
|
|
@@ -1245,6 +1262,190 @@ var orderStatus = {
|
|
|
1245
1262
|
}
|
|
1246
1263
|
};
|
|
1247
1264
|
|
|
1265
|
+
/**
|
|
1266
|
+
* Add an item to the grouping structure
|
|
1267
|
+
*
|
|
1268
|
+
* @param dt DataTable API instance
|
|
1269
|
+
* @param dataSrc Grouping data point to add
|
|
1270
|
+
* @returns Grouping array
|
|
1271
|
+
*/
|
|
1272
|
+
function rowGroupAdd$1(dt, dataSrc) {
|
|
1273
|
+
var applied = rowGroupApplied(dt);
|
|
1274
|
+
var idx = applied.indexOf(dataSrc);
|
|
1275
|
+
if (idx === -1) {
|
|
1276
|
+
applied.push(dataSrc);
|
|
1277
|
+
dt.rowGroup().dataSrc(applied);
|
|
1278
|
+
}
|
|
1279
|
+
return applied;
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* Always want an array return
|
|
1283
|
+
*
|
|
1284
|
+
* @param dt DataTable API instance
|
|
1285
|
+
* @returns
|
|
1286
|
+
*/
|
|
1287
|
+
function rowGroupApplied(dt) {
|
|
1288
|
+
var applied = dt.rowGroup().dataSrc();
|
|
1289
|
+
return Array.isArray(applied)
|
|
1290
|
+
? applied
|
|
1291
|
+
: [applied];
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Remove all grouping
|
|
1295
|
+
*
|
|
1296
|
+
* @param dt DataTable API instance
|
|
1297
|
+
*/
|
|
1298
|
+
function rowGroupClear$1(dt) {
|
|
1299
|
+
dt.rowGroup().dataSrc([]);
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Remove an item from the grouping structure
|
|
1303
|
+
*
|
|
1304
|
+
* @param dt DataTable API instance
|
|
1305
|
+
* @param dataSrc Grouping data point to remove
|
|
1306
|
+
* @returns Grouping array
|
|
1307
|
+
*/
|
|
1308
|
+
function rowGroupRemove$1(dt, dataSrc) {
|
|
1309
|
+
var applied = rowGroupApplied(dt);
|
|
1310
|
+
var idx = applied.indexOf(dataSrc);
|
|
1311
|
+
if (idx !== -1) {
|
|
1312
|
+
applied.splice(idx, 1);
|
|
1313
|
+
dt.rowGroup().dataSrc(applied);
|
|
1314
|
+
}
|
|
1315
|
+
return applied;
|
|
1316
|
+
}
|
|
1317
|
+
var rowGroup = {
|
|
1318
|
+
defaults: {
|
|
1319
|
+
className: 'rowGroup',
|
|
1320
|
+
icon: 'groupTop',
|
|
1321
|
+
order: true,
|
|
1322
|
+
text: 'Group rows'
|
|
1323
|
+
},
|
|
1324
|
+
init: function (config) {
|
|
1325
|
+
var _this = this;
|
|
1326
|
+
var dt = this.dt();
|
|
1327
|
+
var btn = new Button(dt, this)
|
|
1328
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1329
|
+
.icon(config.icon)
|
|
1330
|
+
.className(config.className)
|
|
1331
|
+
.handler(function () {
|
|
1332
|
+
var dataSrc = dt.column(_this.idx()).dataSrc();
|
|
1333
|
+
if (btn.active()) {
|
|
1334
|
+
// Grouping is active - remove
|
|
1335
|
+
rowGroupRemove$1(dt, dataSrc);
|
|
1336
|
+
}
|
|
1337
|
+
else {
|
|
1338
|
+
// No grouping by this column yet, set it
|
|
1339
|
+
rowGroupClear$1(dt);
|
|
1340
|
+
rowGroupAdd$1(dt, dataSrc);
|
|
1341
|
+
if (config.order !== false) {
|
|
1342
|
+
dt.order([_this.idx(), 'asc']);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
dt.draw();
|
|
1346
|
+
});
|
|
1347
|
+
// Show as active when grouping is applied
|
|
1348
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1349
|
+
var applied = rowGroupApplied(dt);
|
|
1350
|
+
var ours = dt.column(_this.idx()).dataSrc();
|
|
1351
|
+
btn.active(applied.includes(ours));
|
|
1352
|
+
});
|
|
1353
|
+
return btn.element();
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1357
|
+
var rowGroupAdd = {
|
|
1358
|
+
defaults: {
|
|
1359
|
+
className: 'rowGroupAdd',
|
|
1360
|
+
icon: 'groupAdd',
|
|
1361
|
+
order: true,
|
|
1362
|
+
text: 'Add to grouping'
|
|
1363
|
+
},
|
|
1364
|
+
init: function (config) {
|
|
1365
|
+
var _this = this;
|
|
1366
|
+
var dt = this.dt();
|
|
1367
|
+
var btn = new Button(dt, this)
|
|
1368
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1369
|
+
.icon(config.icon)
|
|
1370
|
+
.className(config.className)
|
|
1371
|
+
.handler(function () {
|
|
1372
|
+
var dataSrc = dt.column(_this.idx()).dataSrc();
|
|
1373
|
+
if (btn.enable()) {
|
|
1374
|
+
// No grouping by this column yet, add it
|
|
1375
|
+
rowGroupAdd$1(dt, dataSrc);
|
|
1376
|
+
}
|
|
1377
|
+
dt.draw();
|
|
1378
|
+
});
|
|
1379
|
+
// Show as active when grouping is applied
|
|
1380
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1381
|
+
var applied = rowGroupApplied(dt);
|
|
1382
|
+
var ours = dt.column(_this.idx()).dataSrc();
|
|
1383
|
+
btn.enable(!applied.includes(ours));
|
|
1384
|
+
});
|
|
1385
|
+
return btn.element();
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
|
|
1389
|
+
var rowGroupClear = {
|
|
1390
|
+
defaults: {
|
|
1391
|
+
className: 'rowGroupClear',
|
|
1392
|
+
icon: 'groupClear',
|
|
1393
|
+
text: 'Clear all grouping'
|
|
1394
|
+
},
|
|
1395
|
+
init: function (config) {
|
|
1396
|
+
var dt = this.dt();
|
|
1397
|
+
var btn = new Button(dt, this)
|
|
1398
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1399
|
+
.icon(config.icon)
|
|
1400
|
+
.className(config.className)
|
|
1401
|
+
.handler(function () {
|
|
1402
|
+
rowGroupClear$1(dt);
|
|
1403
|
+
dt.draw();
|
|
1404
|
+
});
|
|
1405
|
+
// Show as active when any grouping is applied
|
|
1406
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1407
|
+
btn.enable(rowGroupApplied(dt).length > 0);
|
|
1408
|
+
});
|
|
1409
|
+
// Default status
|
|
1410
|
+
btn.enable(rowGroupApplied(dt).length > 0);
|
|
1411
|
+
return btn.element();
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
|
|
1415
|
+
var rowGroupRemove = {
|
|
1416
|
+
defaults: {
|
|
1417
|
+
className: 'rowGroupRemove',
|
|
1418
|
+
icon: 'groupRemove',
|
|
1419
|
+
order: true,
|
|
1420
|
+
text: 'Remove from grouping'
|
|
1421
|
+
},
|
|
1422
|
+
init: function (config) {
|
|
1423
|
+
var _this = this;
|
|
1424
|
+
var dt = this.dt();
|
|
1425
|
+
var btn = new Button(dt, this)
|
|
1426
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1427
|
+
.icon(config.icon)
|
|
1428
|
+
.className(config.className)
|
|
1429
|
+
.handler(function () {
|
|
1430
|
+
var dataSrc = dt.column(_this.idx()).dataSrc();
|
|
1431
|
+
if (btn.enable()) {
|
|
1432
|
+
// Grouping is active - remove
|
|
1433
|
+
rowGroupRemove$1(dt, dataSrc);
|
|
1434
|
+
dt.draw();
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
// Show as active when grouping is applied
|
|
1438
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1439
|
+
var applied = rowGroupApplied(dt);
|
|
1440
|
+
var ours = dt.column(_this.idx()).dataSrc();
|
|
1441
|
+
btn.enable(applied.includes(ours));
|
|
1442
|
+
});
|
|
1443
|
+
// Default disabled
|
|
1444
|
+
btn.enable(false);
|
|
1445
|
+
return btn.element();
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1248
1449
|
var SearchInput = /** @class */ (function () {
|
|
1249
1450
|
/**
|
|
1250
1451
|
* Create a container element, for consistent DOM structure and styling
|
|
@@ -1252,6 +1453,8 @@ var SearchInput = /** @class */ (function () {
|
|
|
1252
1453
|
function SearchInput(dt, idx) {
|
|
1253
1454
|
var _this = this;
|
|
1254
1455
|
this._type = 'text';
|
|
1456
|
+
this._sspTransform = null;
|
|
1457
|
+
this._sspData = {};
|
|
1255
1458
|
this._dt = dt;
|
|
1256
1459
|
this._idx = idx;
|
|
1257
1460
|
this._dom = {
|
|
@@ -1290,28 +1493,28 @@ var SearchInput = /** @class */ (function () {
|
|
|
1290
1493
|
});
|
|
1291
1494
|
// State handling - all components that use this class have the same state saving structure
|
|
1292
1495
|
// so shared handling can be performed here.
|
|
1293
|
-
dt.on('stateSaveParams', function (e, s, data) {
|
|
1496
|
+
dt.on('stateSaveParams.DT', function (e, s, data) {
|
|
1294
1497
|
if (!data.columnControl) {
|
|
1295
1498
|
data.columnControl = {};
|
|
1296
1499
|
}
|
|
1297
|
-
if (!data.columnControl[
|
|
1298
|
-
data.columnControl[
|
|
1500
|
+
if (!data.columnControl[_this._idx]) {
|
|
1501
|
+
data.columnControl[_this._idx] = {};
|
|
1299
1502
|
}
|
|
1300
|
-
data.columnControl[
|
|
1503
|
+
data.columnControl[_this._idx].searchInput = {
|
|
1301
1504
|
logic: dom.select.value,
|
|
1302
1505
|
type: _this._type,
|
|
1303
1506
|
value: dom.input.value
|
|
1304
1507
|
};
|
|
1305
1508
|
});
|
|
1306
|
-
dt.on('stateLoaded', function (e, s, state) {
|
|
1509
|
+
dt.on('stateLoaded.DT', function (e, s, state) {
|
|
1307
1510
|
_this._stateLoad(state);
|
|
1308
1511
|
});
|
|
1309
1512
|
// Same as for ColumnControl - reassign a column index if needed.
|
|
1310
|
-
dt.on('columns-reordered', function (e, details) {
|
|
1513
|
+
dt.on('columns-reordered.DT', function (e, details) {
|
|
1311
1514
|
_this._idx = dt.colReorder.transpose(originalIdx, 'fromOriginal');
|
|
1312
1515
|
});
|
|
1313
|
-
// Column control search clearing (column().
|
|
1314
|
-
dt.on('cc-search-clear', function (e, colIdx) {
|
|
1516
|
+
// Column control search clearing (column().columnControl.searchClear() method)
|
|
1517
|
+
dt.on('cc-search-clear.DT', function (e, colIdx) {
|
|
1315
1518
|
if (colIdx === _this._idx) {
|
|
1316
1519
|
// Don't want an automatic redraw on this event
|
|
1317
1520
|
_this._loadingState = true;
|
|
@@ -1319,6 +1522,23 @@ var SearchInput = /** @class */ (function () {
|
|
|
1319
1522
|
_this._loadingState = false;
|
|
1320
1523
|
}
|
|
1321
1524
|
});
|
|
1525
|
+
// Data for server-side processing
|
|
1526
|
+
if (dt.page.info().serverSide) {
|
|
1527
|
+
dt.on('preXhr.DT', function (e, s, d) {
|
|
1528
|
+
if (!d.columns[_this._idx].columnControl) {
|
|
1529
|
+
d.columns[_this._idx].columnControl = {};
|
|
1530
|
+
}
|
|
1531
|
+
var val = _this._dom.input.value;
|
|
1532
|
+
if (_this._sspTransform) {
|
|
1533
|
+
val = _this._sspTransform(val);
|
|
1534
|
+
}
|
|
1535
|
+
d.columns[_this._idx].columnControl.search = Object.assign({
|
|
1536
|
+
value: val,
|
|
1537
|
+
logic: _this._dom.select.value,
|
|
1538
|
+
type: _this._type
|
|
1539
|
+
}, _this._sspData);
|
|
1540
|
+
});
|
|
1541
|
+
}
|
|
1322
1542
|
}
|
|
1323
1543
|
/**
|
|
1324
1544
|
* Add a class to the container
|
|
@@ -1441,6 +1661,26 @@ var SearchInput = /** @class */ (function () {
|
|
|
1441
1661
|
this.runSearch();
|
|
1442
1662
|
return this;
|
|
1443
1663
|
};
|
|
1664
|
+
/**
|
|
1665
|
+
* Set a function to transform the input value before SSP data submission
|
|
1666
|
+
*
|
|
1667
|
+
* @param fn Transform function
|
|
1668
|
+
* @returns Self for chaining
|
|
1669
|
+
*/
|
|
1670
|
+
SearchInput.prototype.sspTransform = function (fn) {
|
|
1671
|
+
this._sspTransform = fn;
|
|
1672
|
+
return this;
|
|
1673
|
+
};
|
|
1674
|
+
/**
|
|
1675
|
+
* Set extra information to be send to the server for server-side processing
|
|
1676
|
+
*
|
|
1677
|
+
* @param data Data object
|
|
1678
|
+
* @returns Self for chaining
|
|
1679
|
+
*/
|
|
1680
|
+
SearchInput.prototype.sspData = function (data) {
|
|
1681
|
+
this._sspData = data;
|
|
1682
|
+
return this;
|
|
1683
|
+
};
|
|
1444
1684
|
/**
|
|
1445
1685
|
* Set the text that will be shown as the title for the control
|
|
1446
1686
|
*
|
|
@@ -1503,6 +1743,8 @@ var SearchInput = /** @class */ (function () {
|
|
|
1503
1743
|
var searchDateTime = {
|
|
1504
1744
|
defaults: {
|
|
1505
1745
|
clear: true,
|
|
1746
|
+
format: '',
|
|
1747
|
+
mask: '',
|
|
1506
1748
|
placeholder: '',
|
|
1507
1749
|
title: '',
|
|
1508
1750
|
titleAttr: ''
|
|
@@ -1514,11 +1756,14 @@ var searchDateTime = {
|
|
|
1514
1756
|
var luxon = DataTable.use('luxon');
|
|
1515
1757
|
var dt = this.dt();
|
|
1516
1758
|
var i18nBase = 'columnControl.search.datetime.';
|
|
1517
|
-
var
|
|
1759
|
+
var pickerFormat = '';
|
|
1760
|
+
var dataSrcFormat = '';
|
|
1518
1761
|
var dateTime;
|
|
1519
1762
|
var searchInput = new SearchInput(dt, this.idx())
|
|
1520
1763
|
.type('date')
|
|
1521
1764
|
.addClass('dtcc-searchDateTime')
|
|
1765
|
+
.sspTransform(function (val) { return toISO(val, pickerFormat, moment, luxon); })
|
|
1766
|
+
.sspData({ mask: config.mask })
|
|
1522
1767
|
.clearable(config.clear)
|
|
1523
1768
|
.placeholder(config.placeholder)
|
|
1524
1769
|
.title(config.title)
|
|
@@ -1532,10 +1777,18 @@ var searchDateTime = {
|
|
|
1532
1777
|
{ label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
|
|
1533
1778
|
])
|
|
1534
1779
|
.search(function (searchType, searchTerm, loadingState) {
|
|
1780
|
+
// When SSP, don't apply a filter here, SearchInput will add to the submit data
|
|
1781
|
+
if (dt.page.info().serverSide) {
|
|
1782
|
+
if (!loadingState) {
|
|
1783
|
+
dt.draw();
|
|
1784
|
+
}
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
var mask = config.mask;
|
|
1535
1788
|
var column = dt.column(_this.idx());
|
|
1536
1789
|
var search = searchTerm === ''
|
|
1537
1790
|
? ''
|
|
1538
|
-
: dateToNum(dateTime && fromPicker ? dateTime.val() : searchTerm.trim(),
|
|
1791
|
+
: dateToNum(dateTime && fromPicker ? dateTime.val() : searchTerm.trim(), pickerFormat, moment, luxon, mask);
|
|
1539
1792
|
if (searchType === 'empty') {
|
|
1540
1793
|
column.search.fixed('dtcc', function (haystack) { return !haystack; });
|
|
1541
1794
|
}
|
|
@@ -1554,16 +1807,24 @@ var searchDateTime = {
|
|
|
1554
1807
|
// Use a function for matching - weak typing
|
|
1555
1808
|
// Note that the haystack in the search function is the rendered date - it
|
|
1556
1809
|
// might need to be converted back to a date
|
|
1557
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1810
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1811
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) == search;
|
|
1812
|
+
});
|
|
1558
1813
|
}
|
|
1559
1814
|
else if (searchType === 'notEqual') {
|
|
1560
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1815
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1816
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) != search;
|
|
1817
|
+
});
|
|
1561
1818
|
}
|
|
1562
1819
|
else if (searchType === 'greater') {
|
|
1563
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1820
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1821
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) > search;
|
|
1822
|
+
});
|
|
1564
1823
|
}
|
|
1565
1824
|
else if (searchType === 'less') {
|
|
1566
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1825
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1826
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) < search;
|
|
1827
|
+
});
|
|
1567
1828
|
}
|
|
1568
1829
|
// If in a dropdown, set the parent levels as active
|
|
1569
1830
|
if (config._parents) {
|
|
@@ -1578,10 +1839,13 @@ var searchDateTime = {
|
|
|
1578
1839
|
// Once data has been loaded we can run DateTime with the specified format
|
|
1579
1840
|
dt.ready(function () {
|
|
1580
1841
|
var DateTime = DataTable.use('datetime');
|
|
1581
|
-
|
|
1842
|
+
dataSrcFormat = getFormat(dt, _this.idx());
|
|
1843
|
+
pickerFormat = config.format
|
|
1844
|
+
? config.format
|
|
1845
|
+
: dataSrcFormat;
|
|
1582
1846
|
if (DateTime) {
|
|
1583
1847
|
dateTime = new DateTime(searchInput.input(), {
|
|
1584
|
-
format:
|
|
1848
|
+
format: pickerFormat,
|
|
1585
1849
|
i18n: dt.settings()[0].oLanguage.datetime, // could be undefined
|
|
1586
1850
|
onChange: function () {
|
|
1587
1851
|
fromPicker = true;
|
|
@@ -1608,18 +1872,36 @@ function getFormat(dt, column) {
|
|
|
1608
1872
|
return 'YYYY-MM-DD';
|
|
1609
1873
|
}
|
|
1610
1874
|
else if (type === 'datetime') {
|
|
1611
|
-
// If no format was specified in the DT type,
|
|
1612
|
-
//
|
|
1613
|
-
|
|
1614
|
-
var
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
.
|
|
1875
|
+
// If no format was specified in the DT type, a Javascript native toLocaleDateString
|
|
1876
|
+
// was used. Need to work out what that format is in Moment or Luxon. We need to pass
|
|
1877
|
+
// a known value though the renderer and work out the format
|
|
1878
|
+
var renderer = dt.settings()[0].aoColumns[column].mRender;
|
|
1879
|
+
var resultPm = renderer('1999-08-07T23:05:04Z', 'display');
|
|
1880
|
+
var resultAm = renderer('1999-08-07T03:05:04Z', 'display');
|
|
1881
|
+
var leadingZero = resultAm.includes('03');
|
|
1882
|
+
// What formatter are we using?
|
|
1883
|
+
if (DataTable.use('moment')) {
|
|
1884
|
+
return resultPm
|
|
1885
|
+
.replace('23', leadingZero ? 'HH' : 'H')
|
|
1886
|
+
.replace('11', leadingZero ? 'hh' : 'h')
|
|
1887
|
+
.replace('05', 'mm')
|
|
1888
|
+
.replace('04', 'ss')
|
|
1889
|
+
.replace('PM', 'A')
|
|
1890
|
+
.replace('pm', 'a')
|
|
1891
|
+
.replace('07', 'DD')
|
|
1892
|
+
.replace('7', 'D')
|
|
1893
|
+
.replace('08', 'MM')
|
|
1894
|
+
.replace('8', 'M')
|
|
1895
|
+
.replace('1999', 'YYYY')
|
|
1896
|
+
.replace('99', 'YY');
|
|
1897
|
+
}
|
|
1898
|
+
else if (DataTable.use('luxon')) {
|
|
1899
|
+
return resultPm
|
|
1900
|
+
.replace('23', leadingZero ? 'HH' : 'H')
|
|
1901
|
+
.replace('11', leadingZero ? 'hh' : 'h')
|
|
1902
|
+
.replace('05', 'mm')
|
|
1903
|
+
.replace('04', 'ss')
|
|
1904
|
+
.replace('PM', 'a')
|
|
1623
1905
|
.replace('07', 'dd')
|
|
1624
1906
|
.replace('7', 'd')
|
|
1625
1907
|
.replace('08', 'MM')
|
|
@@ -1627,6 +1909,13 @@ function getFormat(dt, column) {
|
|
|
1627
1909
|
.replace('1999', 'yyyy')
|
|
1628
1910
|
.replace('99', 'yy');
|
|
1629
1911
|
}
|
|
1912
|
+
else if (resultPm.includes('23') && resultPm.includes('1999')) {
|
|
1913
|
+
return 'YYYY-MM-DD hh:mm:ss';
|
|
1914
|
+
}
|
|
1915
|
+
else if (resultPm.includes('23')) {
|
|
1916
|
+
return 'hh:mm:ss';
|
|
1917
|
+
}
|
|
1918
|
+
// fall through to final return
|
|
1630
1919
|
}
|
|
1631
1920
|
else if (type.includes('datetime-')) {
|
|
1632
1921
|
// Column was specified with a particular display format - we can extract that format from
|
|
@@ -1650,19 +1939,75 @@ function getFormat(dt, column) {
|
|
|
1650
1939
|
* @param luxon Luxon object, if it is available
|
|
1651
1940
|
* @returns Time stamp - milliseconds
|
|
1652
1941
|
*/
|
|
1653
|
-
function dateToNum(input, srcFormat, moment, luxon) {
|
|
1942
|
+
function dateToNum(input, srcFormat, moment, luxon, mask) {
|
|
1943
|
+
var d;
|
|
1654
1944
|
if (input === '') {
|
|
1655
1945
|
return '';
|
|
1656
1946
|
}
|
|
1657
|
-
|
|
1658
|
-
|
|
1947
|
+
if (input instanceof Date) {
|
|
1948
|
+
d = input;
|
|
1659
1949
|
}
|
|
1660
1950
|
else if (srcFormat !== 'YYYY-MM-DD' && (moment || luxon)) {
|
|
1661
|
-
|
|
1951
|
+
d = new Date(moment
|
|
1662
1952
|
? moment(input, srcFormat).unix() * 1000
|
|
1663
|
-
: luxon.DateTime.fromFormat(input, srcFormat).toMillis();
|
|
1953
|
+
: luxon.DateTime.fromFormat(input, srcFormat).toMillis());
|
|
1954
|
+
}
|
|
1955
|
+
else {
|
|
1956
|
+
// new Date() with `/` separators will treat the input as local time, but with `-` it will
|
|
1957
|
+
// treat it as UTC. We want UTC so do a replacement
|
|
1958
|
+
d = new Date(input.replace(/\//g, '-'));
|
|
1664
1959
|
}
|
|
1665
|
-
|
|
1960
|
+
if (mask) {
|
|
1961
|
+
if (!mask.includes('YYYY')) {
|
|
1962
|
+
d.setFullYear(1970);
|
|
1963
|
+
}
|
|
1964
|
+
if (!mask.includes('MM')) {
|
|
1965
|
+
d.setUTCMonth(0);
|
|
1966
|
+
}
|
|
1967
|
+
if (!mask.includes('DD')) {
|
|
1968
|
+
d.setUTCDate(1);
|
|
1969
|
+
}
|
|
1970
|
+
if (!mask.includes('hh')) {
|
|
1971
|
+
d.setUTCHours(0);
|
|
1972
|
+
}
|
|
1973
|
+
if (!mask.includes('mm')) {
|
|
1974
|
+
d.setUTCMinutes(0);
|
|
1975
|
+
}
|
|
1976
|
+
if (!mask.includes('ss')) {
|
|
1977
|
+
// This will match milliseconds as well, but that's fine, you won't match mS but not S
|
|
1978
|
+
d.setUTCSeconds(0);
|
|
1979
|
+
}
|
|
1980
|
+
if (!mask.includes('sss')) {
|
|
1981
|
+
d.setUTCMilliseconds(0);
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
return d.getTime();
|
|
1985
|
+
}
|
|
1986
|
+
/**
|
|
1987
|
+
* Convert an input string to an ISO formatted date
|
|
1988
|
+
*
|
|
1989
|
+
* @param input Input value
|
|
1990
|
+
* @param srcFormat String format of the input
|
|
1991
|
+
* @param moment Moment instance, if it is available
|
|
1992
|
+
* @param luxon Luxon object, if it is available
|
|
1993
|
+
* @returns Value in ISO
|
|
1994
|
+
*/
|
|
1995
|
+
function toISO(input, srcFormat, moment, luxon) {
|
|
1996
|
+
if (input === '') {
|
|
1997
|
+
return '';
|
|
1998
|
+
}
|
|
1999
|
+
else if (srcFormat !== 'YYYY-MM-DD' && moment) {
|
|
2000
|
+
// TODO Does it have a time component?
|
|
2001
|
+
return moment.utc(input, srcFormat).toISOString();
|
|
2002
|
+
}
|
|
2003
|
+
else if (srcFormat !== 'YYYY-MM-DD' && luxon) {
|
|
2004
|
+
// TODO Does it have a time component?
|
|
2005
|
+
return luxon.DateTime.fromFormat(input, srcFormat).toISO();
|
|
2006
|
+
}
|
|
2007
|
+
// new Date() with `/` separators will treat the input as local time, but with `-` it will
|
|
2008
|
+
// treat it as UTC. We want UTC so do a replacement
|
|
2009
|
+
input = input.replace(/\//g, '-');
|
|
2010
|
+
return input;
|
|
1666
2011
|
}
|
|
1667
2012
|
|
|
1668
2013
|
/** Set the options to show in the list */
|
|
@@ -1728,17 +2073,19 @@ function reloadOptions(dt, config, idx, checkList, loadedValues) {
|
|
|
1728
2073
|
options = jsonOptions;
|
|
1729
2074
|
}
|
|
1730
2075
|
else if (json && config.ajaxOnly) {
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
config._parents
|
|
2076
|
+
if (config.hidable) {
|
|
2077
|
+
// Ajax only options - need to hide the search list
|
|
2078
|
+
checkList.element().style.display = 'none';
|
|
2079
|
+
// Check if the parent buttons should be hidden as well (they will be if there
|
|
2080
|
+
// is no visible content in them)
|
|
2081
|
+
if (config._parents) {
|
|
2082
|
+
config._parents.forEach(function (btn) { return btn.checkDisplay(); });
|
|
2083
|
+
}
|
|
1737
2084
|
}
|
|
1738
2085
|
// No point in doing any further processing here
|
|
1739
2086
|
return;
|
|
1740
2087
|
}
|
|
1741
|
-
else {
|
|
2088
|
+
else if (!dt.page.info().serverSide) {
|
|
1742
2089
|
// Either no ajax object (i.e. not an Ajax table), or no matching ajax options
|
|
1743
2090
|
// for this column - get the values for the column, taking into account
|
|
1744
2091
|
// orthogonal rendering
|
|
@@ -1746,11 +2093,14 @@ function reloadOptions(dt, config, idx, checkList, loadedValues) {
|
|
|
1746
2093
|
var rows = dt.rows({ order: idx }).indexes().toArray();
|
|
1747
2094
|
var settings = dt.settings()[0];
|
|
1748
2095
|
for (var i = 0; i < rows.length; i++) {
|
|
1749
|
-
var
|
|
2096
|
+
var raw = settings.fastData(rows[i], idx, 'filter');
|
|
2097
|
+
var filter = raw !== null && raw !== undefined
|
|
2098
|
+
? raw.toString()
|
|
2099
|
+
: '';
|
|
1750
2100
|
if (!found[filter]) {
|
|
1751
2101
|
found[filter] = true;
|
|
1752
2102
|
options.push({
|
|
1753
|
-
label: settings.fastData(rows[i], idx,
|
|
2103
|
+
label: settings.fastData(rows[i], idx, config.orthogonal),
|
|
1754
2104
|
value: filter
|
|
1755
2105
|
});
|
|
1756
2106
|
}
|
|
@@ -1767,7 +2117,9 @@ var searchList = {
|
|
|
1767
2117
|
defaults: {
|
|
1768
2118
|
ajaxOnly: true,
|
|
1769
2119
|
className: 'searchList',
|
|
2120
|
+
hidable: true,
|
|
1770
2121
|
options: null,
|
|
2122
|
+
orthogonal: 'display',
|
|
1771
2123
|
search: true,
|
|
1772
2124
|
select: true,
|
|
1773
2125
|
title: ''
|
|
@@ -1779,6 +2131,10 @@ var searchList = {
|
|
|
1779
2131
|
// The search can be applied from a stored start at start up before the options are
|
|
1780
2132
|
// available. It can also be applied by user input, so it is generalised into this function.
|
|
1781
2133
|
var applySearch = function (values) {
|
|
2134
|
+
// When SSP, don't do any client-side filtering
|
|
2135
|
+
if (dt.page.info().serverSide) {
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
1782
2138
|
var col = dt.column(_this.idx());
|
|
1783
2139
|
if (!values) {
|
|
1784
2140
|
return;
|
|
@@ -1798,11 +2154,11 @@ var searchList = {
|
|
|
1798
2154
|
config._parents.forEach(function (btn) { return btn.activeList(_this.unique(), !!values.length); });
|
|
1799
2155
|
}
|
|
1800
2156
|
};
|
|
1801
|
-
var checkList = new CheckList(dt, {
|
|
2157
|
+
var checkList = new CheckList(dt, this, {
|
|
1802
2158
|
search: config.search,
|
|
1803
2159
|
select: config.select
|
|
1804
2160
|
})
|
|
1805
|
-
.searchListener(dt
|
|
2161
|
+
.searchListener(dt)
|
|
1806
2162
|
.title(dt
|
|
1807
2163
|
.i18n('columnControl.searchList', config.title)
|
|
1808
2164
|
.replace('[title]', dt.column(this.idx()).title()))
|
|
@@ -1822,14 +2178,24 @@ var searchList = {
|
|
|
1822
2178
|
dt.ready(function () {
|
|
1823
2179
|
reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
|
|
1824
2180
|
});
|
|
2181
|
+
// Xhr event listener for updates of options
|
|
2182
|
+
dt.on('xhr', function (e, s, json) {
|
|
2183
|
+
// Need to wait for the draw to complete so the table has the latest data
|
|
2184
|
+
dt.one('draw', function () {
|
|
2185
|
+
reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
|
|
2186
|
+
});
|
|
2187
|
+
});
|
|
1825
2188
|
}
|
|
1826
|
-
//
|
|
1827
|
-
dt.
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
2189
|
+
// Data for server-side processing
|
|
2190
|
+
if (dt.page.info().serverSide) {
|
|
2191
|
+
dt.on('preXhr.DT', function (e, s, d) {
|
|
2192
|
+
if (!d.columns[_this.idx()].columnControl) {
|
|
2193
|
+
d.columns[_this.idx()].columnControl = {};
|
|
2194
|
+
}
|
|
2195
|
+
// We need the indexes in the HTTP parameter names (for .NET), so use an object.
|
|
2196
|
+
d.columns[_this.idx()].columnControl.list = Object.assign({}, checkList.values());
|
|
1831
2197
|
});
|
|
1832
|
-
}
|
|
2198
|
+
}
|
|
1833
2199
|
// Unlike the SearchInput based search contents, CheckList does not handle state saving
|
|
1834
2200
|
// (since the mechanism for column visibility is different), so state saving is handled
|
|
1835
2201
|
// here.
|
|
@@ -1837,6 +2203,7 @@ var searchList = {
|
|
|
1837
2203
|
var values = getState(_this.idx(), state);
|
|
1838
2204
|
if (values) {
|
|
1839
2205
|
checkList.values(values);
|
|
2206
|
+
applySearch(values);
|
|
1840
2207
|
}
|
|
1841
2208
|
});
|
|
1842
2209
|
dt.on('stateSaveParams', function (e, s, data) {
|
|
@@ -1854,6 +2221,14 @@ var searchList = {
|
|
|
1854
2221
|
? checkList.values()
|
|
1855
2222
|
: loadedValues;
|
|
1856
2223
|
});
|
|
2224
|
+
dt.settings()[0].aoColumns[this.idx()].columnControlSearchList = function (options) {
|
|
2225
|
+
if (options === 'refresh') {
|
|
2226
|
+
reloadOptions(dt, config, _this.idx(), checkList, null);
|
|
2227
|
+
}
|
|
2228
|
+
else {
|
|
2229
|
+
setOptions(checkList, options);
|
|
2230
|
+
}
|
|
2231
|
+
};
|
|
1857
2232
|
loadedValues = getState(this.idx(), dt.state.loaded());
|
|
1858
2233
|
applySearch(loadedValues);
|
|
1859
2234
|
return checkList.element();
|
|
@@ -1892,6 +2267,13 @@ var searchNumber = {
|
|
|
1892
2267
|
{ label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
|
|
1893
2268
|
])
|
|
1894
2269
|
.search(function (searchType, searchTerm, loadingState) {
|
|
2270
|
+
// When SSP, don't apply a filter here, SearchInput will add to the submit data
|
|
2271
|
+
if (dt.page.info().serverSide) {
|
|
2272
|
+
if (!loadingState) {
|
|
2273
|
+
dt.draw();
|
|
2274
|
+
}
|
|
2275
|
+
return;
|
|
2276
|
+
}
|
|
1895
2277
|
var column = dt.column(_this.idx());
|
|
1896
2278
|
if (searchType === 'empty') {
|
|
1897
2279
|
column.search.fixed('dtcc', function (haystack) { return !haystack; });
|
|
@@ -1989,6 +2371,13 @@ var searchText = {
|
|
|
1989
2371
|
{ label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
|
|
1990
2372
|
])
|
|
1991
2373
|
.search(function (searchType, searchTerm, loadingState) {
|
|
2374
|
+
// When SSP, don't apply a filter here, SearchInput will add to the submit data
|
|
2375
|
+
if (dt.page.info().serverSide) {
|
|
2376
|
+
if (!loadingState) {
|
|
2377
|
+
dt.draw();
|
|
2378
|
+
}
|
|
2379
|
+
return;
|
|
2380
|
+
}
|
|
1992
2381
|
var column = dt.column(_this.idx());
|
|
1993
2382
|
searchTerm = searchTerm.toLowerCase();
|
|
1994
2383
|
if (searchType === 'empty') {
|
|
@@ -2095,7 +2484,7 @@ var search = {
|
|
|
2095
2484
|
}
|
|
2096
2485
|
};
|
|
2097
2486
|
|
|
2098
|
-
var searchClear = {
|
|
2487
|
+
var searchClear$1 = {
|
|
2099
2488
|
defaults: {
|
|
2100
2489
|
className: 'searchClear',
|
|
2101
2490
|
icon: 'searchClear',
|
|
@@ -2104,12 +2493,12 @@ var searchClear = {
|
|
|
2104
2493
|
init: function (config) {
|
|
2105
2494
|
var _this = this;
|
|
2106
2495
|
var dt = this.dt();
|
|
2107
|
-
var btn = new Button(dt)
|
|
2496
|
+
var btn = new Button(dt, this)
|
|
2108
2497
|
.text(dt.i18n('columnControl.searchClear', config.text))
|
|
2109
2498
|
.icon(config.icon)
|
|
2110
2499
|
.className(config.className)
|
|
2111
2500
|
.handler(function () {
|
|
2112
|
-
dt.column(_this.idx()).
|
|
2501
|
+
dt.column(_this.idx()).columnControl.searchClear().draw();
|
|
2113
2502
|
})
|
|
2114
2503
|
.enable(false);
|
|
2115
2504
|
dt.on('draw', function () {
|
|
@@ -2129,7 +2518,9 @@ var searchDropdown = {
|
|
|
2129
2518
|
className: 'searchDropdown',
|
|
2130
2519
|
clear: true,
|
|
2131
2520
|
columns: '',
|
|
2521
|
+
hidable: true,
|
|
2132
2522
|
options: null,
|
|
2523
|
+
orthogonal: 'display',
|
|
2133
2524
|
placeholder: '',
|
|
2134
2525
|
search: true,
|
|
2135
2526
|
select: true,
|
|
@@ -2186,6 +2577,10 @@ var contentTypes = {
|
|
|
2186
2577
|
reorder: reorder,
|
|
2187
2578
|
reorderLeft: reorderLeft,
|
|
2188
2579
|
reorderRight: reorderRight,
|
|
2580
|
+
rowGroup: rowGroup,
|
|
2581
|
+
rowGroupAdd: rowGroupAdd,
|
|
2582
|
+
rowGroupClear: rowGroupClear,
|
|
2583
|
+
rowGroupRemove: rowGroupRemove,
|
|
2189
2584
|
order: order,
|
|
2190
2585
|
orderAddAsc: orderAddAsc,
|
|
2191
2586
|
orderAddDesc: orderAddDesc,
|
|
@@ -2195,7 +2590,7 @@ var contentTypes = {
|
|
|
2195
2590
|
orderRemove: orderRemove,
|
|
2196
2591
|
orderStatus: orderStatus,
|
|
2197
2592
|
search: search,
|
|
2198
|
-
searchClear: searchClear,
|
|
2593
|
+
searchClear: searchClear$1,
|
|
2199
2594
|
searchDropdown: searchDropdown,
|
|
2200
2595
|
searchDateTime: searchDateTime,
|
|
2201
2596
|
searchList: searchList,
|
|
@@ -2225,7 +2620,8 @@ var ColumnControl = /** @class */ (function () {
|
|
|
2225
2620
|
this._c = {};
|
|
2226
2621
|
this._s = {
|
|
2227
2622
|
columnIdx: null,
|
|
2228
|
-
unique: null
|
|
2623
|
+
unique: null,
|
|
2624
|
+
toDestroy: []
|
|
2229
2625
|
};
|
|
2230
2626
|
this._dt = dt;
|
|
2231
2627
|
this._s.columnIdx = columnIdx;
|
|
@@ -2251,10 +2647,33 @@ var ColumnControl = /** @class */ (function () {
|
|
|
2251
2647
|
_this._dom.wrapper.appendChild(el);
|
|
2252
2648
|
});
|
|
2253
2649
|
dt.on('destroy', function () {
|
|
2650
|
+
_this._s.toDestroy.slice().forEach(function (el) {
|
|
2651
|
+
el.destroy();
|
|
2652
|
+
});
|
|
2254
2653
|
_this._dom.wrapper.remove();
|
|
2255
2654
|
});
|
|
2256
2655
|
}
|
|
2257
2656
|
}
|
|
2657
|
+
/**
|
|
2658
|
+
* Add a component to the destroy list. This is so there is a single destroy event handler,
|
|
2659
|
+
* which is much better for performance.
|
|
2660
|
+
*
|
|
2661
|
+
* @param component Any instance with a `destroy` method
|
|
2662
|
+
*/
|
|
2663
|
+
ColumnControl.prototype.destroyAdd = function (component) {
|
|
2664
|
+
this._s.toDestroy.push(component);
|
|
2665
|
+
};
|
|
2666
|
+
/**
|
|
2667
|
+
* Remove an instance from the destroy list (it has been destroyed itself)
|
|
2668
|
+
*
|
|
2669
|
+
* @param component Any instance with a `destroy` method
|
|
2670
|
+
*/
|
|
2671
|
+
ColumnControl.prototype.destroyRemove = function (component) {
|
|
2672
|
+
var idx = this._s.toDestroy.indexOf(component);
|
|
2673
|
+
if (idx !== -1) {
|
|
2674
|
+
this._s.toDestroy.splice(idx, 1);
|
|
2675
|
+
}
|
|
2676
|
+
};
|
|
2258
2677
|
/**
|
|
2259
2678
|
* Get the DataTables API instance that hosts this instance of ColumnControl
|
|
2260
2679
|
*
|
|
@@ -2365,7 +2784,7 @@ var ColumnControl = /** @class */ (function () {
|
|
|
2365
2784
|
/** SVG icons that can be used by the content plugins */
|
|
2366
2785
|
ColumnControl.icons = icons;
|
|
2367
2786
|
/** Version */
|
|
2368
|
-
ColumnControl.version = '1.0
|
|
2787
|
+
ColumnControl.version = '1.1.0';
|
|
2369
2788
|
return ColumnControl;
|
|
2370
2789
|
}());
|
|
2371
2790
|
|
|
@@ -2394,7 +2813,9 @@ $(document).on('i18n.dt', function (e, settings) {
|
|
|
2394
2813
|
settings.titleRow = 0;
|
|
2395
2814
|
}
|
|
2396
2815
|
identifyTargets(baseTargets, tableInit);
|
|
2397
|
-
|
|
2816
|
+
if (ColumnControl.defaults.content) {
|
|
2817
|
+
identifyTargets(baseTargets, defaultInit);
|
|
2818
|
+
}
|
|
2398
2819
|
api.columns().every(function (i) {
|
|
2399
2820
|
var columnInit = this.init().columnControl;
|
|
2400
2821
|
identifyTargets(baseTargets, columnInit);
|
|
@@ -2414,7 +2835,10 @@ $(document).on('preInit.dt', function (e, settings) {
|
|
|
2414
2835
|
var defaultInit = ColumnControl.defaults;
|
|
2415
2836
|
var baseTargets = [];
|
|
2416
2837
|
identifyTargets(baseTargets, tableInit);
|
|
2417
|
-
|
|
2838
|
+
// Only add the default target if there is actually content for it
|
|
2839
|
+
if (ColumnControl.defaults.content) {
|
|
2840
|
+
identifyTargets(baseTargets, defaultInit);
|
|
2841
|
+
}
|
|
2418
2842
|
api.columns().every(function (i) {
|
|
2419
2843
|
var columnInit = this.init().columnControl;
|
|
2420
2844
|
var targets = identifyTargets(baseTargets.slice(), columnInit);
|
|
@@ -2432,12 +2856,20 @@ $(document).on('preInit.dt', function (e, settings) {
|
|
|
2432
2856
|
}
|
|
2433
2857
|
});
|
|
2434
2858
|
});
|
|
2435
|
-
|
|
2859
|
+
function searchClear() {
|
|
2436
2860
|
var ctx = this;
|
|
2437
2861
|
return this.iterator('column', function (settings, idx) {
|
|
2438
2862
|
// Note that the listeners for this will not redraw the table.
|
|
2439
2863
|
ctx.trigger('cc-search-clear', [idx]);
|
|
2440
2864
|
});
|
|
2865
|
+
}
|
|
2866
|
+
DataTable.Api.registerPlural('columns().columnControl.searchClear()', 'column().columnControl.searchClear()', searchClear);
|
|
2867
|
+
// Legacy (1.0.x)) - was never documented, but was mentioned in the forum
|
|
2868
|
+
DataTable.Api.registerPlural('columns().ccSearchClear()', 'column().ccSearchClear()', searchClear);
|
|
2869
|
+
DataTable.Api.registerPlural('columns().columnControl.searchList()', 'column().columnControl.searchList()', function (options) {
|
|
2870
|
+
return this.iterator('column', function (settings, idx) {
|
|
2871
|
+
settings.aoColumns[idx].columnControlSearchList(options);
|
|
2872
|
+
});
|
|
2441
2873
|
});
|
|
2442
2874
|
DataTable.ext.buttons.ccSearchClear = {
|
|
2443
2875
|
text: function (dt) {
|
|
@@ -2445,7 +2877,7 @@ DataTable.ext.buttons.ccSearchClear = {
|
|
|
2445
2877
|
},
|
|
2446
2878
|
init: function (dt, node, config) {
|
|
2447
2879
|
var _this = this;
|
|
2448
|
-
dt.on('draw', function () {
|
|
2880
|
+
dt.on('draw.DT', function () {
|
|
2449
2881
|
var enabled = false;
|
|
2450
2882
|
var glob = !!dt.search();
|
|
2451
2883
|
// No point in wasting clock cycles if we already know it will be enabled
|
|
@@ -2462,7 +2894,7 @@ DataTable.ext.buttons.ccSearchClear = {
|
|
|
2462
2894
|
},
|
|
2463
2895
|
action: function (e, dt, node, config) {
|
|
2464
2896
|
dt.search('');
|
|
2465
|
-
dt.columns().
|
|
2897
|
+
dt.columns().columnControl.searchClear();
|
|
2466
2898
|
dt.draw();
|
|
2467
2899
|
}
|
|
2468
2900
|
};
|
|
@@ -2598,12 +3030,18 @@ function identifyTargets(targets, input) {
|
|
|
2598
3030
|
}
|
|
2599
3031
|
}
|
|
2600
3032
|
if (Array.isArray(input)) {
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
add(
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
3033
|
+
if (input.length === 0) {
|
|
3034
|
+
// Empty array - assume it is empty content
|
|
3035
|
+
add(ColumnControl.defaults.target);
|
|
3036
|
+
}
|
|
3037
|
+
else {
|
|
3038
|
+
// Array of options, or an array of content
|
|
3039
|
+
input.forEach(function (item) {
|
|
3040
|
+
add(typeof item === 'object' && item.target !== undefined
|
|
3041
|
+
? item.target
|
|
3042
|
+
: ColumnControl.defaults.target);
|
|
3043
|
+
});
|
|
3044
|
+
}
|
|
2607
3045
|
}
|
|
2608
3046
|
else if (typeof input === 'object') {
|
|
2609
3047
|
// Full options defined: { target: x, content: [] }
|
|
@@ -2618,9 +3056,7 @@ function identifyTargets(targets, input) {
|
|
|
2618
3056
|
* @returns true if it is a config object
|
|
2619
3057
|
*/
|
|
2620
3058
|
function isIConfig(item) {
|
|
2621
|
-
return typeof item === 'object' && item.target !== undefined
|
|
2622
|
-
? true
|
|
2623
|
-
: false;
|
|
3059
|
+
return typeof item === 'object' && item.target !== undefined ? true : false;
|
|
2624
3060
|
}
|
|
2625
3061
|
/**
|
|
2626
3062
|
* Determine if an array contains only content items or not
|