datatables.net-columncontrol 1.0.7 → 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.7
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
- if (this._s.namespace) {
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
- // Use a unique namespace to be able to easily remove per button
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.emptyOption', 'Empty'))
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, parent) {
770
+ CheckList.prototype.searchListener = function (dt) {
756
771
  var _this = this;
757
- // Column control search clearing (column().ccSearchClear() method)
772
+ // Column control search clearing (column().columnControl.searchClear() method)
758
773
  dt.on('cc-search-clear', function (e, colIdx) {
759
- if (colIdx === parent.idx()) {
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[idx]) {
1298
- data.columnControl[idx] = {};
1500
+ if (!data.columnControl[_this._idx]) {
1501
+ data.columnControl[_this._idx] = {};
1299
1502
  }
1300
- data.columnControl[idx].searchInput = {
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().ccSearchClear() method)
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 displayFormat = '';
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(), displayFormat, moment, luxon);
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) { return dateToNum(haystack, displayFormat, moment, luxon) == search; });
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) { return dateToNum(haystack, displayFormat, moment, luxon) != search; });
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) { return dateToNum(haystack, displayFormat, moment, luxon) > search; });
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) { return dateToNum(haystack, displayFormat, moment, luxon) < search; });
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
- displayFormat = getFormat(dt, _this.idx());
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: displayFormat,
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, then we need to use Moment / Luxon's default
1612
- // locale formatting.
1613
- var moment = DataTable.use('moment');
1614
- var luxon = DataTable.use('luxon');
1615
- if (moment) {
1616
- return moment().creationData().locale._longDateFormat.L;
1617
- }
1618
- if (luxon) {
1619
- // Luxon doesn't appear to provide a way to let us get the default locale formatting
1620
- // string, so we need to attempt to decode it.
1621
- return luxon.DateTime.fromISO('1999-08-07')
1622
- .toLocaleString()
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
- else if (input instanceof Date) {
1658
- return input.getTime();
1947
+ if (input instanceof Date) {
1948
+ d = input;
1659
1949
  }
1660
1950
  else if (srcFormat !== 'YYYY-MM-DD' && (moment || luxon)) {
1661
- return moment
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, '-'));
1959
+ }
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
+ }
1664
1983
  }
1665
- return new Date(input).getTime();
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 */
@@ -1740,7 +2085,7 @@ function reloadOptions(dt, config, idx, checkList, loadedValues) {
1740
2085
  // No point in doing any further processing here
1741
2086
  return;
1742
2087
  }
