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
|
|
@@ -62,6 +62,14 @@ var icons = {
|
|
|
62
62
|
greater: wrap('<path d="m9 18 6-6-6-6"/>'),
|
|
63
63
|
// Custom
|
|
64
64
|
greaterOrEqual: wrap('<path d="m9 16 6-6-6-6"/><path d="m9 21 6-6"/>'),
|
|
65
|
+
// Custom
|
|
66
|
+
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"/>'),
|
|
67
|
+
// Custom
|
|
68
|
+
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"/>'),
|
|
69
|
+
// Custom
|
|
70
|
+
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"/>'),
|
|
71
|
+
// Custom
|
|
72
|
+
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"/>'),
|
|
65
73
|
less: wrap('<path d="m15 18-6-6 6-6"/>'),
|
|
66
74
|
// Custom
|
|
67
75
|
lessOrEqual: wrap('<path d="m15 16-6-6 6-6"/><path d="m15 21-6-6"/>'),
|
|
@@ -168,6 +176,7 @@ function attachDropdown(dropdown, dt, btn) {
|
|
|
168
176
|
dropdown._shown = true;
|
|
169
177
|
dtContainer.append(dropdown);
|
|
170
178
|
positionDropdown(dropdown, dt, btn.element());
|
|
179
|
+
btn.element().setAttribute('aria-expanded', 'true');
|
|
171
180
|
// Note that this could be called when the dropdown has already been removed from the document
|
|
172
181
|
// via another dropdown being shown. This will clean up the event on the next body click.
|
|
173
182
|
var removeDropdown = function (e) {
|
|
@@ -180,6 +189,12 @@ function attachDropdown(dropdown, dt, btn) {
|
|
|
180
189
|
if (e.target === dropdown || dropdown.contains(e.target)) {
|
|
181
190
|
return;
|
|
182
191
|
}
|
|
192
|
+
// If there is currently a datetime picker visible on the page, assume that it belongs to
|
|
193
|
+
// this dropdown. Don't want to close while operating on the picker.
|
|
194
|
+
var datetime = document.querySelector('div.dt-datetime');
|
|
195
|
+
if (datetime && (e.target === datetime || datetime.contains(e.target))) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
183
198
|
dropdown._close();
|
|
184
199
|
document.body.removeEventListener('click', removeDropdown);
|
|
185
200
|
};
|
|
@@ -277,6 +292,7 @@ var dropdownContent = {
|
|
|
277
292
|
dropdown._close = function () {
|
|
278
293
|
dropdown.remove();
|
|
279
294
|
dropdown._shown = false;
|
|
295
|
+
btn.element().setAttribute('aria-expanded', 'false');
|
|
280
296
|
};
|
|
281
297
|
dropdown.setAttribute('role', 'dialog');
|
|
282
298
|
dropdown.setAttribute('aria-label', dt.i18n('columnControl.dropdown', config.text));
|
|
@@ -289,7 +305,7 @@ var dropdownContent = {
|
|
|
289
305
|
});
|
|
290
306
|
// A liner element allows more styling options, so the contents go inside this
|
|
291
307
|
var liner = dropdown.childNodes[0];
|
|
292
|
-
var btn = new Button(dt)
|
|
308
|
+
var btn = new Button(dt, this)
|
|
293
309
|
.text(dt.i18n('columnControl.dropdown', config.text))
|
|
294
310
|
.icon(config.icon)
|
|
295
311
|
.className(config.className)
|
|
@@ -308,6 +324,7 @@ var dropdownContent = {
|
|
|
308
324
|
}
|
|
309
325
|
});
|
|
310
326
|
btn.element().setAttribute('aria-haspopup', 'dialog');
|
|
327
|
+
btn.element().setAttribute('aria-expanded', 'false');
|
|
311
328
|
// Add the content for the dropdown
|
|
312
329
|
for (var i = 0; i < config.content.length; i++) {
|
|
313
330
|
var content = this.resolve(config.content[i]);
|
|
@@ -344,18 +361,20 @@ var Button = /** @class */ (function () {
|
|
|
344
361
|
* Create a new button for use in ColumnControl contents. Buttons created by this class can be
|
|
345
362
|
* used at the top level in the header or in a dropdown.
|
|
346
363
|
*/
|
|
347
|
-
function Button(dt) {
|
|
364
|
+
function Button(dt, host) {
|
|
348
365
|
this._s = {
|
|
349
366
|
active: false,
|
|
350
367
|
activeList: [],
|
|
351
368
|
buttonClick: null,
|
|
352
369
|
dt: null,
|
|
353
370
|
enabled: true,
|
|
371
|
+
host: null,
|
|
354
372
|
label: '',
|
|
355
373
|
namespace: '',
|
|
356
374
|
value: null
|
|
357
375
|
};
|
|
358
376
|
this._s.dt = dt;
|
|
377
|
+
this._s.host = host;
|
|
359
378
|
this._dom = {
|
|
360
379
|
button: createElement('button', Button.classes.container),
|
|
361
380
|
dropdownDisplay: null,
|
|
@@ -433,9 +452,7 @@ var Button = /** @class */ (function () {
|
|
|
433
452
|
this._dom.button.removeEventListener('click', this._s.buttonClick);
|
|
434
453
|
this._dom.button.removeEventListener('keypress', this._s.buttonClick);
|
|
435
454
|
}
|
|
436
|
-
|
|
437
|
-
this._s.dt.off('destroy.' + this._s.namespace);
|
|
438
|
-
}
|
|
455
|
+
this._s.host.destroyRemove(this);
|
|
439
456
|
};
|
|
440
457
|
/**
|
|
441
458
|
* Relevant for drop downs only. When a button in a dropdown is hidden, we might want to
|
|
@@ -457,13 +474,10 @@ var Button = /** @class */ (function () {
|
|
|
457
474
|
Button.prototype.element = function () {
|
|
458
475
|
return this._dom.button;
|
|
459
476
|
};
|
|
460
|
-
/**
|
|
461
|
-
* Set if the button should be enabled or not.
|
|
462
|
-
*
|
|
463
|
-
* @param enable Toggle the enable state
|
|
464
|
-
* @returns Button instance
|
|
465
|
-
*/
|
|
466
477
|
Button.prototype.enable = function (enable) {
|
|
478
|
+
if (enable === undefined) {
|
|
479
|
+
return this._s.enabled;
|
|
480
|
+
}
|
|
467
481
|
this._dom.button.classList.toggle('dtcc-button_disabled', !enable);
|
|
468
482
|
this._s.enabled = enable;
|
|
469
483
|
return this;
|
|
@@ -500,10 +514,7 @@ var Button = /** @class */ (function () {
|
|
|
500
514
|
this._s.namespace = 'dtcc-' + _namespace++;
|
|
501
515
|
this._dom.button.addEventListener('click', buttonClick);
|
|
502
516
|
this._dom.button.addEventListener('keypress', buttonClick);
|
|
503
|
-
|
|
504
|
-
this._s.dt.on('destroy.' + this._s.namespace, function () {
|
|
505
|
-
_this.destroy();
|
|
506
|
-
});
|
|
517
|
+
this._s.host.destroyAdd(this);
|
|
507
518
|
return this;
|
|
508
519
|
};
|
|
509
520
|
/**
|
|
@@ -558,19 +569,22 @@ var CheckList = /** @class */ (function () {
|
|
|
558
569
|
/**
|
|
559
570
|
* Container for a list of buttons
|
|
560
571
|
*/
|
|
561
|
-
function CheckList(dt, opts) {
|
|
572
|
+
function CheckList(dt, host, opts) {
|
|
562
573
|
var _this = this;
|
|
563
574
|
this._s = {
|
|
564
575
|
buttons: [],
|
|
565
576
|
dt: null,
|
|
566
577
|
handler: function () { },
|
|
578
|
+
host: null,
|
|
567
579
|
search: ''
|
|
568
580
|
};
|
|
569
581
|
this._s.dt = dt;
|
|
582
|
+
this._s.host = host;
|
|
570
583
|
this._dom = {
|
|
571
584
|
buttons: createElement('div', 'dtcc-list-buttons'),
|
|
572
585
|
container: createElement('div', CheckList.classes.container),
|
|
573
586
|
controls: createElement('div', 'dtcc-list-controls'),
|
|
587
|
+
empty: createElement('div', 'dtcc-list-empty', dt.i18n('columnControl.list.empty', 'No options')),
|
|
574
588
|
title: createElement('div', 'dtcc-list-title'),
|
|
575
589
|
selectAll: createElement('button', 'dtcc-list-selectAll', dt.i18n('columnControl.list.all', 'Select all')),
|
|
576
590
|
selectAllCount: createElement('span'),
|
|
@@ -582,6 +596,7 @@ var CheckList = /** @class */ (function () {
|
|
|
582
596
|
dom.search.setAttribute('type', 'text');
|
|
583
597
|
dom.container.append(dom.title);
|
|
584
598
|
dom.container.append(dom.controls);
|
|
599
|
+
dom.container.append(dom.empty);
|
|
585
600
|
dom.container.append(dom.buttons);
|
|
586
601
|
if (opts.select) {
|
|
587
602
|
dom.controls.append(dom.selectAll);
|
|
@@ -632,7 +647,7 @@ var CheckList = /** @class */ (function () {
|
|
|
632
647
|
}
|
|
633
648
|
var _loop_1 = function (i) {
|
|
634
649
|
var option = options[i];
|
|
635
|
-
var btn = new Button(this_1._s.dt)
|
|
650
|
+
var btn = new Button(this_1._s.dt, this_1._s.host)
|
|
636
651
|
.active(option.active || false)
|
|
637
652
|
.handler(function (e) {
|
|
638
653
|
_this._s.handler(e, btn, _this._s.buttons, true);
|
|
@@ -641,7 +656,7 @@ var CheckList = /** @class */ (function () {
|
|
|
641
656
|
.icon(option.icon || '')
|
|
642
657
|
.text(option.label !== ''
|
|
643
658
|
? option.label
|
|
644
|
-
: this_1._s.dt.i18n('columnControl.list.
|
|
659
|
+
: this_1._s.dt.i18n('columnControl.list.empty', 'Empty'))
|
|
645
660
|
.value(option.value);
|
|
646
661
|
if (option.label === '') {
|
|
647
662
|
btn.className('empty');
|
|
@@ -712,11 +727,11 @@ var CheckList = /** @class */ (function () {
|
|
|
712
727
|
* @param dt DataTable instance
|
|
713
728
|
* @param idx Column index
|
|
714
729
|
*/
|
|
715
|
-
CheckList.prototype.searchListener = function (dt
|
|
730
|
+
CheckList.prototype.searchListener = function (dt) {
|
|
716
731
|
var _this = this;
|
|
717
|
-
// Column control search clearing (column().
|
|
732
|
+
// Column control search clearing (column().columnControl.searchClear() method)
|
|
718
733
|
dt.on('cc-search-clear', function (e, colIdx) {
|
|
719
|
-
if (colIdx ===
|
|
734
|
+
if (colIdx === _this._s.host.idx()) {
|
|
720
735
|
_this.selectNone();
|
|
721
736
|
_this._s.handler(e, null, _this._s.buttons, false);
|
|
722
737
|
_this._s.search = '';
|
|
@@ -804,6 +819,8 @@ var CheckList = /** @class */ (function () {
|
|
|
804
819
|
el.appendChild(btn.element());
|
|
805
820
|
}
|
|
806
821
|
}
|
|
822
|
+
this._dom.empty.style.display = buttons.length === 0 ? 'block' : 'none';
|
|
823
|
+
el.style.display = buttons.length > 0 ? 'block' : 'none';
|
|
807
824
|
};
|
|
808
825
|
CheckList.classes = {
|
|
809
826
|
container: 'dtcc-list',
|
|
@@ -822,7 +839,7 @@ var colVis = {
|
|
|
822
839
|
},
|
|
823
840
|
init: function (config) {
|
|
824
841
|
var dt = this.dt();
|
|
825
|
-
var checkList = new CheckList(dt, {
|
|
842
|
+
var checkList = new CheckList(dt, this, {
|
|
826
843
|
search: config.search,
|
|
827
844
|
select: config.select
|
|
828
845
|
})
|
|
@@ -905,7 +922,7 @@ var reorder = {
|
|
|
905
922
|
init: function (config) {
|
|
906
923
|
var _this = this;
|
|
907
924
|
var dt = this.dt();
|
|
908
|
-
var btn = new Button(dt)
|
|
925
|
+
var btn = new Button(dt, this)
|
|
909
926
|
.text(dt.i18n('columnControl.reorder', config.text))
|
|
910
927
|
.icon(config.icon)
|
|
911
928
|
.className(config.className)
|
|
@@ -938,7 +955,7 @@ var reorderLeft = {
|
|
|
938
955
|
init: function (config) {
|
|
939
956
|
var _this = this;
|
|
940
957
|
var dt = this.dt();
|
|
941
|
-
var btn = new Button(dt)
|
|
958
|
+
var btn = new Button(dt, this)
|
|
942
959
|
.text(dt.i18n('columnControl.reorderLeft', config.text))
|
|
943
960
|
.icon(config.icon)
|
|
944
961
|
.className(config.className)
|
|
@@ -968,7 +985,7 @@ var reorderRight = {
|
|
|
968
985
|
init: function (config) {
|
|
969
986
|
var _this = this;
|
|
970
987
|
var dt = this.dt();
|
|
971
|
-
var btn = new Button(dt)
|
|
988
|
+
var btn = new Button(dt, this)
|
|
972
989
|
.text(dt.i18n('columnControl.reorderRight', config.text))
|
|
973
990
|
.icon(config.icon)
|
|
974
991
|
.className(config.className)
|
|
@@ -1000,7 +1017,7 @@ var order = {
|
|
|
1000
1017
|
init: function (config) {
|
|
1001
1018
|
var _this = this;
|
|
1002
1019
|
var dt = this.dt();
|
|
1003
|
-
var btn = new Button(dt)
|
|
1020
|
+
var btn = new Button(dt, this)
|
|
1004
1021
|
.text(dt.i18n('columnControl.order', config.text))
|
|
1005
1022
|
.icon('orderAsc')
|
|
1006
1023
|
.className(config.className);
|
|
@@ -1032,7 +1049,7 @@ var orderAddAsc = {
|
|
|
1032
1049
|
init: function (config) {
|
|
1033
1050
|
var _this = this;
|
|
1034
1051
|
var dt = this.dt();
|
|
1035
|
-
var btn = new Button(dt)
|
|
1052
|
+
var btn = new Button(dt, this)
|
|
1036
1053
|
.text(dt.i18n('columnControl.orderAddAsc', config.text))
|
|
1037
1054
|
.icon(config.icon)
|
|
1038
1055
|
.className(config.className)
|
|
@@ -1058,7 +1075,7 @@ var orderAddDesc = {
|
|
|
1058
1075
|
init: function (config) {
|
|
1059
1076
|
var _this = this;
|
|
1060
1077
|
var dt = this.dt();
|
|
1061
|
-
var btn = new Button(dt)
|
|
1078
|
+
var btn = new Button(dt, this)
|
|
1062
1079
|
.text(dt.i18n('columnControl.orderAddDesc', config.text))
|
|
1063
1080
|
.icon(config.icon)
|
|
1064
1081
|
.className(config.className)
|
|
@@ -1084,7 +1101,7 @@ var orderAsc = {
|
|
|
1084
1101
|
init: function (config) {
|
|
1085
1102
|
var _this = this;
|
|
1086
1103
|
var dt = this.dt();
|
|
1087
|
-
var btn = new Button(dt)
|
|
1104
|
+
var btn = new Button(dt, this)
|
|
1088
1105
|
.text(dt.i18n('columnControl.orderAsc', config.text))
|
|
1089
1106
|
.icon(config.icon)
|
|
1090
1107
|
.className(config.className)
|
|
@@ -1114,7 +1131,7 @@ var orderClear = {
|
|
|
1114
1131
|
},
|
|
1115
1132
|
init: function (config) {
|
|
1116
1133
|
var dt = this.dt();
|
|
1117
|
-
var btn = new Button(dt)
|
|
1134
|
+
var btn = new Button(dt, this)
|
|
1118
1135
|
.text(dt.i18n('columnControl.orderClear', config.text))
|
|
1119
1136
|
.icon(config.icon)
|
|
1120
1137
|
.className(config.className)
|
|
@@ -1140,7 +1157,7 @@ var orderDesc = {
|
|
|
1140
1157
|
init: function (config) {
|
|
1141
1158
|
var _this = this;
|
|
1142
1159
|
var dt = this.dt();
|
|
1143
|
-
var btn = new Button(dt)
|
|
1160
|
+
var btn = new Button(dt, this)
|
|
1144
1161
|
.text(dt.i18n('columnControl.orderDesc', config.text))
|
|
1145
1162
|
.icon(config.icon)
|
|
1146
1163
|
.className(config.className)
|
|
@@ -1171,7 +1188,7 @@ var orderRemove = {
|
|
|
1171
1188
|
init: function (config) {
|
|
1172
1189
|
var _this = this;
|
|
1173
1190
|
var dt = this.dt();
|
|
1174
|
-
var btn = new Button(dt)
|
|
1191
|
+
var btn = new Button(dt, this)
|
|
1175
1192
|
.text(dt.i18n('columnControl.orderRemove', config.text))
|
|
1176
1193
|
.icon(config.icon)
|
|
1177
1194
|
.className(config.className)
|
|
@@ -1205,6 +1222,190 @@ var orderStatus = {
|
|
|
1205
1222
|
}
|
|
1206
1223
|
};
|
|
1207
1224
|
|
|
1225
|
+
/**
|
|
1226
|
+
* Add an item to the grouping structure
|
|
1227
|
+
*
|
|
1228
|
+
* @param dt DataTable API instance
|
|
1229
|
+
* @param dataSrc Grouping data point to add
|
|
1230
|
+
* @returns Grouping array
|
|
1231
|
+
*/
|
|
1232
|
+
function rowGroupAdd$1(dt, dataSrc) {
|
|
1233
|
+
var applied = rowGroupApplied(dt);
|
|
1234
|
+
var idx = applied.indexOf(dataSrc);
|
|
1235
|
+
if (idx === -1) {
|
|
1236
|
+
applied.push(dataSrc);
|
|
1237
|
+
dt.rowGroup().dataSrc(applied);
|
|
1238
|
+
}
|
|
1239
|
+
return applied;
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Always want an array return
|
|
1243
|
+
*
|
|
1244
|
+
* @param dt DataTable API instance
|
|
1245
|
+
* @returns
|
|
1246
|
+
*/
|
|
1247
|
+
function rowGroupApplied(dt) {
|
|
1248
|
+
var applied = dt.rowGroup().dataSrc();
|
|
1249
|
+
return Array.isArray(applied)
|
|
1250
|
+
? applied
|
|
1251
|
+
: [applied];
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Remove all grouping
|
|
1255
|
+
*
|
|
1256
|
+
* @param dt DataTable API instance
|
|
1257
|
+
*/
|
|
1258
|
+
function rowGroupClear$1(dt) {
|
|
1259
|
+
dt.rowGroup().dataSrc([]);
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Remove an item from the grouping structure
|
|
1263
|
+
*
|
|
1264
|
+
* @param dt DataTable API instance
|
|
1265
|
+
* @param dataSrc Grouping data point to remove
|
|
1266
|
+
* @returns Grouping array
|
|
1267
|
+
*/
|
|
1268
|
+
function rowGroupRemove$1(dt, dataSrc) {
|
|
1269
|
+
var applied = rowGroupApplied(dt);
|
|
1270
|
+
var idx = applied.indexOf(dataSrc);
|
|
1271
|
+
if (idx !== -1) {
|
|
1272
|
+
applied.splice(idx, 1);
|
|
1273
|
+
dt.rowGroup().dataSrc(applied);
|
|
1274
|
+
}
|
|
1275
|
+
return applied;
|
|
1276
|
+
}
|
|
1277
|
+
var rowGroup = {
|
|
1278
|
+
defaults: {
|
|
1279
|
+
className: 'rowGroup',
|
|
1280
|
+
icon: 'groupTop',
|
|
1281
|
+
order: true,
|
|
1282
|
+
text: 'Group rows'
|
|
1283
|
+
},
|
|
1284
|
+
init: function (config) {
|
|
1285
|
+
var _this = this;
|
|
1286
|
+
var dt = this.dt();
|
|
1287
|
+
var btn = new Button(dt, this)
|
|
1288
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1289
|
+
.icon(config.icon)
|
|
1290
|
+
.className(config.className)
|
|
1291
|
+
.handler(function () {
|
|
1292
|
+
var dataSrc = dt.column(_this.idx()).dataSrc();
|
|
1293
|
+
if (btn.active()) {
|
|
1294
|
+
// Grouping is active - remove
|
|
1295
|
+
rowGroupRemove$1(dt, dataSrc);
|
|
1296
|
+
}
|
|
1297
|
+
else {
|
|
1298
|
+
// No grouping by this column yet, set it
|
|
1299
|
+
rowGroupClear$1(dt);
|
|
1300
|
+
rowGroupAdd$1(dt, dataSrc);
|
|
1301
|
+
if (config.order !== false) {
|
|
1302
|
+
dt.order([_this.idx(), 'asc']);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
dt.draw();
|
|
1306
|
+
});
|
|
1307
|
+
// Show as active when grouping is applied
|
|
1308
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1309
|
+
var applied = rowGroupApplied(dt);
|
|
1310
|
+
var ours = dt.column(_this.idx()).dataSrc();
|
|
1311
|
+
btn.active(applied.includes(ours));
|
|
1312
|
+
});
|
|
1313
|
+
return btn.element();
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
|
|
1317
|
+
var rowGroupAdd = {
|
|
1318
|
+
defaults: {
|
|
1319
|
+
className: 'rowGroupAdd',
|
|
1320
|
+
icon: 'groupAdd',
|
|
1321
|
+
order: true,
|
|
1322
|
+
text: 'Add to grouping'
|
|
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.enable()) {
|
|
1334
|
+
// No grouping by this column yet, add it
|
|
1335
|
+
rowGroupAdd$1(dt, dataSrc);
|
|
1336
|
+
}
|
|
1337
|
+
dt.draw();
|
|
1338
|
+
});
|
|
1339
|
+
// Show as active when grouping is applied
|
|
1340
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1341
|
+
var applied = rowGroupApplied(dt);
|
|
1342
|
+
var ours = dt.column(_this.idx()).dataSrc();
|
|
1343
|
+
btn.enable(!applied.includes(ours));
|
|
1344
|
+
});
|
|
1345
|
+
return btn.element();
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
var rowGroupClear = {
|
|
1350
|
+
defaults: {
|
|
1351
|
+
className: 'rowGroupClear',
|
|
1352
|
+
icon: 'groupClear',
|
|
1353
|
+
text: 'Clear all grouping'
|
|
1354
|
+
},
|
|
1355
|
+
init: function (config) {
|
|
1356
|
+
var dt = this.dt();
|
|
1357
|
+
var btn = new Button(dt, this)
|
|
1358
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1359
|
+
.icon(config.icon)
|
|
1360
|
+
.className(config.className)
|
|
1361
|
+
.handler(function () {
|
|
1362
|
+
rowGroupClear$1(dt);
|
|
1363
|
+
dt.draw();
|
|
1364
|
+
});
|
|
1365
|
+
// Show as active when any grouping is applied
|
|
1366
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1367
|
+
btn.enable(rowGroupApplied(dt).length > 0);
|
|
1368
|
+
});
|
|
1369
|
+
// Default status
|
|
1370
|
+
btn.enable(rowGroupApplied(dt).length > 0);
|
|
1371
|
+
return btn.element();
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
|
|
1375
|
+
var rowGroupRemove = {
|
|
1376
|
+
defaults: {
|
|
1377
|
+
className: 'rowGroupRemove',
|
|
1378
|
+
icon: 'groupRemove',
|
|
1379
|
+
order: true,
|
|
1380
|
+
text: 'Remove from grouping'
|
|
1381
|
+
},
|
|
1382
|
+
init: function (config) {
|
|
1383
|
+
var _this = this;
|
|
1384
|
+
var dt = this.dt();
|
|
1385
|
+
var btn = new Button(dt, this)
|
|
1386
|
+
.text(dt.i18n('columnControl.rowGroup', config.text))
|
|
1387
|
+
.icon(config.icon)
|
|
1388
|
+
.className(config.className)
|
|
1389
|
+
.handler(function () {
|
|
1390
|
+
var dataSrc = dt.column(_this.idx()).dataSrc();
|
|
1391
|
+
if (btn.enable()) {
|
|
1392
|
+
// Grouping is active - remove
|
|
1393
|
+
rowGroupRemove$1(dt, dataSrc);
|
|
1394
|
+
dt.draw();
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
// Show as active when grouping is applied
|
|
1398
|
+
dt.on('rowgroup-datasrc', function () {
|
|
1399
|
+
var applied = rowGroupApplied(dt);
|
|
1400
|
+
var ours = dt.column(_this.idx()).dataSrc();
|
|
1401
|
+
btn.enable(applied.includes(ours));
|
|
1402
|
+
});
|
|
1403
|
+
// Default disabled
|
|
1404
|
+
btn.enable(false);
|
|
1405
|
+
return btn.element();
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
|
|
1208
1409
|
var SearchInput = /** @class */ (function () {
|
|
1209
1410
|
/**
|
|
1210
1411
|
* Create a container element, for consistent DOM structure and styling
|
|
@@ -1212,6 +1413,8 @@ var SearchInput = /** @class */ (function () {
|
|
|
1212
1413
|
function SearchInput(dt, idx) {
|
|
1213
1414
|
var _this = this;
|
|
1214
1415
|
this._type = 'text';
|
|
1416
|
+
this._sspTransform = null;
|
|
1417
|
+
this._sspData = {};
|
|
1215
1418
|
this._dt = dt;
|
|
1216
1419
|
this._idx = idx;
|
|
1217
1420
|
this._dom = {
|
|
@@ -1250,28 +1453,28 @@ var SearchInput = /** @class */ (function () {
|
|
|
1250
1453
|
});
|
|
1251
1454
|
// State handling - all components that use this class have the same state saving structure
|
|
1252
1455
|
// so shared handling can be performed here.
|
|
1253
|
-
dt.on('stateSaveParams', function (e, s, data) {
|
|
1456
|
+
dt.on('stateSaveParams.DT', function (e, s, data) {
|
|
1254
1457
|
if (!data.columnControl) {
|
|
1255
1458
|
data.columnControl = {};
|
|
1256
1459
|
}
|
|
1257
|
-
if (!data.columnControl[
|
|
1258
|
-
data.columnControl[
|
|
1460
|
+
if (!data.columnControl[_this._idx]) {
|
|
1461
|
+
data.columnControl[_this._idx] = {};
|
|
1259
1462
|
}
|
|
1260
|
-
data.columnControl[
|
|
1463
|
+
data.columnControl[_this._idx].searchInput = {
|
|
1261
1464
|
logic: dom.select.value,
|
|
1262
1465
|
type: _this._type,
|
|
1263
1466
|
value: dom.input.value
|
|
1264
1467
|
};
|
|
1265
1468
|
});
|
|
1266
|
-
dt.on('stateLoaded', function (e, s, state) {
|
|
1469
|
+
dt.on('stateLoaded.DT', function (e, s, state) {
|
|
1267
1470
|
_this._stateLoad(state);
|
|
1268
1471
|
});
|
|
1269
1472
|
// Same as for ColumnControl - reassign a column index if needed.
|
|
1270
|
-
dt.on('columns-reordered', function (e, details) {
|
|
1473
|
+
dt.on('columns-reordered.DT', function (e, details) {
|
|
1271
1474
|
_this._idx = dt.colReorder.transpose(originalIdx, 'fromOriginal');
|
|
1272
1475
|
});
|
|
1273
|
-
// Column control search clearing (column().
|
|
1274
|
-
dt.on('cc-search-clear', function (e, colIdx) {
|
|
1476
|
+
// Column control search clearing (column().columnControl.searchClear() method)
|
|
1477
|
+
dt.on('cc-search-clear.DT', function (e, colIdx) {
|
|
1275
1478
|
if (colIdx === _this._idx) {
|
|
1276
1479
|
// Don't want an automatic redraw on this event
|
|
1277
1480
|
_this._loadingState = true;
|
|
@@ -1279,6 +1482,23 @@ var SearchInput = /** @class */ (function () {
|
|
|
1279
1482
|
_this._loadingState = false;
|
|
1280
1483
|
}
|
|
1281
1484
|
});
|
|
1485
|
+
// Data for server-side processing
|
|
1486
|
+
if (dt.page.info().serverSide) {
|
|
1487
|
+
dt.on('preXhr.DT', function (e, s, d) {
|
|
1488
|
+
if (!d.columns[_this._idx].columnControl) {
|
|
1489
|
+
d.columns[_this._idx].columnControl = {};
|
|
1490
|
+
}
|
|
1491
|
+
var val = _this._dom.input.value;
|
|
1492
|
+
if (_this._sspTransform) {
|
|
1493
|
+
val = _this._sspTransform(val);
|
|
1494
|
+
}
|
|
1495
|
+
d.columns[_this._idx].columnControl.search = Object.assign({
|
|
1496
|
+
value: val,
|
|
1497
|
+
logic: _this._dom.select.value,
|
|
1498
|
+
type: _this._type
|
|
1499
|
+
}, _this._sspData);
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1282
1502
|
}
|
|
1283
1503
|
/**
|
|
1284
1504
|
* Add a class to the container
|
|
@@ -1401,6 +1621,26 @@ var SearchInput = /** @class */ (function () {
|
|
|
1401
1621
|
this.runSearch();
|
|
1402
1622
|
return this;
|
|
1403
1623
|
};
|
|
1624
|
+
/**
|
|
1625
|
+
* Set a function to transform the input value before SSP data submission
|
|
1626
|
+
*
|
|
1627
|
+
* @param fn Transform function
|
|
1628
|
+
* @returns Self for chaining
|
|
1629
|
+
*/
|
|
1630
|
+
SearchInput.prototype.sspTransform = function (fn) {
|
|
1631
|
+
this._sspTransform = fn;
|
|
1632
|
+
return this;
|
|
1633
|
+
};
|
|
1634
|
+
/**
|
|
1635
|
+
* Set extra information to be send to the server for server-side processing
|
|
1636
|
+
*
|
|
1637
|
+
* @param data Data object
|
|
1638
|
+
* @returns Self for chaining
|
|
1639
|
+
*/
|
|
1640
|
+
SearchInput.prototype.sspData = function (data) {
|
|
1641
|
+
this._sspData = data;
|
|
1642
|
+
return this;
|
|
1643
|
+
};
|
|
1404
1644
|
/**
|
|
1405
1645
|
* Set the text that will be shown as the title for the control
|
|
1406
1646
|
*
|
|
@@ -1463,6 +1703,8 @@ var SearchInput = /** @class */ (function () {
|
|
|
1463
1703
|
var searchDateTime = {
|
|
1464
1704
|
defaults: {
|
|
1465
1705
|
clear: true,
|
|
1706
|
+
format: '',
|
|
1707
|
+
mask: '',
|
|
1466
1708
|
placeholder: '',
|
|
1467
1709
|
title: '',
|
|
1468
1710
|
titleAttr: ''
|
|
@@ -1474,11 +1716,14 @@ var searchDateTime = {
|
|
|
1474
1716
|
var luxon = DataTable.use('luxon');
|
|
1475
1717
|
var dt = this.dt();
|
|
1476
1718
|
var i18nBase = 'columnControl.search.datetime.';
|
|
1477
|
-
var
|
|
1719
|
+
var pickerFormat = '';
|
|
1720
|
+
var dataSrcFormat = '';
|
|
1478
1721
|
var dateTime;
|
|
1479
1722
|
var searchInput = new SearchInput(dt, this.idx())
|
|
1480
1723
|
.type('date')
|
|
1481
1724
|
.addClass('dtcc-searchDateTime')
|
|
1725
|
+
.sspTransform(function (val) { return toISO(val, pickerFormat, moment, luxon); })
|
|
1726
|
+
.sspData({ mask: config.mask })
|
|
1482
1727
|
.clearable(config.clear)
|
|
1483
1728
|
.placeholder(config.placeholder)
|
|
1484
1729
|
.title(config.title)
|
|
@@ -1492,10 +1737,18 @@ var searchDateTime = {
|
|
|
1492
1737
|
{ label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
|
|
1493
1738
|
])
|
|
1494
1739
|
.search(function (searchType, searchTerm, loadingState) {
|
|
1740
|
+
// When SSP, don't apply a filter here, SearchInput will add to the submit data
|
|
1741
|
+
if (dt.page.info().serverSide) {
|
|
1742
|
+
if (!loadingState) {
|
|
1743
|
+
dt.draw();
|
|
1744
|
+
}
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1747
|
+
var mask = config.mask;
|
|
1495
1748
|
var column = dt.column(_this.idx());
|
|
1496
1749
|
var search = searchTerm === ''
|
|
1497
1750
|
? ''
|
|
1498
|
-
: dateToNum(dateTime && fromPicker ? dateTime.val() : searchTerm.trim(),
|
|
1751
|
+
: dateToNum(dateTime && fromPicker ? dateTime.val() : searchTerm.trim(), pickerFormat, moment, luxon, mask);
|
|
1499
1752
|
if (searchType === 'empty') {
|
|
1500
1753
|
column.search.fixed('dtcc', function (haystack) { return !haystack; });
|
|
1501
1754
|
}
|
|
@@ -1514,16 +1767,24 @@ var searchDateTime = {
|
|
|
1514
1767
|
// Use a function for matching - weak typing
|
|
1515
1768
|
// Note that the haystack in the search function is the rendered date - it
|
|
1516
1769
|
// might need to be converted back to a date
|
|
1517
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1770
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1771
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) == search;
|
|
1772
|
+
});
|
|
1518
1773
|
}
|
|
1519
1774
|
else if (searchType === 'notEqual') {
|
|
1520
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1775
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1776
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) != search;
|
|
1777
|
+
});
|
|
1521
1778
|
}
|
|
1522
1779
|
else if (searchType === 'greater') {
|
|
1523
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1780
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1781
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) > search;
|
|
1782
|
+
});
|
|
1524
1783
|
}
|
|
1525
1784
|
else if (searchType === 'less') {
|
|
1526
|
-
column.search.fixed('dtcc', function (haystack) {
|
|
1785
|
+
column.search.fixed('dtcc', function (haystack) {
|
|
1786
|
+
return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) < search;
|
|
1787
|
+
});
|
|
1527
1788
|
}
|
|
1528
1789
|
// If in a dropdown, set the parent levels as active
|
|
1529
1790
|
if (config._parents) {
|
|
@@ -1538,10 +1799,13 @@ var searchDateTime = {
|
|
|
1538
1799
|
// Once data has been loaded we can run DateTime with the specified format
|
|
1539
1800
|
dt.ready(function () {
|
|
1540
1801
|
var DateTime = DataTable.use('datetime');
|
|
1541
|
-
|
|
1802
|
+
dataSrcFormat = getFormat(dt, _this.idx());
|
|
1803
|
+
pickerFormat = config.format
|
|
1804
|
+
? config.format
|
|
1805
|
+
: dataSrcFormat;
|
|
1542
1806
|
if (DateTime) {
|
|
1543
1807
|
dateTime = new DateTime(searchInput.input(), {
|
|
1544
|
-
format:
|
|
1808
|
+
format: pickerFormat,
|
|
1545
1809
|
i18n: dt.settings()[0].oLanguage.datetime, // could be undefined
|
|
1546
1810
|
onChange: function () {
|
|
1547
1811
|
fromPicker = true;
|
|
@@ -1568,18 +1832,36 @@ function getFormat(dt, column) {
|
|
|
1568
1832
|
return 'YYYY-MM-DD';
|
|
1569
1833
|
}
|
|
1570
1834
|
else if (type === 'datetime') {
|
|
1571
|
-
// If no format was specified in the DT type,
|
|
1572
|
-
//
|
|
1573
|
-
|
|
1574
|
-
var
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
.
|
|
1835
|
+
// If no format was specified in the DT type, a Javascript native toLocaleDateString
|
|
1836
|
+
// was used. Need to work out what that format is in Moment or Luxon. We need to pass
|
|
1837
|
+
// a known value though the renderer and work out the format
|
|
1838
|
+
var renderer = dt.settings()[0].aoColumns[column].mRender;
|
|
1839
|
+
var resultPm = renderer('1999-08-07T23:05:04Z', 'display');
|
|
1840
|
+
var resultAm = renderer('1999-08-07T03:05:04Z', 'display');
|
|
1841
|
+
var leadingZero = resultAm.includes('03');
|
|
1842
|
+
// What formatter are we using?
|
|
1843
|
+
if (DataTable.use('moment')) {
|
|
1844
|
+
return resultPm
|
|
1845
|
+
.replace('23', leadingZero ? 'HH' : 'H')
|
|
1846
|
+
.replace('11', leadingZero ? 'hh' : 'h')
|
|
1847
|
+
.replace('05', 'mm')
|
|
1848
|
+
.replace('04', 'ss')
|
|
1849
|
+
.replace('PM', 'A')
|
|
1850
|
+
.replace('pm', 'a')
|
|
1851
|
+
.replace('07', 'DD')
|
|
1852
|
+
.replace('7', 'D')
|
|
1853
|
+
.replace('08', 'MM')
|
|
1854
|
+
.replace('8', 'M')
|
|
1855
|
+
.replace('1999', 'YYYY')
|
|
1856
|
+
.replace('99', 'YY');
|
|
1857
|
+
}
|
|
1858
|
+
else if (DataTable.use('luxon')) {
|
|
1859
|
+
return resultPm
|
|
1860
|
+
.replace('23', leadingZero ? 'HH' : 'H')
|
|
1861
|
+
.replace('11', leadingZero ? 'hh' : 'h')
|
|
1862
|
+
.replace('05', 'mm')
|
|
1863
|
+
.replace('04', 'ss')
|
|
1864
|
+
.replace('PM', 'a')
|
|
1583
1865
|
.replace('07', 'dd')
|
|
1584
1866
|
.replace('7', 'd')
|
|
1585
1867
|
.replace('08', 'MM')
|
|
@@ -1587,6 +1869,13 @@ function getFormat(dt, column) {
|
|
|
1587
1869
|
.replace('1999', 'yyyy')
|
|
1588
1870
|
.replace('99', 'yy');
|
|
1589
1871
|
}
|
|
1872
|
+
else if (resultPm.includes('23') && resultPm.includes('1999')) {
|
|
1873
|
+
return 'YYYY-MM-DD hh:mm:ss';
|
|
1874
|
+
}
|
|
1875
|
+
else if (resultPm.includes('23')) {
|
|
1876
|
+
return 'hh:mm:ss';
|
|
1877
|
+
}
|
|
1878
|
+
// fall through to final return
|
|
1590
1879
|
}
|
|
1591
1880
|
else if (type.includes('datetime-')) {
|
|
1592
1881
|
// Column was specified with a particular display format - we can extract that format from
|
|
@@ -1610,19 +1899,75 @@ function getFormat(dt, column) {
|
|
|
1610
1899
|
* @param luxon Luxon object, if it is available
|
|
1611
1900
|
* @returns Time stamp - milliseconds
|
|
1612
1901
|
*/
|
|
1613
|
-
function dateToNum(input, srcFormat, moment, luxon) {
|
|
1902
|
+
function dateToNum(input, srcFormat, moment, luxon, mask) {
|
|
1903
|
+
var d;
|
|
1614
1904
|
if (input === '') {
|
|
1615
1905
|
return '';
|
|
1616
1906
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1907
|
+
if (input instanceof Date) {
|
|
1908
|
+
d = input;
|
|
1619
1909
|
}
|
|
1620
1910
|
else if (srcFormat !== 'YYYY-MM-DD' && (moment || luxon)) {
|
|
1621
|
-
|
|
1911
|
+
d = new Date(moment
|
|
1622
1912
|
? moment(input, srcFormat).unix() * 1000
|
|
1623
|
-
: luxon.DateTime.fromFormat(input, srcFormat).toMillis();
|
|
1913
|
+
: luxon.DateTime.fromFormat(input, srcFormat).toMillis());
|
|
1914
|
+
}
|
|
1915
|
+
else {
|
|
1916
|
+
// new Date() with `/` separators will treat the input as local time, but with `-` it will
|
|
1917
|
+
// treat it as UTC. We want UTC so do a replacement
|
|
1918
|
+
d = new Date(input.replace(/\//g, '-'));
|
|
1624
1919
|
}
|
|
1625
|
-
|
|
1920
|
+
if (mask) {
|
|
1921
|
+
if (!mask.includes('YYYY')) {
|
|
1922
|
+
d.setFullYear(1970);
|
|
1923
|
+
}
|
|
1924
|
+
if (!mask.includes('MM')) {
|
|
1925
|
+
d.setUTCMonth(0);
|
|
1926
|
+
}
|
|
1927
|
+
if (!mask.includes('DD')) {
|
|
1928
|
+
d.setUTCDate(1);
|
|
1929
|
+
}
|
|
1930
|
+
if (!mask.includes('hh')) {
|
|
1931
|
+
d.setUTCHours(0);
|
|
1932
|
+
}
|
|
1933
|
+
if (!mask.includes('mm')) {
|
|
1934
|
+
d.setUTCMinutes(0);
|
|
1935
|
+
}
|
|
1936
|
+
if (!mask.includes('ss')) {
|
|
1937
|
+
// This will match milliseconds as well, but that's fine, you won't match mS but not S
|
|
1938
|
+
d.setUTCSeconds(0);
|
|
1939
|
+
}
|
|
1940
|
+
if (!mask.includes('sss')) {
|
|
1941
|
+
d.setUTCMilliseconds(0);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
return d.getTime();
|
|
1945
|
+
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Convert an input string to an ISO formatted date
|
|
1948
|
+
*
|
|
1949
|
+
* @param input Input value
|
|
1950
|
+
* @param srcFormat String format of the input
|
|
1951
|
+
* @param moment Moment instance, if it is available
|
|
1952
|
+
* @param luxon Luxon object, if it is available
|
|
1953
|
+
* @returns Value in ISO
|
|
1954
|
+
*/
|
|
1955
|
+
function toISO(input, srcFormat, moment, luxon) {
|
|
1956
|
+
if (input === '') {
|
|
1957
|
+
return '';
|
|
1958
|
+
}
|
|
1959
|
+
else if (srcFormat !== 'YYYY-MM-DD' && moment) {
|
|
1960
|
+
// TODO Does it have a time component?
|
|
1961
|
+
return moment.utc(input, srcFormat).toISOString();
|
|
1962
|
+
}
|
|
1963
|
+
else if (srcFormat !== 'YYYY-MM-DD' && luxon) {
|
|
1964
|
+
// TODO Does it have a time component?
|
|
1965
|
+
return luxon.DateTime.fromFormat(input, srcFormat).toISO();
|
|
1966
|
+
}
|
|
1967
|
+
// new Date() with `/` separators will treat the input as local time, but with `-` it will
|
|
1968
|
+
// treat it as UTC. We want UTC so do a replacement
|
|
1969
|
+
input = input.replace(/\//g, '-');
|
|
1970
|
+
return input;
|
|
1626
1971
|
}
|
|
1627
1972
|
|
|
1628
1973
|
/** Set the options to show in the list */
|
|
@@ -1688,17 +2033,19 @@ function reloadOptions(dt, config, idx, checkList, loadedValues) {
|
|
|
1688
2033
|
options = jsonOptions;
|
|
1689
2034
|
}
|
|
1690
2035
|
else if (json && config.ajaxOnly) {
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
config._parents
|
|
2036
|
+
if (config.hidable) {
|
|
2037
|
+
// Ajax only options - need to hide the search list
|
|
2038
|
+
checkList.element().style.display = 'none';
|
|
2039
|
+
// Check if the parent buttons should be hidden as well (they will be if there
|
|
2040
|
+
// is no visible content in them)
|
|
2041
|
+
if (config._parents) {
|
|
2042
|
+
config._parents.forEach(function (btn) { return btn.checkDisplay(); });
|
|
2043
|
+
}
|
|
1697
2044
|
}
|
|
1698
2045
|
// No point in doing any further processing here
|
|
1699
2046
|
return;
|
|
1700
2047
|
}
|
|
1701
|
-
else {
|
|
2048
|
+
else if (!dt.page.info().serverSide) {
|
|
1702
2049
|
// Either no ajax object (i.e. not an Ajax table), or no matching ajax options
|
|
1703
2050
|
// for this column - get the values for the column, taking into account
|
|
1704
2051
|
// orthogonal rendering
|
|
@@ -1706,11 +2053,14 @@ function reloadOptions(dt, config, idx, checkList, loadedValues) {
|
|
|
1706
2053
|
var rows = dt.rows({ order: idx }).indexes().toArray();
|
|
1707
2054
|
var settings = dt.settings()[0];
|
|
1708
2055
|
for (var i = 0; i < rows.length; i++) {
|
|
1709
|
-
var
|
|
2056
|
+
var raw = settings.fastData(rows[i], idx, 'filter');
|
|
2057
|
+
var filter = raw !== null && raw !== undefined
|
|
2058
|
+
? raw.toString()
|
|
2059
|
+
: '';
|
|
1710
2060
|
if (!found[filter]) {
|
|
1711
2061
|
found[filter] = true;
|
|
1712
2062
|
options.push({
|
|
1713
|
-
label: settings.fastData(rows[i], idx,
|
|
2063
|
+
label: settings.fastData(rows[i], idx, config.orthogonal),
|
|
1714
2064
|
value: filter
|
|
1715
2065
|
});
|
|
1716
2066
|
}
|
|
@@ -1727,7 +2077,9 @@ var searchList = {
|
|
|
1727
2077
|
defaults: {
|
|
1728
2078
|
ajaxOnly: true,
|
|
1729
2079
|
className: 'searchList',
|
|
2080
|
+
hidable: true,
|
|
1730
2081
|
options: null,
|
|
2082
|
+
orthogonal: 'display',
|
|
1731
2083
|
search: true,
|
|
1732
2084
|
select: true,
|
|
1733
2085
|
title: ''
|
|
@@ -1739,6 +2091,10 @@ var searchList = {
|
|
|
1739
2091
|
// The search can be applied from a stored start at start up before the options are
|
|
1740
2092
|
// available. It can also be applied by user input, so it is generalised into this function.
|
|
1741
2093
|
var applySearch = function (values) {
|
|
2094
|
+
// When SSP, don't do any client-side filtering
|
|
2095
|
+
if (dt.page.info().serverSide) {
|
|
2096
|
+
return;
|
|
2097
|
+
}
|
|
1742
2098
|
var col = dt.column(_this.idx());
|
|
1743
2099
|
if (!values) {
|
|
1744
2100
|
return;
|
|
@@ -1758,11 +2114,11 @@ var searchList = {
|
|
|
1758
2114
|
config._parents.forEach(function (btn) { return btn.activeList(_this.unique(), !!values.length); });
|
|
1759
2115
|
}
|
|
1760
2116
|
};
|
|
1761
|
-
var checkList = new CheckList(dt, {
|
|
2117
|
+
var checkList = new CheckList(dt, this, {
|
|
1762
2118
|
search: config.search,
|
|
1763
2119
|
select: config.select
|
|
1764
2120
|
})
|
|
1765
|
-
.searchListener(dt
|
|
2121
|
+
.searchListener(dt)
|
|
1766
2122
|
.title(dt
|
|
1767
2123
|
.i18n('columnControl.searchList', config.title)
|
|
1768
2124
|
.replace('[title]', dt.column(this.idx()).title()))
|
|
@@ -1782,14 +2138,24 @@ var searchList = {
|
|
|
1782
2138
|
dt.ready(function () {
|
|
1783
2139
|
reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
|
|
1784
2140
|
});
|
|
2141
|
+
// Xhr event listener for updates of options
|
|
2142
|
+
dt.on('xhr', function (e, s, json) {
|
|
2143
|
+
// Need to wait for the draw to complete so the table has the latest data
|
|
2144
|
+
dt.one('draw', function () {
|
|
2145
|
+
reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
|
|
2146
|
+
});
|
|
2147
|
+
});
|
|
1785
2148
|
}
|
|
1786
|
-
//
|
|
1787
|
-
dt.
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
2149
|
+
// Data for server-side processing
|
|
2150
|
+
if (dt.page.info().serverSide) {
|
|
2151
|
+
dt.on('preXhr.DT', function (e, s, d) {
|
|
2152
|
+
if (!d.columns[_this.idx()].columnControl) {
|
|
2153
|
+
d.columns[_this.idx()].columnControl = {};
|
|
2154
|
+
}
|
|
2155
|
+
// We need the indexes in the HTTP parameter names (for .NET), so use an object.
|
|
2156
|
+
d.columns[_this.idx()].columnControl.list = Object.assign({}, checkList.values());
|
|
1791
2157
|
});
|
|
1792
|
-
}
|
|
2158
|
+
}
|
|
1793
2159
|
// Unlike the SearchInput based search contents, CheckList does not handle state saving
|
|
1794
2160
|
// (since the mechanism for column visibility is different), so state saving is handled
|
|
1795
2161
|
// here.
|
|
@@ -1797,6 +2163,7 @@ var searchList = {
|
|
|
1797
2163
|
var values = getState(_this.idx(), state);
|
|
1798
2164
|
if (values) {
|
|
1799
2165
|
checkList.values(values);
|
|
2166
|
+
applySearch(values);
|
|
1800
2167
|
}
|
|
1801
2168
|
});
|
|
1802
2169
|
dt.on('stateSaveParams', function (e, s, data) {
|
|
@@ -1814,6 +2181,14 @@ var searchList = {
|
|
|
1814
2181
|
? checkList.values()
|
|
1815
2182
|
: loadedValues;
|
|
1816
2183
|
});
|
|
2184
|
+
dt.settings()[0].aoColumns[this.idx()].columnControlSearchList = function (options) {
|
|
2185
|
+
if (options === 'refresh') {
|
|
2186
|
+
reloadOptions(dt, config, _this.idx(), checkList, null);
|
|
2187
|
+
}
|
|
2188
|
+
else {
|
|
2189
|
+
setOptions(checkList, options);
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
1817
2192
|
loadedValues = getState(this.idx(), dt.state.loaded());
|
|
1818
2193
|
applySearch(loadedValues);
|
|
1819
2194
|
return checkList.element();
|
|
@@ -1852,6 +2227,13 @@ var searchNumber = {
|
|
|
1852
2227
|
{ label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
|
|
1853
2228
|
])
|
|
1854
2229
|
.search(function (searchType, searchTerm, loadingState) {
|
|
2230
|
+
// When SSP, don't apply a filter here, SearchInput will add to the submit data
|
|
2231
|
+
if (dt.page.info().serverSide) {
|
|
2232
|
+
if (!loadingState) {
|
|
2233
|
+
dt.draw();
|
|
2234
|
+
}
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
1855
2237
|
var column = dt.column(_this.idx());
|
|
1856
2238
|
if (searchType === 'empty') {
|
|
1857
2239
|
column.search.fixed('dtcc', function (haystack) { return !haystack; });
|
|
@@ -1949,6 +2331,13 @@ var searchText = {
|
|
|
1949
2331
|
{ label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
|
|
1950
2332
|
])
|
|
1951
2333
|
.search(function (searchType, searchTerm, loadingState) {
|
|
2334
|
+
// When SSP, don't apply a filter here, SearchInput will add to the submit data
|
|
2335
|
+
if (dt.page.info().serverSide) {
|
|
2336
|
+
if (!loadingState) {
|
|
2337
|
+
dt.draw();
|
|
2338
|
+
}
|
|
2339
|
+
return;
|
|
2340
|
+
}
|
|
1952
2341
|
var column = dt.column(_this.idx());
|
|
1953
2342
|
searchTerm = searchTerm.toLowerCase();
|
|
1954
2343
|
if (searchType === 'empty') {
|
|
@@ -2055,7 +2444,7 @@ var search = {
|
|
|
2055
2444
|
}
|
|
2056
2445
|
};
|
|
2057
2446
|
|
|
2058
|
-
var searchClear = {
|
|
2447
|
+
var searchClear$1 = {
|
|
2059
2448
|
defaults: {
|
|
2060
2449
|
className: 'searchClear',
|
|
2061
2450
|
icon: 'searchClear',
|
|
@@ -2064,12 +2453,12 @@ var searchClear = {
|
|
|
2064
2453
|
init: function (config) {
|
|
2065
2454
|
var _this = this;
|
|
2066
2455
|
var dt = this.dt();
|
|
2067
|
-
var btn = new Button(dt)
|
|
2456
|
+
var btn = new Button(dt, this)
|
|
2068
2457
|
.text(dt.i18n('columnControl.searchClear', config.text))
|
|
2069
2458
|
.icon(config.icon)
|
|
2070
2459
|
.className(config.className)
|
|
2071
2460
|
.handler(function () {
|
|
2072
|
-
dt.column(_this.idx()).
|
|
2461
|
+
dt.column(_this.idx()).columnControl.searchClear().draw();
|
|
2073
2462
|
})
|
|
2074
2463
|
.enable(false);
|
|
2075
2464
|
dt.on('draw', function () {
|
|
@@ -2089,7 +2478,9 @@ var searchDropdown = {
|
|
|
2089
2478
|
className: 'searchDropdown',
|
|
2090
2479
|
clear: true,
|
|
2091
2480
|
columns: '',
|
|
2481
|
+
hidable: true,
|
|
2092
2482
|
options: null,
|
|
2483
|
+
orthogonal: 'display',
|
|
2093
2484
|
placeholder: '',
|
|
2094
2485
|
search: true,
|
|
2095
2486
|
select: true,
|
|
@@ -2146,6 +2537,10 @@ var contentTypes = {
|
|
|
2146
2537
|
reorder: reorder,
|
|
2147
2538
|
reorderLeft: reorderLeft,
|
|
2148
2539
|
reorderRight: reorderRight,
|
|
2540
|
+
rowGroup: rowGroup,
|
|
2541
|
+
rowGroupAdd: rowGroupAdd,
|
|
2542
|
+
rowGroupClear: rowGroupClear,
|
|
2543
|
+
rowGroupRemove: rowGroupRemove,
|
|
2149
2544
|
order: order,
|
|
2150
2545
|
orderAddAsc: orderAddAsc,
|
|
2151
2546
|
orderAddDesc: orderAddDesc,
|
|
@@ -2155,7 +2550,7 @@ var contentTypes = {
|
|
|
2155
2550
|
orderRemove: orderRemove,
|
|
2156
2551
|
orderStatus: orderStatus,
|
|
2157
2552
|
search: search,
|
|
2158
|
-
searchClear: searchClear,
|
|
2553
|
+
searchClear: searchClear$1,
|
|
2159
2554
|
searchDropdown: searchDropdown,
|
|
2160
2555
|
searchDateTime: searchDateTime,
|
|
2161
2556
|
searchList: searchList,
|
|
@@ -2185,7 +2580,8 @@ var ColumnControl = /** @class */ (function () {
|
|
|
2185
2580
|
this._c = {};
|
|
2186
2581
|
this._s = {
|
|
2187
2582
|
columnIdx: null,
|
|
2188
|
-
unique: null
|
|
2583
|
+
unique: null,
|
|
2584
|
+
toDestroy: []
|
|
2189
2585
|
};
|
|
2190
2586
|
this._dt = dt;
|
|
2191
2587
|
this._s.columnIdx = columnIdx;
|
|
@@ -2211,10 +2607,33 @@ var ColumnControl = /** @class */ (function () {
|
|
|
2211
2607
|
_this._dom.wrapper.appendChild(el);
|
|
2212
2608
|
});
|
|
2213
2609
|
dt.on('destroy', function () {
|
|
2610
|
+
_this._s.toDestroy.slice().forEach(function (el) {
|
|
2611
|
+
el.destroy();
|
|
2612
|
+
});
|
|
2214
2613
|
_this._dom.wrapper.remove();
|
|
2215
2614
|
});
|
|
2216
2615
|
}
|
|
2217
2616
|
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Add a component to the destroy list. This is so there is a single destroy event handler,
|
|
2619
|
+
* which is much better for performance.
|
|
2620
|
+
*
|
|
2621
|
+
* @param component Any instance with a `destroy` method
|
|
2622
|
+
*/
|
|
2623
|
+
ColumnControl.prototype.destroyAdd = function (component) {
|
|
2624
|
+
this._s.toDestroy.push(component);
|
|
2625
|
+
};
|
|
2626
|
+
/**
|
|
2627
|
+
* Remove an instance from the destroy list (it has been destroyed itself)
|
|
2628
|
+
*
|
|
2629
|
+
* @param component Any instance with a `destroy` method
|
|
2630
|
+
*/
|
|
2631
|
+
ColumnControl.prototype.destroyRemove = function (component) {
|
|
2632
|
+
var idx = this._s.toDestroy.indexOf(component);
|
|
2633
|
+
if (idx !== -1) {
|
|
2634
|
+
this._s.toDestroy.splice(idx, 1);
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2218
2637
|
/**
|
|
2219
2638
|
* Get the DataTables API instance that hosts this instance of ColumnControl
|
|
2220
2639
|
*
|
|
@@ -2325,7 +2744,7 @@ var ColumnControl = /** @class */ (function () {
|
|
|
2325
2744
|
/** SVG icons that can be used by the content plugins */
|
|
2326
2745
|
ColumnControl.icons = icons;
|
|
2327
2746
|
/** Version */
|
|
2328
|
-
ColumnControl.version = '1.0
|
|
2747
|
+
ColumnControl.version = '1.1.0';
|
|
2329
2748
|
return ColumnControl;
|
|
2330
2749
|
}());
|
|
2331
2750
|
|
|
@@ -2354,7 +2773,9 @@ $(document).on('i18n.dt', function (e, settings) {
|
|
|
2354
2773
|
settings.titleRow = 0;
|
|
2355
2774
|
}
|
|
2356
2775
|
identifyTargets(baseTargets, tableInit);
|
|
2357
|
-
|
|
2776
|
+
if (ColumnControl.defaults.content) {
|
|
2777
|
+
identifyTargets(baseTargets, defaultInit);
|
|
2778
|
+
}
|
|
2358
2779
|
api.columns().every(function (i) {
|
|
2359
2780
|
var columnInit = this.init().columnControl;
|
|
2360
2781
|
identifyTargets(baseTargets, columnInit);
|
|
@@ -2374,7 +2795,10 @@ $(document).on('preInit.dt', function (e, settings) {
|
|
|
2374
2795
|
var defaultInit = ColumnControl.defaults;
|
|
2375
2796
|
var baseTargets = [];
|
|
2376
2797
|
identifyTargets(baseTargets, tableInit);
|
|
2377
|
-
|
|
2798
|
+
// Only add the default target if there is actually content for it
|
|
2799
|
+
if (ColumnControl.defaults.content) {
|
|
2800
|
+
identifyTargets(baseTargets, defaultInit);
|
|
2801
|
+
}
|
|
2378
2802
|
api.columns().every(function (i) {
|
|
2379
2803
|
var columnInit = this.init().columnControl;
|
|
2380
2804
|
var targets = identifyTargets(baseTargets.slice(), columnInit);
|
|
@@ -2392,12 +2816,20 @@ $(document).on('preInit.dt', function (e, settings) {
|
|
|
2392
2816
|
}
|
|
2393
2817
|
});
|
|
2394
2818
|
});
|
|
2395
|
-
|
|
2819
|
+
function searchClear() {
|
|
2396
2820
|
var ctx = this;
|
|
2397
2821
|
return this.iterator('column', function (settings, idx) {
|
|
2398
2822
|
// Note that the listeners for this will not redraw the table.
|
|
2399
2823
|
ctx.trigger('cc-search-clear', [idx]);
|
|
2400
2824
|
});
|
|
2825
|
+
}
|
|
2826
|
+
DataTable.Api.registerPlural('columns().columnControl.searchClear()', 'column().columnControl.searchClear()', searchClear);
|
|
2827
|
+
// Legacy (1.0.x)) - was never documented, but was mentioned in the forum
|
|
2828
|
+
DataTable.Api.registerPlural('columns().ccSearchClear()', 'column().ccSearchClear()', searchClear);
|
|
2829
|
+
DataTable.Api.registerPlural('columns().columnControl.searchList()', 'column().columnControl.searchList()', function (options) {
|
|
2830
|
+
return this.iterator('column', function (settings, idx) {
|
|
2831
|
+
settings.aoColumns[idx].columnControlSearchList(options);
|
|
2832
|
+
});
|
|
2401
2833
|
});
|
|
2402
2834
|
DataTable.ext.buttons.ccSearchClear = {
|
|
2403
2835
|
text: function (dt) {
|
|
@@ -2405,7 +2837,7 @@ DataTable.ext.buttons.ccSearchClear = {
|
|
|
2405
2837
|
},
|
|
2406
2838
|
init: function (dt, node, config) {
|
|
2407
2839
|
var _this = this;
|
|
2408
|
-
dt.on('draw', function () {
|
|
2840
|
+
dt.on('draw.DT', function () {
|
|
2409
2841
|
var enabled = false;
|
|
2410
2842
|
var glob = !!dt.search();
|
|
2411
2843
|
// No point in wasting clock cycles if we already know it will be enabled
|
|
@@ -2422,7 +2854,7 @@ DataTable.ext.buttons.ccSearchClear = {
|
|
|
2422
2854
|
},
|
|
2423
2855
|
action: function (e, dt, node, config) {
|
|
2424
2856
|
dt.search('');
|
|
2425
|
-
dt.columns().
|
|
2857
|
+
dt.columns().columnControl.searchClear();
|
|
2426
2858
|
dt.draw();
|
|
2427
2859
|
}
|
|
2428
2860
|
};
|
|
@@ -2558,12 +2990,18 @@ function identifyTargets(targets, input) {
|
|
|
2558
2990
|
}
|
|
2559
2991
|
}
|
|
2560
2992
|
if (Array.isArray(input)) {
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
add(
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2993
|
+
if (input.length === 0) {
|
|
2994
|
+
// Empty array - assume it is empty content
|
|
2995
|
+
add(ColumnControl.defaults.target);
|
|
2996
|
+
}
|
|
2997
|
+
else {
|
|
2998
|
+
// Array of options, or an array of content
|
|
2999
|
+
input.forEach(function (item) {
|
|
3000
|
+
add(typeof item === 'object' && item.target !== undefined
|
|
3001
|
+
? item.target
|
|
3002
|
+
: ColumnControl.defaults.target);
|
|
3003
|
+
});
|
|
3004
|
+
}
|
|
2567
3005
|
}
|
|
2568
3006
|
else if (typeof input === 'object') {
|
|
2569
3007
|
// Full options defined: { target: x, content: [] }
|
|
@@ -2578,9 +3016,7 @@ function identifyTargets(targets, input) {
|
|
|
2578
3016
|
* @returns true if it is a config object
|
|
2579
3017
|
*/
|
|
2580
3018
|
function isIConfig(item) {
|
|
2581
|
-
return typeof item === 'object' && item.target !== undefined
|
|
2582
|
-
? true
|
|
2583
|
-
: false;
|
|
3019
|
+
return typeof item === 'object' && item.target !== undefined ? true : false;
|
|
2584
3020
|
}
|
|
2585
3021
|
/**
|
|
2586
3022
|
* Determine if an array contains only content items or not
|