datatables.net-columncontrol 1.1.1 → 1.2.1

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.1.1
1
+ /*! ColumnControl 1.2.1
2
2
  * Copyright (c) SpryMedia Ltd - datatables.net/license
3
3
  *
4
4
  * SVG icons: ISC License
@@ -81,73 +81,6 @@ function addClass(el, classes) {
81
81
  });
82
82
  }
83
83
 
84
- // The SVG for many of these icons are from Lucide ( https://lucide.dev ), which are available
85
- // under the ISC License. There are a number of custom icons as well. These are optimised through
86
- // https://optimize.svgomg.net/
87
- function wrap(paths) {
88
- return ('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
89
- paths +
90
- '</svg>');
91
- }
92
- var icons = {
93
- chevronRight: wrap('<path d="m9 18 6-6-6-6"/>'),
94
- // columns-3
95
- columns: wrap('<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18"/><path d="M15 3v18"/>'),
96
- // Custom
97
- contains: wrap('<path d="M10 3h4v18h-4z"/><path d="M18 8h3v9h-3"/><path d="M6 17H3V8h3"/>'),
98
- empty: wrap('<circle cx="12" cy="12" r="10"/>'),
99
- ends: wrap('<path d="M21 3h-4v18h4z"/><path d="M13 8H3v9h10"/>'),
100
- // Customised
101
- equal: wrap('<line x1="5" x2="19" y1="9" y2="9"/><line x1="5" x2="19" y1="15" y2="15"/>'),
102
- greater: wrap('<path d="m9 18 6-6-6-6"/>'),
103
- // Custom
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"/>'),
113
- less: wrap('<path d="m15 18-6-6 6-6"/>'),
114
- // Custom
115
- lessOrEqual: wrap('<path d="m15 16-6-6 6-6"/><path d="m15 21-6-6"/>'),
116
- menu: wrap('<line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/>'),
117
- // move-horizontal
118
- move: wrap('<line x1="12" x2="12" y1="3" y2="21"/><polyline points="8 8 4 12 8 16"/><polyline points="16 16 20 12 16 8"/>'),
119
- // arrow-left-from-line
120
- moveLeft: wrap('<path d="m9 6-6 6 6 6"/><path d="M3 12h14"/><path d="M21 19V5"/>'),
121
- // arrow-right-from-line
122
- moveRight: wrap('<path d="M3 5v14"/><path d="M21 12H7"/><path d="m15 18 6-6-6-6"/>'),
123
- // Custom
124
- notContains: wrap('<path d="M15 4 9 20"/><path d="M3 8h18v9H3z"/>'),
125
- notEmpty: wrap('<circle cx="12" cy="12" r="10"/><line x1="9" x2="15" y1="15" y2="9"/>'),
126
- notEqual: wrap('<path d="M5 9h14"/><path d="M5 15h14"/><path d="M15 5 9 19"/>'),
127
- // Custom
128
- orderAddAsc: wrap('<path d="M17 21v-8"/><path d="M3 4h6"/><path d="M3 8h9"/><path d="M3 12h10"/><path d="M13 17h8"/>'),
129
- // Custom
130
- orderAddDesc: wrap('<path d="M17 21v-8"/><path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="M13 17h8"/>'),
131
- orderAsc: wrap('<path d="m3 8 4-4 4 4"/><path d="M7 4v16"/><path d="M11 12h4"/><path d="M11 16h7"/><path d="M11 20h10"/>'),
132
- // Custom
133
- orderClear: wrap('<path d="m21 21-8-8"/><path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="m13 21 8-8"/>'),
134
- orderDesc: wrap('<path d="m3 16 4 4 4-4"/><path d="M7 20V4"/><path d="M11 4h10"/><path d="M11 8h7"/><path d="M11 12h4"/>'),
135
- // Custom
136
- orderRemove: wrap('<path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="M13 17h8"/>'),
137
- // Custom
138
- orderNone: wrap('<path d="m3 8 4-4 4 4"/><path d="m11 16-4 4-4-4"/><path d="M7 4v16"/><path d="M15 8h6"/><path d="M15 16h6"/><path d="M13 12h8"/>'),
139
- // search
140
- search: wrap('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),
141
- // search-x
142
- searchClear: wrap('<path d="m13.5 8.5-5 5"/><path d="m8.5 8.5 5 5"/><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),
143
- // Custom
144
- starts: wrap('<path d="M3 3h4v18H3z"/><path d="M11 8h10v9H11"/>'),
145
- // tick
146
- tick: wrap('<path d="M20 6 9 17l-5-5"/>'),
147
- // x
148
- x: wrap('<path d="M18 6 6 18"/><path d="m6 6 12 12"/>')
149
- };
150
-
151
84
  /**
152
85
  * Close all or only other dropdowns
153
86
  *
@@ -395,6 +328,73 @@ var dropdownContent = {
395
328
  }
396
329
  };
397
330
 
331
+ // The SVG for many of these icons are from Lucide ( https://lucide.dev ), which are available
332
+ // under the ISC License. There are a number of custom icons as well. These are optimised through
333
+ // https://optimize.svgomg.net/
334
+ function wrap(paths) {
335
+ return ('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
336
+ paths +
337
+ '</svg>');
338
+ }
339
+ var icons = {
340
+ chevronRight: wrap('<path d="m9 18 6-6-6-6"/>'),
341
+ // columns-3
342
+ columns: wrap('<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18"/><path d="M15 3v18"/>'),
343
+ // Custom
344
+ contains: wrap('<path d="M10 3h4v18h-4z"/><path d="M18 8h3v9h-3"/><path d="M6 17H3V8h3"/>'),
345
+ empty: wrap('<circle cx="12" cy="12" r="10"/>'),
346
+ ends: wrap('<path d="M21 3h-4v18h4z"/><path d="M13 8H3v9h10"/>'),
347
+ // Customised
348
+ equal: wrap('<line x1="5" x2="19" y1="9" y2="9"/><line x1="5" x2="19" y1="15" y2="15"/>'),
349
+ greater: wrap('<path d="m9 18 6-6-6-6"/>'),
350
+ // Custom
351
+ greaterOrEqual: wrap('<path d="m9 16 6-6-6-6"/><path d="m9 21 6-6"/>'),
352
+ // Custom
353
+ 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"/>'),
354
+ // Custom
355
+ 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"/>'),
356
+ // Custom
357
+ 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"/>'),
358
+ // Custom
359
+ 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"/>'),
360
+ less: wrap('<path d="m15 18-6-6 6-6"/>'),
361
+ // Custom
362
+ lessOrEqual: wrap('<path d="m15 16-6-6 6-6"/><path d="m15 21-6-6"/>'),
363
+ menu: wrap('<line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/>'),
364
+ // move-horizontal
365
+ move: wrap('<line x1="12" x2="12" y1="3" y2="21"/><polyline points="8 8 4 12 8 16"/><polyline points="16 16 20 12 16 8"/>'),
366
+ // arrow-left-from-line
367
+ moveLeft: wrap('<path d="m9 6-6 6 6 6"/><path d="M3 12h14"/><path d="M21 19V5"/>'),
368
+ // arrow-right-from-line
369
+ moveRight: wrap('<path d="M3 5v14"/><path d="M21 12H7"/><path d="m15 18 6-6-6-6"/>'),
370
+ // Custom
371
+ notContains: wrap('<path d="M15 4 9 20"/><path d="M3 8h18v9H3z"/>'),
372
+ notEmpty: wrap('<circle cx="12" cy="12" r="10"/><line x1="9" x2="15" y1="15" y2="9"/>'),
373
+ notEqual: wrap('<path d="M5 9h14"/><path d="M5 15h14"/><path d="M15 5 9 19"/>'),
374
+ // Custom
375
+ orderAddAsc: wrap('<path d="M17 21v-8"/><path d="M3 4h6"/><path d="M3 8h9"/><path d="M3 12h10"/><path d="M13 17h8"/>'),
376
+ // Custom
377
+ orderAddDesc: wrap('<path d="M17 21v-8"/><path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="M13 17h8"/>'),
378
+ orderAsc: wrap('<path d="m3 8 4-4 4 4"/><path d="M7 4v16"/><path d="M11 12h4"/><path d="M11 16h7"/><path d="M11 20h10"/>'),
379
+ // Custom
380
+ orderClear: wrap('<path d="m21 21-8-8"/><path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="m13 21 8-8"/>'),
381
+ orderDesc: wrap('<path d="m3 16 4 4 4-4"/><path d="M7 20V4"/><path d="M11 4h10"/><path d="M11 8h7"/><path d="M11 12h4"/>'),
382
+ // Custom
383
+ orderRemove: wrap('<path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="M13 17h8"/>'),
384
+ // Custom
385
+ orderNone: wrap('<path d="m3 8 4-4 4 4"/><path d="m11 16-4 4-4-4"/><path d="M7 4v16"/><path d="M15 8h6"/><path d="M15 16h6"/><path d="M13 12h8"/>'),
386
+ // search
387
+ search: wrap('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),
388
+ // search-x
389
+ searchClear: wrap('<path d="m13.5 8.5-5 5"/><path d="m8.5 8.5 5 5"/><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),
390
+ // Custom
391
+ starts: wrap('<path d="M3 3h4v18H3z"/><path d="M11 8h10v9H11"/>'),
392
+ // tick
393
+ tick: wrap('<path d="M20 6 9 17l-5-5"/>'),
394
+ // x
395
+ x: wrap('<path d="M18 6 6 18"/><path d="m6 6 12 12"/>')
396
+ };
397
+
398
398
  var _namespace = 0;
399
399
  var Button = /** @class */ (function () {
400
400
  /**
@@ -1446,13 +1446,14 @@ var SearchInput = /** @class */ (function () {
1446
1446
  /**
1447
1447
  * Create a container element, for consistent DOM structure and styling
1448
1448
  */
1449
- function SearchInput(dt, idx) {
1449
+ function SearchInput(dt, idx, columnUnique) {
1450
1450
  var _this = this;
1451
1451
  this._type = 'text';
1452
1452
  this._sspTransform = null;
1453
1453
  this._sspData = {};
1454
1454
  this._dt = dt;
1455
1455
  this._idx = idx;
1456
+ this._colUnique = columnUnique;
1456
1457
  this._dom = {
1457
1458
  clear: createElement('span', 'dtcc-search-clear', icons['x']),
1458
1459
  container: createElement('div', SearchInput.classes.container),
@@ -1493,10 +1494,10 @@ var SearchInput = /** @class */ (function () {
1493
1494
  if (!data.columnControl) {
1494
1495
  data.columnControl = {};
1495
1496
  }
1496
- if (!data.columnControl[_this._idx]) {
1497
- data.columnControl[_this._idx] = {};
1497
+ if (!data.columnControl[_this._colUnique]) {
1498
+ data.columnControl[_this._colUnique] = {};
1498
1499
  }
1499
- data.columnControl[_this._idx].searchInput = {
1500
+ data.columnControl[_this._colUnique].searchInput = {
1500
1501
  logic: dom.select.value,
1501
1502
  type: _this._type,
1502
1503
  value: dom.input.value
@@ -1719,7 +1720,7 @@ var SearchInput = /** @class */ (function () {
1719
1720
  SearchInput.prototype._stateLoad = function (state) {
1720
1721
  var _a, _b;
1721
1722
  var dom = this._dom;
1722
- var idx = this._idx;
1723
+ var idx = this._colUnique;
1723
1724
  var loadedState = (_b = (_a = state === null || state === void 0 ? void 0 : state.columnControl) === null || _a === void 0 ? void 0 : _a[idx]) === null || _b === void 0 ? void 0 : _b.searchInput;
1724
1725
  if (loadedState) {
1725
1726
  // The search callback needs to know if we are loading an existing state or not
@@ -1743,6 +1744,7 @@ var SearchInput = /** @class */ (function () {
1743
1744
  var searchDateTime = {
1744
1745
  defaults: {
1745
1746
  clear: true,
1747
+ excludeLogic: [],
1746
1748
  format: '',
1747
1749
  mask: '',
1748
1750
  placeholder: '',
@@ -1759,7 +1761,7 @@ var searchDateTime = {
1759
1761
  var pickerFormat = '';
1760
1762
  var dataSrcFormat = '';
1761
1763
  var dateTime;
1762
- var searchInput = new SearchInput(dt, this.idx())
1764
+ var searchInput = new SearchInput(dt, this.idx(), this.idxOriginal())
1763
1765
  .type('date')
1764
1766
  .addClass('dtcc-searchDateTime')
1765
1767
  .sspTransform(function (val) { return toISO(val, pickerFormat, moment, luxon); })
@@ -1775,17 +1777,28 @@ var searchDateTime = {
1775
1777
  { label: dt.i18n(i18nBase + 'less', 'Before'), value: 'less' },
1776
1778
  { label: dt.i18n(i18nBase + 'empty', 'Empty'), value: 'empty' },
1777
1779
  { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
1778
- ])
1780
+ ].filter(function (x) { return !config.excludeLogic.includes(x.value); }))
1779
1781
  .search(function (searchType, searchTerm, loadingState) {
1782
+ // If in a dropdown, set the parent levels as active
1783
+ if (config._parents) {
1784
+ config._parents.forEach(function (btn) {
1785
+ return btn.activeList(_this.unique() + 'date', searchType === 'empty' || searchType === 'notEmpty' || !!searchTerm);
1786
+ });
1787
+ }
1788
+ var column = dt.column(_this.idx());
1780
1789
  // When SSP, don't apply a filter here, SearchInput will add to the submit data
1781
1790
  if (dt.page.info().serverSide) {
1791
+ // Need to let the searchClear button know if we have a filter
1792
+ // applied though.
1793
+ column.init().__ccList = !!(searchType === 'empty' ||
1794
+ searchType === 'notEmpty' ||
1795
+ searchTerm);
1782
1796
  if (!loadingState) {
1783
1797
  dt.draw();
1784
1798
  }
1785
1799
  return;
1786
1800
  }
1787
1801
  var mask = config.mask;
1788
- var column = dt.column(_this.idx());
1789
1802
  var search = searchTerm === ''
1790
1803
  ? ''
1791
1804
  : dateToNum(dateTime && fromPicker ? dateTime.val() : searchTerm.trim(), pickerFormat, moment, luxon, mask);
@@ -1826,12 +1839,6 @@ var searchDateTime = {
1826
1839
  return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) < search;
1827
1840
  });
1828
1841
  }
1829
- // If in a dropdown, set the parent levels as active
1830
- if (config._parents) {
1831
- config._parents.forEach(function (btn) {
1832
- return btn.activeList(_this.unique(), !!column.search.fixed('dtcc'));
1833
- });
1834
- }
1835
1842
  if (!loadingState) {
1836
1843
  column.draw();
1837
1844
  }
@@ -1840,9 +1847,7 @@ var searchDateTime = {
1840
1847
  dt.ready(function () {
1841
1848
  var DateTime = DataTable.use('datetime');
1842
1849
  dataSrcFormat = getFormat(dt, _this.idx());
1843
- pickerFormat = config.format
1844
- ? config.format
1845
- : dataSrcFormat;
1850
+ pickerFormat = config.format ? config.format : dataSrcFormat;
1846
1851
  if (DateTime) {
1847
1852
  dateTime = new DateTime(searchInput.input(), {
1848
1853
  format: pickerFormat,
@@ -2011,20 +2016,21 @@ function toISO(input, srcFormat, moment, luxon) {
2011
2016
  }
2012
2017
 
2013
2018
  /** Set the options to show in the list */
2014
- function setOptions(checkList, opts) {
2019
+ function setOptions(checkList, opts, activeList) {
2020
+ if (activeList === void 0) { activeList = []; }
2015
2021
  var existing = checkList.values();
2016
2022
  checkList.clear();
2017
2023
  for (var i = 0; i < opts.length; i++) {
2018
2024
  if (typeof opts[i] === 'object') {
2019
2025
  checkList.add({
2020
- active: false,
2026
+ active: activeList.includes(opts[i].value),
2021
2027
  label: opts[i].label,
2022
2028
  value: opts[i].value
2023
2029
  }, i === opts.length - 1);
2024
2030
  }
2025
2031
  else {
2026
2032
  checkList.add({
2027
- active: false,
2033
+ active: activeList.includes(opts[i]),
2028
2034
  label: opts[i],
2029
2035
  value: opts[i]
2030
2036
  }, i === opts.length - 1);
@@ -2131,11 +2137,18 @@ var searchList = {
2131
2137
  // The search can be applied from a stored start at start up before the options are
2132
2138
  // available. It can also be applied by user input, so it is generalised into this function.
2133
2139
  var applySearch = function (values) {
2140
+ // If in a dropdown, set the parent levels as active
2141
+ if (config._parents) {
2142
+ config._parents.forEach(function (btn) { return btn.activeList(_this.unique() + 'list', values && !!values.length); });
2143
+ }
2144
+ var col = dt.column(_this.idx());
2134
2145
  // When SSP, don't do any client-side filtering
2135
2146
  if (dt.page.info().serverSide) {
2147
+ // Need to let the searchClear button know if we have a filter
2148
+ // applied though.
2149
+ col.init().__ccList = values && values.length !== 0;
2136
2150
  return;
2137
2151
  }
2138
- var col = dt.column(_this.idx());
2139
2152
  if (!values) {
2140
2153
  return;
2141
2154
  }
@@ -2149,10 +2162,6 @@ var searchList = {
2149
2162
  return values.includes(val);
2150
2163
  });
2151
2164
  }
2152
- // If in a dropdown, set the parent levels as active
2153
- if (config._parents) {
2154
- config._parents.forEach(function (btn) { return btn.activeList(_this.unique(), !!values.length); });
2155
- }
2156
2165
  };
2157
2166
  var checkList = new CheckList(dt, this, {
2158
2167
  search: config.search,
@@ -2171,8 +2180,9 @@ var searchList = {
2171
2180
  dt.draw();
2172
2181
  }
2173
2182
  });
2183
+ loadedValues = getState(this.idx(), dt.state.loaded());
2174
2184
  if (config.options) {
2175
- setOptions(checkList, config.options);
2185
+ setOptions(checkList, config.options, loadedValues);
2176
2186
  }
2177
2187
  else {
2178
2188
  dt.ready(function () {
@@ -2183,9 +2193,11 @@ var searchList = {
2183
2193
  // Need to wait for the draw to complete so the table has the latest data
2184
2194
  dt.one('draw', function () {
2185
2195
  reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
2196
+ loadedValues = null;
2186
2197
  });
2187
2198
  });
2188
2199
  }
2200
+ var sspValues = [];
2189
2201
  // Data for server-side processing
2190
2202
  if (dt.page.info().serverSide) {
2191
2203
  dt.on('preXhr.DT', function (e, s, d) {
@@ -2196,22 +2208,24 @@ var searchList = {
2196
2208
  if (!d.columns[_this.idx()].columnControl) {
2197
2209
  d.columns[_this.idx()].columnControl = {};
2198
2210
  }
2211
+ var values = sspValues.length ? sspValues : checkList.values();
2212
+ sspValues = [];
2199
2213
  // We need the indexes in the HTTP parameter names (for .NET), so use an object.
2200
- d.columns[_this.idx()].columnControl.list = Object.assign({}, checkList.values());
2214
+ d.columns[_this.idx()].columnControl.list = Object.assign({}, values);
2201
2215
  });
2202
2216
  }
2203
2217
  // Unlike the SearchInput based search contents, CheckList does not handle state saving
2204
2218
  // (since the mechanism for column visibility is different), so state saving is handled
2205
2219
  // here.
2206
2220
  dt.on('stateLoaded', function (e, s, state) {
2207
- var values = getState(_this.idx(), state);
2221
+ var values = getState(_this.idxOriginal(), state);
2208
2222
  if (values) {
2209
2223
  checkList.values(values);
2210
2224
  applySearch(values);
2211
2225
  }
2212
2226
  });
2213
2227
  dt.on('stateSaveParams', function (e, s, data) {
2214
- var idx = _this.idx();
2228
+ var idx = _this.idxOriginal();
2215
2229
  if (!data.columnControl) {
2216
2230
  data.columnControl = {};
2217
2231
  }
@@ -2233,8 +2247,12 @@ var searchList = {
2233
2247
  setOptions(checkList, options);
2234
2248
  }
2235
2249
  };
2236
- loadedValues = getState(this.idx(), dt.state.loaded());
2237
2250
  applySearch(loadedValues);
2251
+ // If SSP, then there are no options yet, so for a saved state we need
2252
+ // to use the values from the state in a temporary variable
2253
+ if (dt.page.info().serverSide && loadedValues && loadedValues.length) {
2254
+ sspValues = loadedValues;
2255
+ }
2238
2256
  return checkList.element();
2239
2257
  }
2240
2258
  };
@@ -2242,6 +2260,7 @@ var searchList = {
2242
2260
  var searchNumber = {
2243
2261
  defaults: {
2244
2262
  clear: true,
2263
+ excludeLogic: [],
2245
2264
  placeholder: '',
2246
2265
  title: '',
2247
2266
  titleAttr: ''
@@ -2250,7 +2269,7 @@ var searchNumber = {
2250
2269
  var _this = this;
2251
2270
  var dt = this.dt();
2252
2271
  var i18nBase = 'columnControl.search.number.';
2253
- var searchInput = new SearchInput(dt, this.idx())
2272
+ var searchInput = new SearchInput(dt, this.idx(), this.idxOriginal())
2254
2273
  .type('num')
2255
2274
  .addClass('dtcc-searchNumber')
2256
2275
  .clearable(config.clear)
@@ -2266,19 +2285,34 @@ var searchNumber = {
2266
2285
  value: 'greaterOrEqual'
2267
2286
  },
2268
2287
  { label: dt.i18n(i18nBase + 'less', 'Less than'), value: 'less' },
2269
- { label: dt.i18n(i18nBase + 'lessOrEqual', 'Less or equal'), value: 'lessOrEqual' },
2288
+ {
2289
+ label: dt.i18n(i18nBase + 'lessOrEqual', 'Less or equal'),
2290
+ value: 'lessOrEqual'
2291
+ },
2270
2292
  { label: dt.i18n(i18nBase + 'empty', 'Empty'), value: 'empty' },
2271
2293
  { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
2272
- ])
2294
+ ].filter(function (x) { return !config.excludeLogic.includes(x.value); }))
2273
2295
  .search(function (searchType, searchTerm, loadingState) {
2274
- // When SSP, don't apply a filter here, SearchInput will add to the submit data
2296
+ // If in a dropdown, set the parent levels as active
2297
+ if (config._parents) {
2298
+ config._parents.forEach(function (btn) {
2299
+ return btn.activeList(_this.unique() + 'number', searchType === 'empty' || searchType === 'notEmpty' || !!searchTerm);
2300
+ });
2301
+ }
2302
+ var column = dt.column(_this.idx());
2303
+ // When SSP, don't apply a filter here, SearchInput will add to
2304
+ // the submit data
2275
2305
  if (dt.page.info().serverSide) {
2306
+ // Need to let the searchClear button know if we have a filter
2307
+ // applied though.
2308
+ column.init().__ccList = !!(searchType === 'empty' ||
2309
+ searchType === 'notEmpty' ||
2310
+ searchTerm);
2276
2311
  if (!loadingState) {
2277
2312
  dt.draw();
2278
2313
  }
2279
2314
  return;
2280
2315
  }
2281
- var column = dt.column(_this.idx());
2282
2316
  if (searchType === 'empty') {
2283
2317
  column.search.fixed('dtcc', function (haystack) { return !haystack; });
2284
2318
  }
@@ -2312,12 +2346,6 @@ var searchNumber = {
2312
2346
  else if (searchType === 'lessOrEqual') {
2313
2347
  column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) <= searchTerm; });
2314
2348
  }
2315
- // If in a dropdown, set the parents as active
2316
- if (config._parents) {
2317
- config._parents.forEach(function (btn) {
2318
- return btn.activeList(_this.unique(), !!column.search.fixed('dtcc'));
2319
- });
2320
- }
2321
2349
  if (!loadingState) {
2322
2350
  column.draw();
2323
2351
  }
@@ -2347,6 +2375,7 @@ function stringToNum(d) {
2347
2375
  var searchText = {
2348
2376
  defaults: {
2349
2377
  clear: true,
2378
+ excludeLogic: [],
2350
2379
  placeholder: '',
2351
2380
  title: '',
2352
2381
  titleAttr: ''
@@ -2355,7 +2384,7 @@ var searchText = {
2355
2384
  var _this = this;
2356
2385
  var dt = this.dt();
2357
2386
  var i18nBase = 'columnControl.search.text.';
2358
- var searchInput = new SearchInput(dt, this.idx())
2387
+ var searchInput = new SearchInput(dt, this.idx(), this.idxOriginal())
2359
2388
  .addClass('dtcc-searchText')
2360
2389
  .clearable(config.clear)
2361
2390
  .placeholder(config.placeholder)
@@ -2373,16 +2402,27 @@ var searchText = {
2373
2402
  { label: dt.i18n(i18nBase + 'ends', 'Ends'), value: 'ends' },
2374
2403
  { label: dt.i18n(i18nBase + 'empty', 'Empty'), value: 'empty' },
2375
2404
  { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
2376
- ])
2405
+ ].filter(function (x) { return !config.excludeLogic.includes(x.value); }))
2377
2406
  .search(function (searchType, searchTerm, loadingState) {
2407
+ // If in a dropdown, set the parent levels as active
2408
+ if (config._parents) {
2409
+ config._parents.forEach(function (btn) {
2410
+ return btn.activeList(_this.unique() + 'text', searchType === 'empty' || searchType === 'notEmpty' || !!searchTerm);
2411
+ });
2412
+ }
2413
+ var column = dt.column(_this.idx());
2378
2414
  // When SSP, don't apply a filter here, SearchInput will add to the submit data
2379
2415
  if (dt.page.info().serverSide) {
2416
+ // Need to let the searchClear button know if we have a filter
2417
+ // applied though.
2418
+ column.init().__ccList = !!(searchType === 'empty' ||
2419
+ searchType === 'notEmpty' ||
2420
+ searchTerm);
2380
2421
  if (!loadingState) {
2381
2422
  dt.draw();
2382
2423
  }
2383
2424
  return;
2384
2425
  }
2385
- var column = dt.column(_this.idx());
2386
2426
  searchTerm = searchTerm.toLowerCase();
2387
2427
  if (searchType === 'empty') {
2388
2428
  column.search.fixed('dtcc', function (haystack) { return !haystack; });
@@ -2427,7 +2467,7 @@ var searchText = {
2427
2467
  // If in a dropdown, set the parent levels as active
2428
2468
  if (config._parents) {
2429
2469
  config._parents.forEach(function (btn) {
2430
- return btn.activeList(_this.unique(), !!column.search.fixed('dtcc'));
2470
+ return btn.activeList(_this.unique() + 'string', !!column.search.fixed('dtcc'));
2431
2471
  });
2432
2472
  }
2433
2473
  if (!loadingState) {
@@ -2444,15 +2484,15 @@ var search = {
2444
2484
  },
2445
2485
  init: function (config) {
2446
2486
  var _this = this;
2447
- var _a, _b, _c;
2487
+ var _a, _b;
2448
2488
  var dt = this.dt();
2449
2489
  var idx = this.idx();
2450
2490
  var displayEl;
2451
- var loadedState = (_c = (_b = (_a = dt.state.loaded()) === null || _a === void 0 ? void 0 : _a.columnControl) === null || _b === void 0 ? void 0 : _b[idx]) === null || _c === void 0 ? void 0 : _c.searchInput;
2491
+ var loadedState = (_b = (_a = dt.state.loaded()) === null || _a === void 0 ? void 0 : _a.columnControl) === null || _b === void 0 ? void 0 : _b[idx];
2452
2492
  var initType = function (type) {
2453
2493
  var json = getJsonOptions(dt, idx);
2454
2494
  // Attempt to match what type of search should be shown
2455
- if (config.allowSearchList && json) {
2495
+ if (type === 'list' || (config.allowSearchList && json)) {
2456
2496
  // We've got a list of JSON options, and are allowed to show the searchList
2457
2497
  return searchList.init.call(_this, Object.assign({}, searchList.defaults, config));
2458
2498
  }
@@ -2473,9 +2513,14 @@ var search = {
2473
2513
  // to allow the state to be applied to the table and the first draw to have a filter
2474
2514
  // applied (if it is needed).
2475
2515
  if (loadedState) {
2476
- displayEl = initType(loadedState.type);
2516
+ if (loadedState.searchInput) {
2517
+ displayEl = initType(loadedState.searchInput.type);
2518
+ }
2519
+ else if (loadedState.searchList) {
2520
+ displayEl = initType('list');
2521
+ }
2477
2522
  }
2478
- else {
2523
+ if (!displayEl) {
2479
2524
  // Wait until we can get the data type for the column and the run the corresponding type
2480
2525
  displayEl = document.createElement('div');
2481
2526
  dt.ready(function () {
@@ -2507,9 +2552,12 @@ var searchClear$1 = {
2507
2552
  .enable(false);
2508
2553
  dt.on('draw', function () {
2509
2554
  // change enable state
2510
- var search = dt.column(_this.idx()).search.fixed('dtcc');
2511
- var searchList = dt.column(_this.idx()).search.fixed('dtcc-list');
2512
- btn.enable(!!(search || searchList));
2555
+ var col = dt.column(_this.idx());
2556
+ var search = col.search.fixed('dtcc');
2557
+ var searchList = col.search.fixed('dtcc-list');
2558
+ var searchSearchSsp = col.init().__ccSearch;
2559
+ var searchListSsp = col.init().__ccList;
2560
+ btn.enable(!!(search || searchList || searchSearchSsp || searchListSsp));
2513
2561
  });
2514
2562
  return btn.element();
2515
2563
  }
@@ -2694,6 +2742,20 @@ var ColumnControl = /** @class */ (function () {
2694
2742
  ColumnControl.prototype.idx = function () {
2695
2743
  return this._s.columnIdx;
2696
2744
  };
2745
+ /**
2746
+ * Get the column index that was originally used for initialisation of this
2747
+ * column. This is important when used with ColReorder and when arrays can
2748
+ * be reordered (i.e. state saving on initialisation).
2749
+ *
2750
+ * @returns Column index
2751
+ */
2752
+ ColumnControl.prototype.idxOriginal = function () {
2753
+ var currentIdx = this.idx();
2754
+ if (this._dt.colReorder) {
2755
+ return this._dt.colReorder.transpose(currentIdx, 'toOriginal');
2756
+ }
2757
+ return currentIdx;
2758
+ };
2697
2759
  /**
2698
2760
  * Covert the options from `content` in the DataTable initialisation for this instance into a
2699
2761
  * resolved plugin and options.
@@ -2788,7 +2850,7 @@ var ColumnControl = /** @class */ (function () {
2788
2850
  /** SVG icons that can be used by the content plugins */
2789
2851
  ColumnControl.icons = icons;
2790
2852
  /** Version */
2791
- ColumnControl.version = '1.1.1';
2853
+ ColumnControl.version = '1.2.1';
2792
2854
  return ColumnControl;
2793
2855
  }());
2794
2856
 
@@ -2890,7 +2952,10 @@ DataTable.ext.buttons.ccSearchClear = {
2890
2952
  // No point in wasting clock cycles if we already know it will be enabled
2891
2953
  if (!glob) {
2892
2954
  dt.columns().every(function () {
2893
- if (this.search.fixed('dtcc') || this.search.fixed('dtcc-list')) {
2955
+ if (this.search.fixed('dtcc') ||
2956
+ this.search.fixed('dtcc-list') ||
2957
+ this.init().__ccList // server-side processing
2958
+ ) {
2894
2959
  enabled = true;
2895
2960
  }
2896
2961
  });