1743
- else {
2088
+ else if (!dt.page.info().serverSide) {
1744
2089
  // Either no ajax object (i.e. not an Ajax table), or no matching ajax options
1745
2090
  // for this column - get the values for the column, taking into account
1746
2091
  // orthogonal rendering
@@ -1786,6 +2131,10 @@ var searchList = {
1786
2131
  // The search can be applied from a stored start at start up before the options are
1787
2132
  // available. It can also be applied by user input, so it is generalised into this function.
1788
2133
  var applySearch = function (values) {
2134
+ // When SSP, don't do any client-side filtering
2135
+ if (dt.page.info().serverSide) {
2136
+ return;
2137
+ }
1789
2138
  var col = dt.column(_this.idx());
1790
2139
  if (!values) {
1791
2140
  return;
@@ -1805,11 +2154,11 @@ var searchList = {
1805
2154
  config._parents.forEach(function (btn) { return btn.activeList(_this.unique(), !!values.length); });
1806
2155
  }
1807
2156
  };
1808
- var checkList = new CheckList(dt, {
2157
+ var checkList = new CheckList(dt, this, {
1809
2158
  search: config.search,
1810
2159
  select: config.select
1811
2160
  })
1812
- .searchListener(dt, this)
2161
+ .searchListener(dt)
1813
2162
  .title(dt
1814
2163
  .i18n('columnControl.searchList', config.title)
1815
2164
  .replace('[title]', dt.column(this.idx()).title()))
@@ -1829,14 +2178,24 @@ var searchList = {
1829
2178
  dt.ready(function () {
1830
2179
  reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
1831
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
+ });
1832
2188
  }
1833
- // Xhr event listener for updates of options
1834
- dt.on('xhr', function (e, s, json) {
1835
- // Need to wait for the draw to complete so the table has the latest data
1836
- dt.one('draw', function () {
1837
- reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
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());
1838
2197
  });
1839
- });
2198
+ }
1840
2199
  // Unlike the SearchInput based search contents, CheckList does not handle state saving
1841
2200
  // (since the mechanism for column visibility is different), so state saving is handled
1842
2201
  // here.
@@ -1844,6 +2203,7 @@ var searchList = {
1844
2203
  var values = getState(_this.idx(), state);
1845
2204
  if (values) {
1846
2205
  checkList.values(values);
2206
+ applySearch(values);
1847
2207
  }
1848
2208
  });
1849
2209
  dt.on('stateSaveParams', function (e, s, data) {
@@ -1861,6 +2221,14 @@ var searchList = {
1861
2221
  ? checkList.values()
1862
2222
  : loadedValues;
1863
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
+ };
1864
2232
  loadedValues = getState(this.idx(), dt.state.loaded());
1865
2233
  applySearch(loadedValues);
1866
2234
  return checkList.element();
@@ -1899,6 +2267,13 @@ var searchNumber = {
1899
2267
  { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
1900
2268
  ])
1901
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
+ }
1902
2277
  var column = dt.column(_this.idx());
1903
2278
  if (searchType === 'empty') {
1904
2279
  column.search.fixed('dtcc', function (haystack) { return !haystack; });
@@ -1996,6 +2371,13 @@ var searchText = {
1996
2371
  { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
1997
2372
  ])
1998
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
+ }
1999
2381
  var column = dt.column(_this.idx());
2000
2382
  searchTerm = searchTerm.toLowerCase();
2001
2383
  if (searchType === 'empty') {
@@ -2102,7 +2484,7 @@ var search = {
2102
2484
  }
2103
2485
  };
2104
2486
 
2105
- var searchClear = {
2487
+ var searchClear$1 = {
2106
2488
  defaults: {
2107
2489
  className: 'searchClear',
2108
2490
  icon: 'searchClear',
@@ -2111,12 +2493,12 @@ var searchClear = {
2111
2493
  init: function (config) {
2112
2494
  var _this = this;
2113
2495
  var dt = this.dt();
2114
- var btn = new Button(dt)
2496
+ var btn = new Button(dt, this)
2115
2497
  .text(dt.i18n('columnControl.searchClear', config.text))
2116
2498
  .icon(config.icon)
2117
2499
  .className(config.className)
2118
2500
  .handler(function () {
2119
- dt.column(_this.idx()).ccSearchClear().draw();
2501
+ dt.column(_this.idx()).columnControl.searchClear().draw();
2120
2502
  })
2121
2503
  .enable(false);
2122
2504
  dt.on('draw', function () {
@@ -2138,6 +2520,7 @@ var searchDropdown = {
2138
2520
  columns: '',
2139
2521
  hidable: true,
2140
2522
  options: null,
2523
+ orthogonal: 'display',
2141
2524
  placeholder: '',
2142
2525
  search: true,
2143
2526
  select: true,
@@ -2194,6 +2577,10 @@ var contentTypes = {
2194
2577
  reorder: reorder,
2195
2578
  reorderLeft: reorderLeft,
2196
2579
  reorderRight: reorderRight,
2580
+ rowGroup: rowGroup,
2581
+ rowGroupAdd: rowGroupAdd,
2582
+ rowGroupClear: rowGroupClear,
2583
+ rowGroupRemove: rowGroupRemove,
2197
2584
  order: order,
2198
2585
  orderAddAsc: orderAddAsc,
2199
2586
  orderAddDesc: orderAddDesc,
@@ -2203,7 +2590,7 @@ var contentTypes = {
2203
2590
  orderRemove: orderRemove,
2204
2591
  orderStatus: orderStatus,
2205
2592
  search: search,
2206
- searchClear: searchClear,
2593
+ searchClear: searchClear$1,
2207
2594
  searchDropdown: searchDropdown,
2208
2595
  searchDateTime: searchDateTime,
2209
2596
  searchList: searchList,
@@ -2233,7 +2620,8 @@ var ColumnControl = /** @class */ (function () {
2233
2620
  this._c = {};
2234
2621
  this._s = {
2235
2622
  columnIdx: null,
2236
- unique: null
2623
+ unique: null,
2624
+ toDestroy: []
2237
2625
  };
2238
2626
  this._dt = dt;
2239
2627
  this._s.columnIdx = columnIdx;
@@ -2259,10 +2647,33 @@ var ColumnControl = /** @class */ (function () {
2259
2647
  _this._dom.wrapper.appendChild(el);
2260
2648
  });
2261
2649
  dt.on('destroy', function () {
2650
+ _this._s.toDestroy.slice().forEach(function (el) {
2651
+ el.destroy();
2652
+ });
2262
2653
  _this._dom.wrapper.remove();
2263
2654
  });
2264
2655
  }
2265
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
+ };
2266
2677
  /**
2267
2678
  * Get the DataTables API instance that hosts this instance of ColumnControl
2268
2679
  *
@@ -2373,7 +2784,7 @@ var ColumnControl = /** @class */ (function () {
2373
2784
  /** SVG icons that can be used by the content plugins */
2374
2785
  ColumnControl.icons = icons;
2375
2786
  /** Version */
2376
- ColumnControl.version = '1.0.7';
2787
+ ColumnControl.version = '1.1.0';
2377
2788
  return ColumnControl;
2378
2789
  }());
2379
2790
 
@@ -2445,12 +2856,20 @@ $(document).on('preInit.dt', function (e, settings) {
2445
2856
  }
2446
2857
  });
2447
2858
  });
2448
- DataTable.Api.registerPlural('columns().ccSearchClear()', 'column().ccSearchClear()', function () {
2859
+ function searchClear() {
2449
2860
  var ctx = this;
2450
2861
  return this.iterator('column', function (settings, idx) {
2451
2862
  // Note that the listeners for this will not redraw the table.
2452
2863
  ctx.trigger('cc-search-clear', [idx]);
2453
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
+ });
2454
2873
  });
2455
2874
  DataTable.ext.buttons.ccSearchClear = {
2456
2875
  text: function (dt) {
@@ -2458,7 +2877,7 @@ DataTable.ext.buttons.ccSearchClear = {
2458
2877
  },
2459
2878
  init: function (dt, node, config) {
2460
2879
  var _this = this;
2461
- dt.on('draw', function () {
2880
+ dt.on('draw.DT', function () {
2462
2881
  var enabled = false;
2463
2882
  var glob = !!dt.search();
2464
2883
  // No point in wasting clock cycles if we already know it will be enabled
@@ -2475,7 +2894,7 @@ DataTable.ext.buttons.ccSearchClear = {
2475
2894
  },
2476
2895
  action: function (e, dt, node, config) {
2477
2896
  dt.search('');
2478
- dt.columns().ccSearchClear();
2897
+ dt.columns().columnControl.searchClear();
2479
2898
  dt.draw();
2480
2899
  }
2481
2900
  };
@@ -2637,9 +3056,7 @@ function identifyTargets(targets, input) {
2637
3056
  * @returns true if it is a config object
2638
3057
  */
2639
3058
  function isIConfig(item) {
2640
- return typeof item === 'object' && item.target !== undefined
2641
- ? true
2642
- : false;
3059
+ return typeof item === 'object' && item.target !== undefined ? true : false;
2643
3060
  }
2644
3061
  /**
2645
3062
  * Determine if an array contains only content items or not