aa-intel-tool 2.12.1__py3-none-any.whl → 2.13.1__py3-none-any.whl

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.
Files changed (60) hide show
  1. aa_intel_tool/__init__.py +1 -1
  2. aa_intel_tool/constants.py +38 -35
  3. aa_intel_tool/locale/cs_CZ/LC_MESSAGES/django.po +6 -6
  4. aa_intel_tool/locale/de/LC_MESSAGES/django.mo +0 -0
  5. aa_intel_tool/locale/de/LC_MESSAGES/django.po +10 -10
  6. aa_intel_tool/locale/django.pot +7 -7
  7. aa_intel_tool/locale/es/LC_MESSAGES/django.po +6 -6
  8. aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.po +6 -6
  9. aa_intel_tool/locale/it_IT/LC_MESSAGES/django.po +6 -6
  10. aa_intel_tool/locale/ja/LC_MESSAGES/django.mo +0 -0
  11. aa_intel_tool/locale/ja/LC_MESSAGES/django.po +10 -10
  12. aa_intel_tool/locale/ko_KR/LC_MESSAGES/django.po +6 -6
  13. aa_intel_tool/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
  14. aa_intel_tool/locale/nl_NL/LC_MESSAGES/django.po +11 -12
  15. aa_intel_tool/locale/pl_PL/LC_MESSAGES/django.po +6 -6
  16. aa_intel_tool/locale/ru/LC_MESSAGES/django.po +6 -6
  17. aa_intel_tool/locale/sk/LC_MESSAGES/django.po +6 -6
  18. aa_intel_tool/locale/uk/LC_MESSAGES/django.po +6 -6
  19. aa_intel_tool/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  20. aa_intel_tool/locale/zh_Hans/LC_MESSAGES/django.po +15 -12
  21. aa_intel_tool/parser/general.py +7 -1
  22. aa_intel_tool/parser/module/dscan.py +4 -4
  23. aa_intel_tool/templates/aa_intel_tool/views/scan/chatlist.html +4 -2
  24. aa_intel_tool/templates/aa_intel_tool/views/scan/dscan.html +4 -2
  25. aa_intel_tool/templates/aa_intel_tool/views/scan/fleetcomp.html +4 -2
  26. aa_intel_tool/tests/__init__.py +17 -0
  27. aa_intel_tool/tests/test_access.py +1 -6
  28. aa_intel_tool/tests/test_auth_hooks.py +1 -6
  29. {aa_intel_tool-2.12.1.dist-info → aa_intel_tool-2.13.1.dist-info}/METADATA +6 -10
  30. {aa_intel_tool-2.12.1.dist-info → aa_intel_tool-2.13.1.dist-info}/RECORD +32 -60
  31. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/dataTables.bootstrap5.css +0 -610
  32. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/dataTables.bootstrap5.js +0 -123
  33. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/dataTables.bootstrap5.min.css +0 -8
  34. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/dataTables.bootstrap5.min.css.map +0 -1
  35. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/dataTables.bootstrap5.min.js +0 -6
  36. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/dataTables.bootstrap5.min.js.map +0 -1
  37. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/datatables.min.js +0 -10
  38. aa_intel_tool/static/aa_intel_tool/libs/DataTables/2.3.4/datatables.min.js.map +0 -1
  39. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/css/columnControl.bootstrap5.css +0 -516
  40. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/css/columnControl.bootstrap5.min.css +0 -2
  41. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/css/columnControl.bootstrap5.min.css.map +0 -1
  42. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/js/columnControl.bootstrap5.js +0 -73
  43. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/js/columnControl.bootstrap5.min.js +0 -6
  44. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/js/columnControl.bootstrap5.min.js.map +0 -1
  45. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/js/dataTables.columnControl.js +0 -3091
  46. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/js/dataTables.columnControl.min.js +0 -10
  47. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/ColumnControl/1.1.1/js/dataTables.columnControl.min.js.map +0 -1
  48. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/css/fixedHeader.bootstrap5.css +0 -20
  49. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/css/fixedHeader.bootstrap5.min.css +0 -2
  50. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/css/fixedHeader.bootstrap5.min.css.map +0 -1
  51. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/js/dataTables.fixedHeader.js +0 -1203
  52. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/js/dataTables.fixedHeader.min.js +0 -6
  53. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/js/dataTables.fixedHeader.min.js.map +0 -1
  54. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/js/fixedHeader.bootstrap5.js +0 -59
  55. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/js/fixedHeader.bootstrap5.min.js +0 -6
  56. aa_intel_tool/static/aa_intel_tool/libs/DataTables/Extensions/FixedHeader/4.0.4/js/fixedHeader.bootstrap5.min.js.map +0 -1
  57. aa_intel_tool/templates/aa_intel_tool/bundles/datatables-2-css.html +0 -11
  58. aa_intel_tool/templates/aa_intel_tool/bundles/datatables-2-js.html +0 -14
  59. {aa_intel_tool-2.12.1.dist-info → aa_intel_tool-2.13.1.dist-info}/WHEEL +0 -0
  60. {aa_intel_tool-2.12.1.dist-info → aa_intel_tool-2.13.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,3091 +0,0 @@
1
- /*!
2
- * ColumnControl 1.1.1
3
- * Copyright (c) SpryMedia Ltd - datatables.net/license
4
- *
5
- * SVG icons: ISC License
6
- * Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2022 as part of Feather (MIT).
7
- * All other copyright (c) for Lucide are held by Lucide Contributors 2022.
8
- */
9
-
10
- (function( factory ){
11
- if ( typeof define === 'function' && define.amd ) {
12
- // AMD
13
- define( ['jquery', 'datatables.net'], function ( $ ) {
14
- return factory( $, window, document );
15
- } );
16
- }
17
- else if ( typeof exports === 'object' ) {
18
- // CommonJS
19
- var jq = require('jquery');
20
- var cjsRequires = function (root, $) {
21
- if ( ! $.fn.dataTable ) {
22
- require('datatables.net')(root, $);
23
- }
24
- };
25
-
26
- if (typeof window === 'undefined') {
27
- module.exports = function (root, $) {
28
- if ( ! root ) {
29
- // CommonJS environments without a window global must pass a
30
- // root. This will give an error otherwise
31
- root = window;
32
- }
33
-
34
- if ( ! $ ) {
35
- $ = jq( root );
36
- }
37
-
38
- cjsRequires( root, $ );
39
- return factory( $, root, root.document );
40
- };
41
- }
42
- else {
43
- cjsRequires( window, jq );
44
- module.exports = factory( jq, window, window.document );
45
- }
46
- }
47
- else {
48
- // Browser
49
- factory( jQuery, window, document );
50
- }
51
- }(function( $, window, document ) {
52
- 'use strict';
53
- var DataTable = $.fn.dataTable;
54
-
55
-
56
-
57
- function createElement(type, classes, text, children) {
58
- if (classes === void 0) { classes = []; }
59
- if (text === void 0) { text = null; }
60
- if (children === void 0) { children = []; }
61
- var el = document.createElement(type);
62
- addClass(el, classes);
63
- if (text) {
64
- el.innerHTML = text;
65
- }
66
- children.forEach(function (child) {
67
- el.appendChild(child);
68
- });
69
- return el;
70
- }
71
- function addClass(el, classes) {
72
- if (!classes) {
73
- return;
74
- }
75
- if (!Array.isArray(classes)) {
76
- classes = [classes];
77
- }
78
- classes.forEach(function (className) {
79
- if (el && className) {
80
- el.classList.add(className);
81
- }
82
- });
83
- }
84
-
85
- // The SVG for many of these icons are from Lucide ( https://lucide.dev ), which are available
86
- // under the ISC License. There are a number of custom icons as well. These are optimised through
87
- // https://optimize.svgomg.net/
88
- function wrap(paths) {
89
- 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">' +
90
- paths +
91
- '</svg>');
92
- }
93
- var icons = {
94
- chevronRight: wrap('<path d="m9 18 6-6-6-6"/>'),
95
- // columns-3
96
- columns: wrap('<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18"/><path d="M15 3v18"/>'),
97
- // Custom
98
- contains: wrap('<path d="M10 3h4v18h-4z"/><path d="M18 8h3v9h-3"/><path d="M6 17H3V8h3"/>'),
99
- empty: wrap('<circle cx="12" cy="12" r="10"/>'),
100
- ends: wrap('<path d="M21 3h-4v18h4z"/><path d="M13 8H3v9h10"/>'),
101
- // Customised
102
- equal: wrap('<line x1="5" x2="19" y1="9" y2="9"/><line x1="5" x2="19" y1="15" y2="15"/>'),
103
- greater: wrap('<path d="m9 18 6-6-6-6"/>'),
104
- // Custom
105
- greaterOrEqual: wrap('<path d="m9 16 6-6-6-6"/><path d="m9 21 6-6"/>'),
106
- // Custom
107
- 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"/>'),
108
- // Custom
109
- 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"/>'),
110
- // Custom
111
- 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"/>'),
112
- // Custom
113
- 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"/>'),
114
- less: wrap('<path d="m15 18-6-6 6-6"/>'),
115
- // Custom
116
- lessOrEqual: wrap('<path d="m15 16-6-6 6-6"/><path d="m15 21-6-6"/>'),
117
- 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"/>'),
118
- // move-horizontal
119
- 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"/>'),
120
- // arrow-left-from-line
121
- moveLeft: wrap('<path d="m9 6-6 6 6 6"/><path d="M3 12h14"/><path d="M21 19V5"/>'),
122
- // arrow-right-from-line
123
- moveRight: wrap('<path d="M3 5v14"/><path d="M21 12H7"/><path d="m15 18 6-6-6-6"/>'),
124
- // Custom
125
- notContains: wrap('<path d="M15 4 9 20"/><path d="M3 8h18v9H3z"/>'),
126
- notEmpty: wrap('<circle cx="12" cy="12" r="10"/><line x1="9" x2="15" y1="15" y2="9"/>'),
127
- notEqual: wrap('<path d="M5 9h14"/><path d="M5 15h14"/><path d="M15 5 9 19"/>'),
128
- // Custom
129
- orderAddAsc: wrap('<path d="M17 21v-8"/><path d="M3 4h6"/><path d="M3 8h9"/><path d="M3 12h10"/><path d="M13 17h8"/>'),
130
- // Custom
131
- orderAddDesc: wrap('<path d="M17 21v-8"/><path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="M13 17h8"/>'),
132
- 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"/>'),
133
- // Custom
134
- 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"/>'),
135
- 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"/>'),
136
- // Custom
137
- orderRemove: wrap('<path d="M3 4h12"/><path d="M3 8h9"/><path d="M3 12h6"/><path d="M13 17h8"/>'),
138
- // Custom
139
- 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"/>'),
140
- // search
141
- search: wrap('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),
142
- // search-x
143
- 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"/>'),
144
- // Custom
145
- starts: wrap('<path d="M3 3h4v18H3z"/><path d="M11 8h10v9H11"/>'),
146
- // tick
147
- tick: wrap('<path d="M20 6 9 17l-5-5"/>'),
148
- // x
149
- x: wrap('<path d="M18 6 6 18"/><path d="m6 6 12 12"/>')
150
- };
151
-
152
- /**
153
- * Close all or only other dropdowns
154
- *
155
- * @param e Event or null to close all others
156
- */
157
- function close(e) {
158
- if (e === void 0) { e = null; }
159
- document.querySelectorAll('div.dtcc-dropdown').forEach(function (el) {
160
- if (e === null || !el.contains(e.target)) {
161
- el._close();
162
- if (!e._closed) {
163
- e._closed = [];
164
- }
165
- e._closed.push(el);
166
- }
167
- });
168
- }
169
- function getContainer(dt, btn) {
170
- return btn.closest('div.dtfh-floatingparent') || dt.table().container();
171
- }
172
- /**
173
- * Position the dropdown relative to the button that activated it, with possible corrections
174
- * to make sure it is visible on the page.
175
- *
176
- * @param dropdown Dropdown element
177
- * @param dt Container DataTable
178
- * @param btn Button the dropdown emanates from
179
- */
180
- function positionDropdown(dropdown, dt, btn) {
181
- var header = btn.closest('div.dt-column-header');
182
- var container = getContainer(dt, btn);
183
- var headerStyle = getComputedStyle(header);
184
- var dropdownWidth = dropdown.offsetWidth;
185
- var position = relativePosition(container, btn);
186
- var left, top;
187
- top = position.top + btn.offsetHeight;
188
- if (headerStyle.flexDirection === 'row-reverse') {
189
- // Icon is on the left of the header - align the left hand sides
190
- left = position.left;
191
- }
192
- else {
193
- // Icon is on the right of the header - align the right hand sides
194
- left = position.left - dropdownWidth + btn.offsetWidth;
195
- }
196
- // Corrections - don't extend past the DataTable to the left and right
197
- var containerWidth = container.offsetWidth;
198
- if (left + dropdownWidth > containerWidth) {
199
- left -= left + dropdownWidth - containerWidth;
200
- }
201
- if (left < 0) {
202
- left = 0;
203
- }
204
- dropdown.style.top = top + 'px';
205
- dropdown.style.left = left + 'px';
206
- }
207
- /**
208
- * Display the dropdown in the document
209
- *
210
- * @param dropdown Dropdown element
211
- * @param dt Container DataTable
212
- * @param btn Button the dropdown emanates from
213
- * @returns Function to call when the dropdown should be removed from the document
214
- */
215
- function attachDropdown(dropdown, dt, btn) {
216
- var dtContainer = getContainer(dt, btn.element());
217
- dropdown._shown = true;
218
- dtContainer.append(dropdown);
219
- positionDropdown(dropdown, dt, btn.element());
220
- btn.element().setAttribute('aria-expanded', 'true');
221
- // Note that this could be called when the dropdown has already been removed from the document
222
- // via another dropdown being shown. This will clean up the event on the next body click.
223
- var removeDropdown = function (e) {
224
- // Not in document, so just clean up the event handler
225
- if (!dropdown._shown) {
226
- document.body.removeEventListener('click', removeDropdown);
227
- return;
228
- }
229
- // If the click is inside the dropdown, ignore it - we don't want to immediately close
230
- if (e.target === dropdown || dropdown.contains(e.target)) {
231
- return;
232
- }
233
- // If there is currently a datetime picker visible on the page, assume that it belongs to
234
- // this dropdown. Don't want to close while operating on the picker.
235
- var datetime = document.querySelector('div.dt-datetime');
236
- if (datetime && (e.target === datetime || datetime.contains(e.target))) {
237
- return;
238
- }
239
- dropdown._close();
240
- document.body.removeEventListener('click', removeDropdown);
241
- };
242
- document.body.addEventListener('click', removeDropdown);
243
- return removeDropdown;
244
- }
245
- /**
246
- * Get the position of an element, relative to a given parent. The origin MUST be under the
247
- * parent's tree.
248
- *
249
- * @param parent Parent element to get position relative to
250
- * @param origin Target element
251
- */
252
- function relativePosition(parent, origin) {
253
- var top = 0;
254
- var left = 0;
255
- while (origin && origin !== parent && origin !== document.body) {
256
- top += origin.offsetTop;
257
- left += origin.offsetLeft;
258
- if (origin.scrollTop) {
259
- left -= origin.scrollTop;
260
- }
261
- if (origin.scrollLeft) {
262
- left -= origin.scrollLeft;
263
- }
264
- origin = origin.offsetParent;
265
- }
266
- return {
267
- top: top,
268
- left: left
269
- };
270
- }
271
- /**
272
- * Function that will provide the keyboard navigation for the dropdown
273
- *
274
- * @param dropdown Dropdown element in question
275
- * @returns Function that can be bound to `keypress`
276
- */
277
- function focusCapture(dropdown, host) {
278
- return function (e) {
279
- // Do nothing if not shown
280
- if (!dropdown._shown) {
281
- return;
282
- }
283
- // Focus trap for tab key
284
- var elements = Array.from(dropdown.querySelectorAll('a, button, input, select'));
285
- var active = document.activeElement;
286
- // An escape key should close the dropdown
287
- if (e.key === 'Escape') {
288
- dropdown._close();
289
- host.focus(); // Restore focus to the host
290
- return;
291
- }
292
- else if (e.key !== 'Tab' || elements.length === 0) {
293
- // Anything other than tab we aren't interested in from here
294
- return;
295
- }
296
- if (!elements.includes(active)) {
297
- // If new focus is not inside the popover we want to drag it back in
298
- elements[0].focus();
299
- e.preventDefault();
300
- }
301
- else if (e.shiftKey) {
302
- // Reverse tabbing order when shift key is pressed
303
- if (active === elements[0]) {
304
- elements[elements.length - 1].focus();
305
- e.preventDefault();
306
- }
307
- }
308
- else {
309
- if (active === elements[elements.length - 1]) {
310
- elements[0].focus();
311
- e.preventDefault();
312
- }
313
- }
314
- };
315
- }
316
- var dropdownContent = {
317
- classes: {
318
- container: 'dtcc-dropdown',
319
- liner: 'dtcc-dropdown-liner'
320
- },
321
- defaults: {
322
- className: 'dropdown',
323
- content: [],
324
- icon: 'menu',
325
- text: 'More...'
326
- },
327
- init: function (config) {
328
- var dt = this.dt();
329
- var dropdown = createElement('div', dropdownContent.classes.container, '', [
330
- createElement('div', dropdownContent.classes.liner)
331
- ]);
332
- dropdown._shown = false;
333
- dropdown._close = function () {
334
- dropdown.remove();
335
- dropdown._shown = false;
336
- btn.element().setAttribute('aria-expanded', 'false');
337
- };
338
- dropdown.setAttribute('role', 'dialog');
339
- dropdown.setAttribute('aria-label', dt.i18n('columnControl.dropdown', config.text));
340
- // When FixedHeader is used, the transition between states messes up positioning, so if
341
- // shown we just reattach the dropdown.
342
- dt.on('fixedheader-mode', function () {
343
- if (dropdown._shown) {
344
- attachDropdown(dropdown, dt, config._parents ? config._parents[0] : btn);
345
- }
346
- });
347
- // A liner element allows more styling options, so the contents go inside this
348
- var liner = dropdown.childNodes[0];
349
- var btn = new Button(dt, this)
350
- .text(dt.i18n('columnControl.dropdown', config.text))
351
- .icon(config.icon)
352
- .className(config.className)
353
- .dropdownDisplay(liner)
354
- .handler(function (e) {
355
- // Do nothing if our dropdown was just closed as part of the event (i.e. allow
356
- // the button to toggle it closed)
357
- if (e._closed && e._closed.includes(dropdown)) {
358
- return;
359
- }
360
- attachDropdown(dropdown, dt, config._parents ? config._parents[0] : btn);
361
- // When activated using a key - auto focus on the first item in the popover
362
- var focusable = dropdown.querySelector('input, a, button');
363
- if (focusable && e.type === 'keypress') {
364
- focusable.focus();
365
- }
366
- });
367
- btn.element().setAttribute('aria-haspopup', 'dialog');
368
- btn.element().setAttribute('aria-expanded', 'false');
369
- // Add the content for the dropdown
370
- for (var i = 0; i < config.content.length; i++) {
371
- var content = this.resolve(config.content[i]);
372
- // For nested items we need to keep a reference to the top level so the sub-levels
373
- // can communicate back - e.g. active or positioned relative to that top level.
374
- if (!content.config._parents) {
375
- content.config._parents = [];
376
- }
377
- content.config._parents.push(btn);
378
- var el = content.plugin.init.call(this, content.config);
379
- liner.appendChild(el);
380
- }
381
- // For nested dropdowns, add an extra icon element to show that it will dropdown further
382
- if (config._parents && config._parents.length) {
383
- btn.extra('chevronRight');
384
- }
385
- // Reposition if needed
386
- dt.on('columns-reordered', function () {
387
- positionDropdown(dropdown, dt, btn.element());
388
- });
389
- // Focus capture events
390
- var capture = focusCapture(dropdown, btn.element());
391
- document.body.addEventListener('keydown', capture);
392
- dt.on('destroy', function () {
393
- document.body.removeEventListener('keydown', capture);
394
- });
395
- return btn.element();
396
- }
397
- };
398
-
399
- var _namespace = 0;
400
- var Button = /** @class */ (function () {
401
- /**
402
- * Create a new button for use in ColumnControl contents. Buttons created by this class can be
403
- * used at the top level in the header or in a dropdown.
404
- */
405
- function Button(dt, host) {
406
- this._s = {
407
- active: false,
408
- activeList: [],
409
- buttonClick: null,
410
- dt: null,
411
- enabled: true,
412
- host: null,
413
- label: '',
414
- namespace: '',
415
- value: null
416
- };
417
- this._s.dt = dt;
418
- this._s.host = host;
419
- this._dom = {
420
- button: createElement('button', Button.classes.container),
421
- dropdownDisplay: null,
422
- extra: createElement('span', 'dtcc-button-extra'),
423
- icon: createElement('span', 'dtcc-button-icon'),
424
- state: createElement('span', 'dtcc-button-state'),
425
- text: createElement('span', 'dtcc-button-text')
426
- };
427
- this._dom.button.setAttribute('type', 'button');
428
- this._dom.button.append(this._dom.icon);
429
- this._dom.button.append(this._dom.text);
430
- this._dom.button.append(this._dom.state);
431
- this._dom.button.append(this._dom.extra);
432
- // Default state is enabled
433
- this.enable(true);
434
- }
435
- Button.prototype.active = function (active) {
436
- if (active === undefined) {
437
- return this._s.active;
438
- }
439
- this._s.active = active;
440
- this._checkActive();
441
- return this;
442
- };
443
- /**
444
- * A button can be marked as active by any of its sub-buttons (i.e. if it is a dropdown)
445
- * and each one needs to be able to enable this button without effecting the active state
446
- * trigged by any other sub-buttons. This method provides a way to do that.
447
- *
448
- * @param unique Unique id for the activate state
449
- * @param active If it is active
450
- * @returns Button instance
451
- */
452
- Button.prototype.activeList = function (unique, active) {
453
- this._s.activeList[unique] = active;
454
- this._checkActive();
455
- return this;
456
- };
457
- /**
458
- * Scan over the dropdown element looking for any visible content. If there isn't any then
459
- * we hide this button.
460
- *
461
- * @returns Button instance
462
- */
463
- Button.prototype.checkDisplay = function () {
464
- var visible = 0;
465
- var children = this._dom.dropdownDisplay.childNodes;
466
- for (var i = 0; i < children.length; i++) {
467
- // No need to getComputedStyle since if a button is hidden, it was done with JS writing
468
- // to style.display, so we can check against that.
469
- if (children[i].style.display !== 'none') {
470
- visible++;
471
- }
472
- }
473
- if (visible === 0) {
474
- this._dom.button.style.display = 'none';
475
- }
476
- return this;
477
- };
478
- /**
479
- * Set the class name for the button
480
- *
481
- * @param className Class name
482
- * @returns Button instance
483
- */
484
- Button.prototype.className = function (className) {
485
- this._dom.button.classList.add('dtcc-button_' + className);
486
- return this;
487
- };
488
- /**
489
- * Destroy the button, cleaning up event listeners
490
- */
491
- Button.prototype.destroy = function () {
492
- if (this._s.buttonClick) {
493
- this._dom.button.removeEventListener('click', this._s.buttonClick);
494
- this._dom.button.removeEventListener('keypress', this._s.buttonClick);
495
- }
496
- this._s.host.destroyRemove(this);
497
- };
498
- /**
499
- * Relevant for drop downs only. When a button in a dropdown is hidden, we might want to
500
- * hide the host button as well (if it has nothing else to show). For that we need to know
501
- * what the dropdown element is.
502
- *
503
- * @param el Element that can be used for telling us about drop down elements.
504
- * @returns Button instance
505
- */
506
- Button.prototype.dropdownDisplay = function (el) {
507
- this._dom.dropdownDisplay = el;
508
- return this;
509
- };
510
- /**
511
- * Get the DOM Button element to attach into the document
512
- *
513
- * @returns The Button element
514
- */
515
- Button.prototype.element = function () {
516
- return this._dom.button;
517
- };
518
- Button.prototype.enable = function (enable) {
519
- if (enable === undefined) {
520
- return this._s.enabled;
521
- }
522
- this._dom.button.classList.toggle('dtcc-button_disabled', !enable);
523
- this._s.enabled = enable;
524
- return this;
525
- };
526
- /**
527
- * Set the extra information icon
528
- *
529
- * @param icon Icon name
530
- * @returns Button instance
531
- */
532
- Button.prototype.extra = function (icon) {
533
- this._dom.extra.innerHTML = icon ? icons[icon] : '';
534
- return this;
535
- };
536
- /**
537
- * Set the event handler for when the button is activated
538
- *
539
- * @param fn Event handler
540
- * @returns Button instance
541
- */
542
- Button.prototype.handler = function (fn) {
543
- var _this = this;
544
- var buttonClick = function (e) {
545
- // Close any dropdowns which are already open
546
- close(e);
547
- // Stop bubbling to the DataTables default header, which might still be enabled
548
- e.stopPropagation();
549
- e.preventDefault();
550
- if (_this._s.enabled) {
551
- fn(e);
552
- }
553
- };
554
- this._s.buttonClick = buttonClick;
555
- this._s.namespace = 'dtcc-' + _namespace++;
556
- this._dom.button.addEventListener('click', buttonClick);
557
- this._dom.button.addEventListener('keypress', buttonClick);
558
- this._s.host.destroyAdd(this);
559
- return this;
560
- };
561
- /**
562
- * Set the icon to display in the button
563
- *
564
- * @param icon Icon name
565
- * @returns Button instance
566
- */
567
- Button.prototype.icon = function (icon) {
568
- this._dom.icon.innerHTML = icon ? icons[icon] : '';
569
- return this;
570
- };
571
- Button.prototype.text = function (text) {
572
- if (text === undefined) {
573
- return this._s.label;
574
- }
575
- this._dom.text.innerHTML = text;
576
- this._s.label = text; // for fast retrieval
577
- this._dom.button.setAttribute('aria-label', text);
578
- return this;
579
- };
580
- Button.prototype.value = function (val) {
581
- if (val === undefined) {
582
- return this._s.value;
583
- }
584
- this._s.value = val;
585
- return this;
586
- };
587
- /**
588
- * Check if anything is making this button active
589
- *
590
- * @returns Self for chaining
591
- */
592
- Button.prototype._checkActive = function () {
593
- if (this._s.active === true || Object.values(this._s.activeList).includes(true)) {
594
- this._dom.state.innerHTML = icons.tick;
595
- this._dom.button.classList.add('dtcc-button_active');
596
- }
597
- else {
598
- this._dom.state.innerHTML = '';
599
- this._dom.button.classList.remove('dtcc-button_active');
600
- }
601
- return this;
602
- };
603
- Button.classes = {
604
- container: 'dtcc-button'
605
- };
606
- return Button;
607
- }());
608
-
609
- var CheckList = /** @class */ (function () {
610
- /**
611
- * Container for a list of buttons
612
- */
613
- function CheckList(dt, host, opts) {
614
- var _this = this;
615
- this._s = {
616
- buttons: [],
617
- dt: null,
618
- handler: function () { },
619
- host: null,
620
- search: ''
621
- };
622
- this._s.dt = dt;
623
- this._s.host = host;
624
- this._dom = {
625
- buttons: createElement('div', 'dtcc-list-buttons'),
626
- container: createElement('div', CheckList.classes.container),
627
- controls: createElement('div', 'dtcc-list-controls'),
628
- empty: createElement('div', 'dtcc-list-empty', dt.i18n('columnControl.list.empty', 'No options')),
629
- title: createElement('div', 'dtcc-list-title'),
630
- selectAll: createElement('button', 'dtcc-list-selectAll', dt.i18n('columnControl.list.all', 'Select all')),
631
- selectAllCount: createElement('span'),
632
- selectNone: createElement('button', 'dtcc-list-selectNone', dt.i18n('columnControl.list.none', 'Deselect')),
633
- selectNoneCount: createElement('span'),
634
- search: createElement('input', CheckList.classes.input)
635
- };
636
- var dom = this._dom;
637
- dom.search.setAttribute('type', 'text');
638
- dom.container.append(dom.title);
639
- dom.container.append(dom.controls);
640
- dom.container.append(dom.empty);
641
- dom.container.append(dom.buttons);
642
- if (opts.select) {
643
- dom.controls.append(dom.selectAll);
644
- dom.controls.append(dom.selectNone);
645
- dom.selectAll.append(dom.selectAllCount);
646
- dom.selectNone.append(dom.selectNoneCount);
647
- dom.selectAll.setAttribute('type', 'button');
648
- dom.selectNone.setAttribute('type', 'button');
649
- }
650
- // Events
651
- var searchInput = function () {
652
- _this._s.search = dom.search.value;
653
- _this._redraw();
654
- };
655
- var selectAllClick = function (e) {
656
- _this.selectAll();
657
- _this._s.handler(e, null, _this._s.buttons, true);
658
- _this._updateCount();
659
- };
660
- var selectNoneClick = function (e) {
661
- _this.selectNone();
662
- _this._s.handler(e, null, _this._s.buttons, true);
663
- _this._updateCount();
664
- };
665
- if (opts.search) {
666
- dom.controls.append(dom.search);
667
- dom.search.setAttribute('placeholder', dt.i18n('columnControl.list.search', 'Search...'));
668
- dom.search.addEventListener('input', searchInput);
669
- }
670
- dom.selectAll.addEventListener('click', selectAllClick);
671
- dom.selectNone.addEventListener('click', selectNoneClick);
672
- dt.on('destroy', function () {
673
- dom.selectAll.removeEventListener('click', selectAllClick);
674
- dom.selectNone.removeEventListener('click', selectNoneClick);
675
- dom.search.removeEventListener('input', searchInput);
676
- });
677
- }
678
- /**
679
- * Add one or more buttons to the list
680
- *
681
- * @param options Configuration for the button(s) to add
682
- * @returns Self for chaining
683
- */
684
- CheckList.prototype.add = function (options, update) {
685
- var _this = this;
686
- if (!Array.isArray(options)) {
687
- options = [options];
688
- }
689
- var _loop_1 = function (i) {
690
- var option = options[i];
691
- var btn = new Button(this_1._s.dt, this_1._s.host)
692
- .active(option.active || false)
693
- .handler(function (e) {
694
- _this._s.handler(e, btn, _this._s.buttons, true);
695
- _this._updateCount();
696
- })
697
- .icon(option.icon || '')
698
- .text(option.label !== ''
699
- ? option.label
700
- : this_1._s.dt.i18n('columnControl.list.empty', 'Empty'))
701
- .value(option.value);
702
- if (option.label === '') {
703
- btn.className('empty');
704
- }
705
- this_1._s.buttons.push(btn);
706
- };
707
- var this_1 = this;
708
- for (var i = 0; i < options.length; i++) {
709
- _loop_1(i);
710
- }
711
- var count = this._s.buttons.length;
712
- if (update === true || update === undefined) {
713
- this._dom.selectAllCount.innerHTML = count ? '(' + count + ')' : '';
714
- this._redraw();
715
- }
716
- return this;
717
- };
718
- /**
719
- * Find a button with a given value
720
- *
721
- * @param val Value to search for
722
- * @returns Found button
723
- */
724
- CheckList.prototype.button = function (val) {
725
- var buttons = this._s.buttons;
726
- for (var i = 0; i < buttons.length; i++) {
727
- if (buttons[i].value() === val) {
728
- return buttons[i];
729
- }
730
- }
731
- return null;
732
- };
733
- /**
734
- * Remove all buttons from the list
735
- *
736
- * @returns Self for chaining
737
- */
738
- CheckList.prototype.clear = function () {
739
- // Clean up the buttons
740
- for (var i = 0; i < this._s.buttons.length; i++) {
741
- this._s.buttons[i].destroy();
742
- }
743
- // Then empty them out
744
- this._dom.buttons.replaceChildren();
745
- this._s.buttons.length = 0;
746
- return this;
747
- };
748
- /**
749
- * Get the DOM container element to attach into the document
750
- *
751
- * @returns Container
752
- */
753
- CheckList.prototype.element = function () {
754
- return this._dom.container;
755
- };
756
- /**
757
- * Set the event handler for what happens when a button is clicked
758
- *
759
- * @param fn Event handler
760
- */
761
- CheckList.prototype.handler = function (fn) {
762
- this._s.handler = fn;
763
- return this;
764
- };
765
- /**
766
- * Indicate that this is a search control and should listen for corresponding events
767
- *
768
- * @param dt DataTable instance
769
- * @param idx Column index
770
- */
771
- CheckList.prototype.searchListener = function (dt) {
772
- var _this = this;
773
- // Column control search clearing (column().columnControl.searchClear() method)
774
- dt.on('cc-search-clear', function (e, colIdx) {
775
- if (colIdx === _this._s.host.idx()) {
776
- _this.selectNone();
777
- _this._s.handler(e, null, _this._s.buttons, false);
778
- _this._s.search = '';
779
- _this._dom.search.value = '';
780
- _this._redraw();
781
- _this._updateCount();
782
- }
783
- });
784
- return this;
785
- };
786
- /**
787
- * Select all buttons
788
- *
789
- * @returns Self for chaining
790
- */
791
- CheckList.prototype.selectAll = function () {
792
- for (var i = 0; i < this._s.buttons.length; i++) {
793
- this._s.buttons[i].active(true);
794
- }
795
- return this;
796
- };
797
- /**
798
- * Deselect all buttons
799
- *
800
- * @returns Self for chaining
801
- */
802
- CheckList.prototype.selectNone = function () {
803
- for (var i = 0; i < this._s.buttons.length; i++) {
804
- this._s.buttons[i].active(false);
805
- }
806
- return this;
807
- };
808
- /**
809
- * Set the list's title
810
- *
811
- * @param title Display title
812
- * @returns Button instance
813
- */
814
- CheckList.prototype.title = function (title) {
815
- this._dom.title.innerHTML = title;
816
- return this;
817
- };
818
- CheckList.prototype.values = function (values) {
819
- var i;
820
- var result = [];
821
- var buttons = this._s.buttons;
822
- if (values !== undefined) {
823
- for (i = 0; i < buttons.length; i++) {
824
- if (values.includes(buttons[i].value())) {
825
- buttons[i].active(true);
826
- }
827
- }
828
- this._updateCount();
829
- return this;
830
- }
831
- for (i = 0; i < buttons.length; i++) {
832
- if (buttons[i].active()) {
833
- result.push(buttons[i].value());
834
- }
835
- }
836
- return result;
837
- };
838
- /**
839
- * Update the deselect counter
840
- */
841
- CheckList.prototype._updateCount = function () {
842
- var count = this.values().length;
843
- this._dom.selectNoneCount.innerHTML = count ? '(' + count + ')' : '';
844
- };
845
- /**
846
- * Add the buttons to the page - taking into account filtering
847
- */
848
- CheckList.prototype._redraw = function () {
849
- var buttons = this._s.buttons;
850
- var el = this._dom.buttons;
851
- var searchTerm = this._s.search.toLowerCase();
852
- el.replaceChildren();
853
- for (var i = 0; i < buttons.length; i++) {
854
- var btn = buttons[i];
855
- if (!searchTerm ||
856
- btn
857
- .text()
858
- .toLowerCase()
859
- .includes(searchTerm)) {
860
- el.appendChild(btn.element());
861
- }
862
- }
863
- this._dom.empty.style.display = buttons.length === 0 ? 'block' : 'none';
864
- el.style.display = buttons.length > 0 ? 'block' : 'none';
865
- };
866
- CheckList.classes = {
867
- container: 'dtcc-list',
868
- input: 'dtcc-list-search'
869
- };
870
- return CheckList;
871
- }());
872
-
873
- var colVis = {
874
- defaults: {
875
- className: 'colVis',
876
- columns: '',
877
- search: false,
878
- select: false,
879
- title: 'Column visibility'
880
- },
881
- init: function (config) {
882
- var dt = this.dt();
883
- var checkList = new CheckList(dt, this, {
884
- search: config.search,
885
- select: config.select
886
- })
887
- .title(dt.i18n('columnControl.colVis', config.title))
888
- .handler(function (e, btn, buttons) {
889
- if (btn) {
890
- btn.active(!btn.active());
891
- }
892
- apply(buttons);
893
- });
894
- // Need to apply in a loop to allow for select all / select none
895
- var apply = function (buttons) {
896
- for (var i = 0; i < buttons.length; i++) {
897
- var btn = buttons[i];
898
- var idx = btn.value();
899
- var col = dt.column(idx);
900
- if (btn.active() && !col.visible()) {
901
- col.visible(true);
902
- }
903
- else if (!btn.active() && col.visible()) {
904
- col.visible(false);
905
- }
906
- }
907
- };
908
- var rebuild = function () {
909
- var columns = dt.columns(config.columns);
910
- columns.every(function () {
911
- checkList.add({
912
- active: this.visible(),
913
- label: this.title(),
914
- value: this.index()
915
- });
916
- });
917
- };
918
- rebuild();
919
- dt.on('column-visibility', function (e, s, colIdx, state) {
920
- var btn = checkList.button(colIdx);
921
- if (btn) {
922
- btn.active(state);
923
- }
924
- });
925
- dt.on('columns-reordered', function (e, details) {
926
- checkList.clear();
927
- rebuild();
928
- });
929
- return checkList.element();
930
- }
931
- };
932
-
933
- var colVisDropdown = {
934
- defaults: {
935
- className: 'colVis',
936
- columns: '',
937
- search: false,
938
- select: false,
939
- text: 'Column visibility',
940
- title: 'Column visibility'
941
- },
942
- extend: function (config) {
943
- var dt = this.dt();
944
- return {
945
- extend: 'dropdown',
946
- icon: 'columns',
947
- text: dt.i18n('columnControl.colVisDropdown', config.text),
948
- content: [
949
- Object.assign(config, {
950
- extend: 'colVis'
951
- })
952
- ]
953
- };
954
- }
955
- };
956
-
957
- var reorder = {
958
- defaults: {
959
- className: 'reorder',
960
- icon: 'move',
961
- text: 'Reorder columns'
962
- },
963
- init: function (config) {
964
- var _this = this;
965
- var dt = this.dt();
966
- var btn = new Button(dt, this)
967
- .text(dt.i18n('columnControl.reorder', config.text))
968
- .icon(config.icon)
969
- .className(config.className);
970
- // The event handling for this is done in ColReorder._addListener - no event
971
- // handler needed here for click / drag
972
- if (this.idx() === 0) {
973
- btn.enable(false);
974
- }
975
- dt.on('columns-reordered', function (e, details) {
976
- btn.enable(_this.idx() > 0);
977
- });
978
- // If ColReorder wasn't initialised on this DataTable, then we need to add it
979
- if (!dt.init().colReorder) {
980
- new DataTable.ColReorder(dt, {});
981
- }
982
- return btn.element();
983
- }
984
- };
985
-
986
- var reorderLeft = {
987
- defaults: {
988
- className: 'reorderLeft',
989
- icon: 'moveLeft',
990
- text: 'Move column left'
991
- },
992
- init: function (config) {
993
- var _this = this;
994
- var dt = this.dt();
995
- var btn = new Button(dt, this)
996
- .text(dt.i18n('columnControl.reorderLeft', config.text))
997
- .icon(config.icon)
998
- .className(config.className)
999
- .handler(function () {
1000
- var idx = _this.idx();
1001
- // TODO account for visibility
1002
- if (idx > 0) {
1003
- dt.colReorder.move(idx, idx - 1);
1004
- }
1005
- });
1006
- if (this.idx() === 0) {
1007
- btn.enable(false);
1008
- }
1009
- dt.on('columns-reordered', function (e, details) {
1010
- btn.enable(_this.idx() > 0);
1011
- });
1012
- return btn.element();
1013
- }
1014
- };
1015
-
1016
- var reorderRight = {
1017
- defaults: {
1018
- className: 'reorderRight',
1019
- icon: 'moveRight',
1020
- text: 'Move column right'
1021
- },
1022
- init: function (config) {
1023
- var _this = this;
1024
- var dt = this.dt();
1025
- var btn = new Button(dt, this)
1026
- .text(dt.i18n('columnControl.reorderRight', config.text))
1027
- .icon(config.icon)
1028
- .className(config.className)
1029
- .handler(function () {
1030
- var idx = _this.idx();
1031
- if (idx < dt.columns().count() - 1) {
1032
- dt.colReorder.move(idx, idx + 1);
1033
- }
1034
- });
1035
- if (this.idx() === dt.columns().count() - 1) {
1036
- btn.enable(false);
1037
- }
1038
- dt.on('columns-reordered', function (e, details) {
1039
- btn.enable(_this.idx() < dt.columns().count() - 1);
1040
- });
1041
- return btn.element();
1042
- }
1043
- };
1044
-
1045
- var order = {
1046
- defaults: {
1047
- className: 'order',
1048
- iconAsc: 'orderAsc',
1049
- iconDesc: 'orderDesc',
1050
- iconNone: 'orderNone',
1051
- statusOnly: false,
1052
- text: 'Toggle ordering'
1053
- },
1054
- init: function (config) {
1055
- var _this = this;
1056
- var dt = this.dt();
1057
- var btn = new Button(dt, this)
1058
- .text(dt.i18n('columnControl.order', config.text))
1059
- .icon('orderAsc')
1060
- .className(config.className);
1061
- if (!config.statusOnly) {
1062
- dt.order.listener(btn.element(), DataTable.versionCheck('2.3.2') ? function () { return [_this.idx()]; } : this.idx(), function () { });
1063
- }
1064
- dt.on('order', function (e, s, order) {
1065
- var found = order.find(function (o) { return o.col === _this.idx(); });
1066
- if (!found) {
1067
- btn.active(false).icon(config.iconNone);
1068
- }
1069
- else if (found.dir === 'asc') {
1070
- btn.active(true).icon(config.iconAsc);
1071
- }
1072
- else if (found.dir === 'desc') {
1073
- btn.active(true).icon(config.iconDesc);
1074
- }
1075
- });
1076
- return btn.element();
1077
- }
1078
- };
1079
-
1080
- var orderAddAsc = {
1081
- defaults: {
1082
- className: 'orderAddAsc',
1083
- icon: 'orderAddAsc',
1084
- text: 'Add Sort Ascending'
1085
- },
1086
- init: function (config) {
1087
- var _this = this;
1088
- var dt = this.dt();
1089
- var btn = new Button(dt, this)
1090
- .text(dt.i18n('columnControl.orderAddAsc', config.text))
1091
- .icon(config.icon)
1092
- .className(config.className)
1093
- .handler(function () {
1094
- var order = dt.order();
1095
- order.push([_this.idx(), 'asc']);
1096
- dt.draw();
1097
- });
1098
- dt.on('order', function (e, s, order) {
1099
- var found = order.some(function (o) { return o.col === _this.idx(); });
1100
- btn.enable(!found);
1101
- });
1102
- return btn.element();
1103
- }
1104
- };
1105
-
1106
- var orderAddDesc = {
1107
- defaults: {
1108
- className: 'orderAddDesc',
1109
- icon: 'orderAddDesc',
1110
- text: 'Add Sort Descending'
1111
- },
1112
- init: function (config) {
1113
- var _this = this;
1114
- var dt = this.dt();
1115
- var btn = new Button(dt, this)
1116
- .text(dt.i18n('columnControl.orderAddDesc', config.text))
1117
- .icon(config.icon)
1118
- .className(config.className)
1119
- .handler(function () {
1120
- var order = dt.order();
1121
- order.push([_this.idx(), 'desc']);
1122
- dt.draw();
1123
- });
1124
- dt.on('order', function (e, s, order) {
1125
- var found = order.some(function (o) { return o.col === _this.idx(); });
1126
- btn.enable(!found);
1127
- });
1128
- return btn.element();
1129
- }
1130
- };
1131
-
1132
- var orderAsc = {
1133
- defaults: {
1134
- className: 'orderAsc',
1135
- icon: 'orderAsc',
1136
- text: 'Sort Ascending'
1137
- },
1138
- init: function (config) {
1139
- var _this = this;
1140
- var dt = this.dt();
1141
- var btn = new Button(dt, this)
1142
- .text(dt.i18n('columnControl.orderAsc', config.text))
1143
- .icon(config.icon)
1144
- .className(config.className)
1145
- .handler(function () {
1146
- _this.dt()
1147
- .order([
1148
- {
1149
- idx: _this.idx(),
1150
- dir: 'asc'
1151
- }
1152
- ])
1153
- .draw();
1154
- });
1155
- dt.on('order', function (e, s, order) {
1156
- var found = order.some(function (o) { return o.col === _this.idx() && o.dir === 'asc'; });
1157
- btn.active(found);
1158
- });
1159
- return btn.element();
1160
- }
1161
- };
1162
-
1163
- var orderClear = {
1164
- defaults: {
1165
- className: 'orderClear',
1166
- icon: 'orderClear',
1167
- text: 'Clear sort'
1168
- },
1169
- init: function (config) {
1170
- var dt = this.dt();
1171
- var btn = new Button(dt, this)
1172
- .text(dt.i18n('columnControl.orderClear', config.text))
1173
- .icon(config.icon)
1174
- .className(config.className)
1175
- .handler(function () {
1176
- dt.order([]).draw();
1177
- });
1178
- dt.on('order', function (e, s, order) {
1179
- btn.enable(order.length > 0);
1180
- });
1181
- if (dt.order().length === 0) {
1182
- btn.enable(false);
1183
- }
1184
- return btn.element();
1185
- }
1186
- };
1187
-
1188
- var orderDesc = {
1189
- defaults: {
1190
- className: 'orderDesc',
1191
- icon: 'orderDesc',
1192
- text: 'Sort Descending'
1193
- },
1194
- init: function (config) {
1195
- var _this = this;
1196
- var dt = this.dt();
1197
- var btn = new Button(dt, this)
1198
- .text(dt.i18n('columnControl.orderDesc', config.text))
1199
- .icon(config.icon)
1200
- .className(config.className)
1201
- .handler(function () {
1202
- _this.dt()
1203
- .order([
1204
- {
1205
- idx: _this.idx(),
1206
- dir: 'desc'
1207
- }
1208
- ])
1209
- .draw();
1210
- });
1211
- dt.on('order', function (e, s, order) {
1212
- var found = order.some(function (o) { return o.col === _this.idx() && o.dir === 'desc'; });
1213
- btn.active(found);
1214
- });
1215
- return btn.element();
1216
- }
1217
- };
1218
-
1219
- var orderRemove = {
1220
- defaults: {
1221
- className: 'orderRemove',
1222
- icon: 'orderRemove',
1223
- text: 'Remove from sort'
1224
- },
1225
- init: function (config) {
1226
- var _this = this;
1227
- var dt = this.dt();
1228
- var btn = new Button(dt, this)
1229
- .text(dt.i18n('columnControl.orderRemove', config.text))
1230
- .icon(config.icon)
1231
- .className(config.className)
1232
- .handler(function () {
1233
- // Remove the current column from the ordering array, then reorder the table
1234
- var order = dt.order();
1235
- var idx = order.findIndex(function (o) { return o[0] === _this.idx(); });
1236
- order.splice(idx, 1);
1237
- dt.order(order).draw();
1238
- });
1239
- dt.on('order', function (e, s, order) {
1240
- var found = order.some(function (o) { return o.col === _this.idx(); });
1241
- btn.enable(found);
1242
- });
1243
- btn.enable(false);
1244
- return btn.element();
1245
- }
1246
- };
1247
-
1248
- var orderStatus = {
1249
- defaults: {
1250
- className: 'order',
1251
- iconAsc: 'orderAsc',
1252
- iconDesc: 'orderDesc',
1253
- iconNone: 'orderNone',
1254
- statusOnly: true,
1255
- text: 'Sort status'
1256
- },
1257
- extend: function (config) {
1258
- return Object.assign(config, { extend: 'order' });
1259
- }
1260
- };
1261
-
1262
- /**
1263
- * Add an item to the grouping structure
1264
- *
1265
- * @param dt DataTable API instance
1266
- * @param dataSrc Grouping data point to add
1267
- * @returns Grouping array
1268
- */
1269
- function rowGroupAdd$1(dt, dataSrc) {
1270
- var applied = rowGroupApplied(dt);
1271
- var idx = applied.indexOf(dataSrc);
1272
- if (idx === -1) {
1273
- applied.push(dataSrc);
1274
- dt.rowGroup().dataSrc(applied);
1275
- }
1276
- return applied;
1277
- }
1278
- /**
1279
- * Always want an array return
1280
- *
1281
- * @param dt DataTable API instance
1282
- * @returns
1283
- */
1284
- function rowGroupApplied(dt) {
1285
- var applied = dt.rowGroup().dataSrc();
1286
- return Array.isArray(applied)
1287
- ? applied
1288
- : [applied];
1289
- }
1290
- /**
1291
- * Remove all grouping
1292
- *
1293
- * @param dt DataTable API instance
1294
- */
1295
- function rowGroupClear$1(dt) {
1296
- dt.rowGroup().dataSrc([]);
1297
- }
1298
- /**
1299
- * Remove an item from the grouping structure
1300
- *
1301
- * @param dt DataTable API instance
1302
- * @param dataSrc Grouping data point to remove
1303
- * @returns Grouping array
1304
- */
1305
- function rowGroupRemove$1(dt, dataSrc) {
1306
- var applied = rowGroupApplied(dt);
1307
- var idx = applied.indexOf(dataSrc);
1308
- if (idx !== -1) {
1309
- applied.splice(idx, 1);
1310
- dt.rowGroup().dataSrc(applied);
1311
- }
1312
- return applied;
1313
- }
1314
- var rowGroup = {
1315
- defaults: {
1316
- className: 'rowGroup',
1317
- icon: 'groupTop',
1318
- order: true,
1319
- text: 'Group rows'
1320
- },
1321
- init: function (config) {
1322
- var _this = this;
1323
- var dt = this.dt();
1324
- var btn = new Button(dt, this)
1325
- .text(dt.i18n('columnControl.rowGroup', config.text))
1326
- .icon(config.icon)
1327
- .className(config.className)
1328
- .handler(function () {
1329
- var dataSrc = dt.column(_this.idx()).dataSrc();
1330
- if (btn.active()) {
1331
- // Grouping is active - remove
1332
- rowGroupRemove$1(dt, dataSrc);
1333
- }
1334
- else {
1335
- // No grouping by this column yet, set it
1336
- rowGroupClear$1(dt);
1337
- rowGroupAdd$1(dt, dataSrc);
1338
- if (config.order !== false) {
1339
- dt.order([_this.idx(), 'asc']);
1340
- }
1341
- }
1342
- dt.draw();
1343
- });
1344
- // Show as active when grouping is applied
1345
- dt.on('rowgroup-datasrc', function () {
1346
- var applied = rowGroupApplied(dt);
1347
- var ours = dt.column(_this.idx()).dataSrc();
1348
- btn.active(applied.includes(ours));
1349
- });
1350
- return btn.element();
1351
- }
1352
- };
1353
-
1354
- var rowGroupAdd = {
1355
- defaults: {
1356
- className: 'rowGroupAdd',
1357
- icon: 'groupAdd',
1358
- order: true,
1359
- text: 'Add to grouping'
1360
- },
1361
- init: function (config) {
1362
- var _this = this;
1363
- var dt = this.dt();
1364
- var btn = new Button(dt, this)
1365
- .text(dt.i18n('columnControl.rowGroup', config.text))
1366
- .icon(config.icon)
1367
- .className(config.className)
1368
- .handler(function () {
1369
- var dataSrc = dt.column(_this.idx()).dataSrc();
1370
- if (btn.enable()) {
1371
- // No grouping by this column yet, add it
1372
- rowGroupAdd$1(dt, dataSrc);
1373
- }
1374
- dt.draw();
1375
- });
1376
- // Show as active when grouping is applied
1377
- dt.on('rowgroup-datasrc', function () {
1378
- var applied = rowGroupApplied(dt);
1379
- var ours = dt.column(_this.idx()).dataSrc();
1380
- btn.enable(!applied.includes(ours));
1381
- });
1382
- return btn.element();
1383
- }
1384
- };
1385
-
1386
- var rowGroupClear = {
1387
- defaults: {
1388
- className: 'rowGroupClear',
1389
- icon: 'groupClear',
1390
- text: 'Clear all grouping'
1391
- },
1392
- init: function (config) {
1393
- var dt = this.dt();
1394
- var btn = new Button(dt, this)
1395
- .text(dt.i18n('columnControl.rowGroup', config.text))
1396
- .icon(config.icon)
1397
- .className(config.className)
1398
- .handler(function () {
1399
- rowGroupClear$1(dt);
1400
- dt.draw();
1401
- });
1402
- // Show as active when any grouping is applied
1403
- dt.on('rowgroup-datasrc', function () {
1404
- btn.enable(rowGroupApplied(dt).length > 0);
1405
- });
1406
- // Default status
1407
- btn.enable(rowGroupApplied(dt).length > 0);
1408
- return btn.element();
1409
- }
1410
- };
1411
-
1412
- var rowGroupRemove = {
1413
- defaults: {
1414
- className: 'rowGroupRemove',
1415
- icon: 'groupRemove',
1416
- order: true,
1417
- text: 'Remove from grouping'
1418
- },
1419
- init: function (config) {
1420
- var _this = this;
1421
- var dt = this.dt();
1422
- var btn = new Button(dt, this)
1423
- .text(dt.i18n('columnControl.rowGroup', config.text))
1424
- .icon(config.icon)
1425
- .className(config.className)
1426
- .handler(function () {
1427
- var dataSrc = dt.column(_this.idx()).dataSrc();
1428
- if (btn.enable()) {
1429
- // Grouping is active - remove
1430
- rowGroupRemove$1(dt, dataSrc);
1431
- dt.draw();
1432
- }
1433
- });
1434
- // Show as active when grouping is applied
1435
- dt.on('rowgroup-datasrc', function () {
1436
- var applied = rowGroupApplied(dt);
1437
- var ours = dt.column(_this.idx()).dataSrc();
1438
- btn.enable(applied.includes(ours));
1439
- });
1440
- // Default disabled
1441
- btn.enable(false);
1442
- return btn.element();
1443
- }
1444
- };
1445
-
1446
- var SearchInput = /** @class */ (function () {
1447
- /**
1448
- * Create a container element, for consistent DOM structure and styling
1449
- */
1450
- function SearchInput(dt, idx) {
1451
- var _this = this;
1452
- this._type = 'text';
1453
- this._sspTransform = null;
1454
- this._sspData = {};
1455
- this._dt = dt;
1456
- this._idx = idx;
1457
- this._dom = {
1458
- clear: createElement('span', 'dtcc-search-clear', icons['x']),
1459
- container: createElement('div', SearchInput.classes.container),
1460
- typeIcon: createElement('div', 'dtcc-search-type-icon'),
1461
- searchIcon: createElement('div', 'dtcc-search-icon', icons['search']),
1462
- input: createElement('input', SearchInput.classes.input),
1463
- inputs: createElement('div'),
1464
- select: createElement('select', SearchInput.classes.select),
1465
- title: createElement('div', 'dtcc-search-title')
1466
- };
1467
- var dom = this._dom;
1468
- var originalIdx = idx;
1469
- dom.input.setAttribute('type', 'text');
1470
- dom.container.append(dom.title, dom.inputs);
1471
- dom.inputs.append(dom.typeIcon, dom.select, dom.searchIcon, dom.clear, dom.input);
1472
- // Listeners
1473
- var inputInput = function () {
1474
- _this.runSearch();
1475
- };
1476
- var selectInput = function () {
1477
- dom.typeIcon.innerHTML = icons[dom.select.value];
1478
- _this.runSearch();
1479
- };
1480
- var clearClick = function () {
1481
- _this.clear();
1482
- };
1483
- dom.input.addEventListener('input', inputInput);
1484
- dom.select.addEventListener('input', selectInput);
1485
- dom.clear.addEventListener('click', clearClick);
1486
- dt.on('destroy', function () {
1487
- dom.input.removeEventListener('input', inputInput);
1488
- dom.select.removeEventListener('input', selectInput);
1489
- dom.clear.removeEventListener('click', clearClick);
1490
- });
1491
- // State handling - all components that use this class have the same state saving structure
1492
- // so shared handling can be performed here.
1493
- dt.on('stateSaveParams.DT', function (e, s, data) {
1494
- if (!data.columnControl) {
1495
- data.columnControl = {};
1496
- }
1497
- if (!data.columnControl[_this._idx]) {
1498
- data.columnControl[_this._idx] = {};
1499
- }
1500
- data.columnControl[_this._idx].searchInput = {
1501
- logic: dom.select.value,
1502
- type: _this._type,
1503
- value: dom.input.value
1504
- };
1505
- });
1506
- dt.on('stateLoaded.DT', function (e, s, state) {
1507
- _this._stateLoad(state);
1508
- });
1509
- // Same as for ColumnControl - reassign a column index if needed.
1510
- dt.on('columns-reordered.DT', function (e, details) {
1511
- _this._idx = dt.colReorder.transpose(originalIdx, 'fromOriginal');
1512
- });
1513
- // Column control search clearing (column().columnControl.searchClear() method)
1514
- dt.on('cc-search-clear.DT', function (e, colIdx) {
1515
- if (colIdx === _this._idx) {
1516
- // Don't want an automatic redraw on this event
1517
- _this._loadingState = true;
1518
- _this.clear();
1519
- _this._loadingState = false;
1520
- }
1521
- });
1522
- // Data for server-side processing
1523
- if (dt.page.info().serverSide) {
1524
- dt.on('preXhr.DT', function (e, s, d) {
1525
- // The column has been removed from the submit data - can't do anything
1526
- if (!d.columns || !d.columns[_this._idx]) {
1527
- return;
1528
- }
1529
- if (!d.columns[_this._idx].columnControl) {
1530
- d.columns[_this._idx].columnControl = {};
1531
- }
1532
- var val = _this._dom.input.value;
1533
- if (_this._sspTransform) {
1534
- val = _this._sspTransform(val);
1535
- }
1536
- d.columns[_this._idx].columnControl.search = Object.assign({
1537
- value: val,
1538
- logic: _this._dom.select.value,
1539
- type: _this._type
1540
- }, _this._sspData);
1541
- });
1542
- }
1543
- }
1544
- /**
1545
- * Add a class to the container
1546
- *
1547
- * @param name Class name to add
1548
- * @returns Self for chaining
1549
- */
1550
- SearchInput.prototype.addClass = function (name) {
1551
- this._dom.container.classList.add(name);
1552
- return this;
1553
- };
1554
- /**
1555
- * Clear any applied search
1556
- *
1557
- * @returns Self for chaining
1558
- */
1559
- SearchInput.prototype.clear = function () {
1560
- this.set(this._dom.select.children[0].getAttribute('value'), '');
1561
- return this;
1562
- };
1563
- /**
1564
- * Set the clear icon feature can be used or not
1565
- *
1566
- * @param set Flag
1567
- * @returns Self for chaining
1568
- */
1569
- SearchInput.prototype.clearable = function (set) {
1570
- // Note there is no add here as it is added by default and never used after setup, so
1571
- // no need.
1572
- if (!set) {
1573
- this._dom.clear.remove();
1574
- }
1575
- return this;
1576
- };
1577
- /**
1578
- * Get the container element
1579
- *
1580
- * @returns The container element
1581
- */
1582
- SearchInput.prototype.element = function () {
1583
- return this._dom.container;
1584
- };
1585
- /**
1586
- * Get the HTML input element for this control
1587
- *
1588
- * @returns HTML Input element
1589
- */
1590
- SearchInput.prototype.input = function () {
1591
- return this._dom.input;
1592
- };
1593
- /**
1594
- * Set the list of options for the dropdown
1595
- *
1596
- * @param opts List of options
1597
- * @returns Self for chaining
1598
- */
1599
- SearchInput.prototype.options = function (opts) {
1600
- var select = this._dom.select;
1601
- for (var i = 0; i < opts.length; i++) {
1602
- select.add(new Option(opts[i].label, opts[i].value));
1603
- }
1604
- // Initial icon
1605
- this._dom.typeIcon.innerHTML = icons[opts[0].value];
1606
- return this;
1607
- };
1608
- /**
1609
- * Set the placeholder attribute for the input element
1610
- *
1611
- * @param placeholder Placeholder string
1612
- * @returns Self for chaining
1613
- */
1614
- SearchInput.prototype.placeholder = function (placeholder) {
1615
- if (placeholder) {
1616
- var columnTitle = this._dt.column(this._idx).title();
1617
- this._dom.input.placeholder = placeholder.replace('[title]', columnTitle);
1618
- }
1619
- return this;
1620
- };
1621
- /**
1622
- * Run the search method
1623
- */
1624
- SearchInput.prototype.runSearch = function () {
1625
- var dom = this._dom;
1626
- var isActive = dom.select.value === 'empty' ||
1627
- dom.select.value === 'notEmpty' ||
1628
- dom.input.value !== '';
1629
- dom.container.classList.toggle('dtcc-search_active', isActive);
1630
- if (this._search &&
1631
- (this._lastValue !== dom.input.value || this._lastType !== dom.select.value)) {
1632
- this._search(dom.select.value, dom.input.value, this._loadingState);
1633
- this._lastValue = dom.input.value;
1634
- this._lastType = dom.select.value;
1635
- }
1636
- };
1637
- /**
1638
- * Set the function that will be run when a search operation is required. Note that this can
1639
- * trigger the function to run if there is a saved state.
1640
- *
1641
- * @param fn Search callback
1642
- * @returns Self for chaining
1643
- */
1644
- SearchInput.prototype.search = function (fn) {
1645
- this._search = fn;
1646
- // If there is a saved state, load it now that set up is done.
1647
- this._stateLoad(this._dt.state.loaded());
1648
- return this;
1649
- };
1650
- /**
1651
- * Set a value for the search input
1652
- *
1653
- * @param logic Logic type
1654
- * @param val Value
1655
- * @returns Self for chaining
1656
- */
1657
- SearchInput.prototype.set = function (logic, val) {
1658
- var dom = this._dom;
1659
- dom.input.value = val;
1660
- dom.select.value = logic;
1661
- dom.typeIcon.innerHTML = icons[dom.select.value];
1662
- this.runSearch();
1663
- return this;
1664
- };
1665
- /**
1666
- * Set a function to transform the input value before SSP data submission
1667
- *
1668
- * @param fn Transform function
1669
- * @returns Self for chaining
1670
- */
1671
- SearchInput.prototype.sspTransform = function (fn) {
1672
- this._sspTransform = fn;
1673
- return this;
1674
- };
1675
- /**
1676
- * Set extra information to be send to the server for server-side processing
1677
- *
1678
- * @param data Data object
1679
- * @returns Self for chaining
1680
- */
1681
- SearchInput.prototype.sspData = function (data) {
1682
- this._sspData = data;
1683
- return this;
1684
- };
1685
- /**
1686
- * Set the text that will be shown as the title for the control
1687
- *
1688
- * @param text Set the title text
1689
- * @returns Self for chaining
1690
- */
1691
- SearchInput.prototype.title = function (text) {
1692
- if (text) {
1693
- var columnTitle = this._dt.column(this._idx).title();
1694
- this._dom.title.innerHTML = text.replace('[title]', columnTitle);
1695
- }
1696
- return this;
1697
- };
1698
- /**
1699
- * Set the title attribute for the input element
1700
- *
1701
- * @param title Title attribute string
1702
- * @returns Self for chaining
1703
- */
1704
- SearchInput.prototype.titleAttr = function (title) {
1705
- if (title) {
1706
- var columnTitle = this._dt.column(this._idx).title();
1707
- this._dom.input.title = title.replace('[title]', columnTitle);
1708
- }
1709
- return this;
1710
- };
1711
- SearchInput.prototype.type = function (t) {
1712
- this._type = t;
1713
- return this;
1714
- };
1715
- /**
1716
- * Load a DataTables state
1717
- *
1718
- * @param state State object being loaded
1719
- */
1720
- SearchInput.prototype._stateLoad = function (state) {
1721
- var _a, _b;
1722
- var dom = this._dom;
1723
- var idx = this._idx;
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;
1725
- if (loadedState) {
1726
- // The search callback needs to know if we are loading an existing state or not
1727
- // so it can determine if it needs to draw the table. If it was a user input, then
1728
- // it redraws, if it was a state load, then there should be no redraw.
1729
- this._loadingState = true;
1730
- dom.select.value = loadedState.logic;
1731
- dom.input.value = loadedState.value;
1732
- dom.select.dispatchEvent(new Event('input'));
1733
- this._loadingState = false;
1734
- }
1735
- };
1736
- SearchInput.classes = {
1737
- container: ['dtcc-content', 'dtcc-search'],
1738
- input: '',
1739
- select: ''
1740
- };
1741
- return SearchInput;
1742
- }());
1743
-
1744
- var searchDateTime = {
1745
- defaults: {
1746
- clear: true,
1747
- format: '',
1748
- mask: '',
1749
- placeholder: '',
1750
- title: '',
1751
- titleAttr: ''
1752
- },
1753
- init: function (config) {
1754
- var _this = this;
1755
- var fromPicker = false;
1756
- var moment = DataTable.use('moment');
1757
- var luxon = DataTable.use('luxon');
1758
- var dt = this.dt();
1759
- var i18nBase = 'columnControl.search.datetime.';
1760
- var pickerFormat = '';
1761
- var dataSrcFormat = '';
1762
- var dateTime;
1763
- var searchInput = new SearchInput(dt, this.idx())
1764
- .type('date')
1765
- .addClass('dtcc-searchDateTime')
1766
- .sspTransform(function (val) { return toISO(val, pickerFormat, moment, luxon); })
1767
- .sspData({ mask: config.mask })
1768
- .clearable(config.clear)
1769
- .placeholder(config.placeholder)
1770
- .title(config.title)
1771
- .titleAttr(config.titleAttr)
1772
- .options([
1773
- { label: dt.i18n(i18nBase + 'equal', 'Equals'), value: 'equal' },
1774
- { label: dt.i18n(i18nBase + 'notEqual', 'Does not equal'), value: 'notEqual' },
1775
- { label: dt.i18n(i18nBase + 'greater', 'After'), value: 'greater' },
1776
- { label: dt.i18n(i18nBase + 'less', 'Before'), value: 'less' },
1777
- { label: dt.i18n(i18nBase + 'empty', 'Empty'), value: 'empty' },
1778
- { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
1779
- ])
1780
- .search(function (searchType, searchTerm, loadingState) {
1781
- // When SSP, don't apply a filter here, SearchInput will add to the submit data
1782
- if (dt.page.info().serverSide) {
1783
- if (!loadingState) {
1784
- dt.draw();
1785
- }
1786
- return;
1787
- }
1788
- var mask = config.mask;
1789
- var column = dt.column(_this.idx());
1790
- var search = searchTerm === ''
1791
- ? ''
1792
- : dateToNum(dateTime && fromPicker ? dateTime.val() : searchTerm.trim(), pickerFormat, moment, luxon, mask);
1793
- if (searchType === 'empty') {
1794
- column.search.fixed('dtcc', function (haystack) { return !haystack; });
1795
- }
1796
- else if (searchType === 'notEmpty') {
1797
- column.search.fixed('dtcc', function (haystack) { return !!haystack; });
1798
- }
1799
- else if (column.search.fixed('dtcc') === '' && search === '') {
1800
- // No change - don't do anything
1801
- return;
1802
- }
1803
- else if (!search) {
1804
- // Clear search
1805
- column.search.fixed('dtcc', '');
1806
- }
1807
- else if (searchType === 'equal') {
1808
- // Use a function for matching - weak typing
1809
- // Note that the haystack in the search function is the rendered date - it
1810
- // might need to be converted back to a date
1811
- column.search.fixed('dtcc', function (haystack) {
1812
- return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) == search;
1813
- });
1814
- }
1815
- else if (searchType === 'notEqual') {
1816
- column.search.fixed('dtcc', function (haystack) {
1817
- return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) != search;
1818
- });
1819
- }
1820
- else if (searchType === 'greater') {
1821
- column.search.fixed('dtcc', function (haystack) {
1822
- return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) > search;
1823
- });
1824
- }
1825
- else if (searchType === 'less') {
1826
- column.search.fixed('dtcc', function (haystack) {
1827
- return dateToNum(haystack, dataSrcFormat, moment, luxon, mask) < search;
1828
- });
1829
- }
1830
- // If in a dropdown, set the parent levels as active
1831
- if (config._parents) {
1832
- config._parents.forEach(function (btn) {
1833
- return btn.activeList(_this.unique(), !!column.search.fixed('dtcc'));
1834
- });
1835
- }
1836
- if (!loadingState) {
1837
- column.draw();
1838
- }
1839
- });
1840
- // Once data has been loaded we can run DateTime with the specified format
1841
- dt.ready(function () {
1842
- var DateTime = DataTable.use('datetime');
1843
- dataSrcFormat = getFormat(dt, _this.idx());
1844
- pickerFormat = config.format
1845
- ? config.format
1846
- : dataSrcFormat;
1847
- if (DateTime) {
1848
- dateTime = new DateTime(searchInput.input(), {
1849
- format: pickerFormat,
1850
- i18n: dt.settings()[0].oLanguage.datetime, // could be undefined
1851
- onChange: function () {
1852
- fromPicker = true;
1853
- searchInput.runSearch();
1854
- fromPicker = false;
1855
- }
1856
- });
1857
- }
1858
- });
1859
- return searchInput.element();
1860
- }
1861
- };
1862
- /**
1863
- * Determine the formatting string for the date time information in the colum
1864
- *
1865
- * @param dt DataTable instance
1866
- * @param column Column index
1867
- * @returns Date / time formatting string
1868
- */
1869
- function getFormat(dt, column) {
1870
- var type = dt.column(column).type();
1871
- if (!type) {
1872
- // Assume that it is ISO unless otherwise specified - that is all DataTables can do anyway
1873
- return 'YYYY-MM-DD';
1874
- }
1875
- else if (type === 'datetime') {
1876
- // If no format was specified in the DT type, a Javascript native toLocaleDateString
1877
- // was used. Need to work out what that format is in Moment or Luxon. We need to pass
1878
- // a known value though the renderer and work out the format
1879
- var renderer = dt.settings()[0].aoColumns[column].mRender;
1880
- var resultPm = renderer('1999-08-07T23:05:04Z', 'display');
1881
- var resultAm = renderer('1999-08-07T03:05:04Z', 'display');
1882
- var leadingZero = resultAm.includes('03');
1883
- // What formatter are we using?
1884
- if (DataTable.use('moment')) {
1885
- return resultPm
1886
- .replace('23', leadingZero ? 'HH' : 'H')
1887
- .replace('11', leadingZero ? 'hh' : 'h')
1888
- .replace('05', 'mm')
1889
- .replace('04', 'ss')
1890
- .replace('PM', 'A')
1891
- .replace('pm', 'a')
1892
- .replace('07', 'DD')
1893
- .replace('7', 'D')
1894
- .replace('08', 'MM')
1895
- .replace('8', 'M')
1896
- .replace('1999', 'YYYY')
1897
- .replace('99', 'YY');
1898
- }
1899
- else if (DataTable.use('luxon')) {
1900
- return resultPm
1901
- .replace('23', leadingZero ? 'HH' : 'H')
1902
- .replace('11', leadingZero ? 'hh' : 'h')
1903
- .replace('05', 'mm')
1904
- .replace('04', 'ss')
1905
- .replace('PM', 'a')
1906
- .replace('07', 'dd')
1907
- .replace('7', 'd')
1908
- .replace('08', 'MM')
1909
- .replace('8', 'M')
1910
- .replace('1999', 'yyyy')
1911
- .replace('99', 'yy');
1912
- }
1913
- else if (resultPm.includes('23') && resultPm.includes('1999')) {
1914
- return 'YYYY-MM-DD hh:mm:ss';
1915
- }
1916
- else if (resultPm.includes('23')) {
1917
- return 'hh:mm:ss';
1918
- }
1919
- // fall through to final return
1920
- }
1921
- else if (type.includes('datetime-')) {
1922
- // Column was specified with a particular display format - we can extract that format from
1923
- // the type, as it is part of the type name.
1924
- return type.replace(/datetime-/g, '');
1925
- }
1926
- else if (type.includes('moment')) {
1927
- return type.replace(/moment-/g, '');
1928
- }
1929
- else if (type.includes('luxon')) {
1930
- return type.replace(/luxon-/g, '');
1931
- }
1932
- return 'YYYY-MM-DD';
1933
- }
1934
- /**
1935
- * Convert from a source date / time value (usually a string) to a timestamp for comparisons.
1936
- *
1937
- * @param input Input value
1938
- * @param srcFormat String format of the input
1939
- * @param moment Moment instance, if it is available
1940
- * @param luxon Luxon object, if it is available
1941
- * @returns Time stamp - milliseconds
1942
- */
1943
- function dateToNum(input, srcFormat, moment, luxon, mask) {
1944
- var d;
1945
- if (input === '') {
1946
- return '';
1947
- }
1948
- if (input instanceof Date) {
1949
- d = input;
1950
- }
1951
- else if (srcFormat !== 'YYYY-MM-DD' && (moment || luxon)) {
1952
- d = new Date(moment
1953
- ? moment(input, srcFormat).unix() * 1000
1954
- : luxon.DateTime.fromFormat(input, srcFormat).toMillis());
1955
- }
1956
- else {
1957
- // new Date() with `/` separators will treat the input as local time, but with `-` it will
1958
- // treat it as UTC. We want UTC so do a replacement
1959
- d = new Date(input.replace(/\//g, '-'));
1960
- }
1961
- if (mask) {
1962
- if (!mask.includes('YYYY')) {
1963
- d.setFullYear(1970);
1964
- }
1965
- if (!mask.includes('MM')) {
1966
- d.setUTCMonth(0);
1967
- }
1968
- if (!mask.includes('DD')) {
1969
- d.setUTCDate(1);
1970
- }
1971
- if (!mask.includes('hh')) {
1972
- d.setUTCHours(0);
1973
- }
1974
- if (!mask.includes('mm')) {
1975
- d.setUTCMinutes(0);
1976
- }
1977
- if (!mask.includes('ss')) {
1978
- // This will match milliseconds as well, but that's fine, you won't match mS but not S
1979
- d.setUTCSeconds(0);
1980
- }
1981
- if (!mask.includes('sss')) {
1982
- d.setUTCMilliseconds(0);
1983
- }
1984
- }
1985
- return d.getTime();
1986
- }
1987
- /**
1988
- * Convert an input string to an ISO formatted date
1989
- *
1990
- * @param input Input value
1991
- * @param srcFormat String format of the input
1992
- * @param moment Moment instance, if it is available
1993
- * @param luxon Luxon object, if it is available
1994
- * @returns Value in ISO
1995
- */
1996
- function toISO(input, srcFormat, moment, luxon) {
1997
- if (input === '') {
1998
- return '';
1999
- }
2000
- else if (srcFormat !== 'YYYY-MM-DD' && moment) {
2001
- // TODO Does it have a time component?
2002
- return moment.utc(input, srcFormat).toISOString();
2003
- }
2004
- else if (srcFormat !== 'YYYY-MM-DD' && luxon) {
2005
- // TODO Does it have a time component?
2006
- return luxon.DateTime.fromFormat(input, srcFormat).toISO();
2007
- }
2008
- // new Date() with `/` separators will treat the input as local time, but with `-` it will
2009
- // treat it as UTC. We want UTC so do a replacement
2010
- input = input.replace(/\//g, '-');
2011
- return input;
2012
- }
2013
-
2014
- /** Set the options to show in the list */
2015
- function setOptions(checkList, opts) {
2016
- var existing = checkList.values();
2017
- checkList.clear();
2018
- for (var i = 0; i < opts.length; i++) {
2019
- if (typeof opts[i] === 'object') {
2020
- checkList.add({
2021
- active: false,
2022
- label: opts[i].label,
2023
- value: opts[i].value
2024
- }, i === opts.length - 1);
2025
- }
2026
- else {
2027
- checkList.add({
2028
- active: false,
2029
- label: opts[i],
2030
- value: opts[i]
2031
- }, i === opts.length - 1);
2032
- }
2033
- }
2034
- if (existing.length) {
2035
- checkList.values(existing);
2036
- }
2037
- }
2038
- /** Load a saved state */
2039
- function getState(columnIdx, state) {
2040
- var _a, _b;
2041
- var loadedState = (_b = (_a = state === null || state === void 0 ? void 0 : state.columnControl) === null || _a === void 0 ? void 0 : _a[columnIdx]) === null || _b === void 0 ? void 0 : _b.searchList;
2042
- if (loadedState) {
2043
- return loadedState;
2044
- }
2045
- }
2046
- /** Get the options for a column from a DT JSON object */
2047
- function getJsonOptions(dt, idx) {
2048
- var _a;
2049
- var json = (_a = dt.ajax.json()) === null || _a === void 0 ? void 0 : _a.columnControl;
2050
- var column = dt.column(idx);
2051
- var name = column.name();
2052
- var dataSrc = column.dataSrc();
2053
- if (json && json[name]) {
2054
- // Found options matching the column's name - top priority
2055
- return json[name];
2056
- }
2057
- else if (json && typeof dataSrc === 'string' && json[dataSrc]) {
2058
- // Found options matching the column's data source string
2059
- return json[dataSrc];
2060
- }
2061
- else if (json && json[idx]) {
2062
- // Found options matching the column's data index
2063
- return json[idx];
2064
- }
2065
- return null;
2066
- }
2067
- function reloadOptions(dt, config, idx, checkList, loadedValues) {
2068
- var _a;
2069
- // Was there options specified in the Ajax return?
2070
- var json = (_a = dt.ajax.json()) === null || _a === void 0 ? void 0 : _a.columnControl;
2071
- var options = [];
2072
- var jsonOptions = getJsonOptions(dt, idx);
2073
- if (jsonOptions) {
2074
- options = jsonOptions;
2075
- }
2076
- else if (json && config.ajaxOnly) {
2077
- if (config.hidable) {
2078
- // Ajax only options - need to hide the search list
2079
- checkList.element().style.display = 'none';
2080
- // Check if the parent buttons should be hidden as well (they will be if there
2081
- // is no visible content in them)
2082
- if (config._parents) {
2083
- config._parents.forEach(function (btn) { return btn.checkDisplay(); });
2084
- }
2085
- }
2086
- // No point in doing any further processing here
2087
- return;
2088
- }
2089
- else if (!dt.page.info().serverSide) {
2090
- // Either no ajax object (i.e. not an Ajax table), or no matching ajax options
2091
- // for this column - get the values for the column, taking into account
2092
- // orthogonal rendering
2093
- var found = {};
2094
- var rows = dt.rows({ order: idx }).indexes().toArray();
2095
- var settings = dt.settings()[0];
2096
- for (var i = 0; i < rows.length; i++) {
2097
- var raw = settings.fastData(rows[i], idx, 'filter');
2098
- var filter = raw !== null && raw !== undefined
2099
- ? raw.toString()
2100
- : '';
2101
- if (!found[filter]) {
2102
- found[filter] = true;
2103
- options.push({
2104
- label: settings.fastData(rows[i], idx, config.orthogonal),
2105
- value: filter
2106
- });
2107
- }
2108
- }
2109
- }
2110
- setOptions(checkList, options);
2111
- // If there was a state loaded at start up, then we need to set the visual
2112
- // appearance to match
2113
- if (loadedValues) {
2114
- checkList.values(loadedValues);
2115
- }
2116
- }
2117
- var searchList = {
2118
- defaults: {
2119
- ajaxOnly: true,
2120
- className: 'searchList',
2121
- hidable: true,
2122
- options: null,
2123
- orthogonal: 'display',
2124
- search: true,
2125
- select: true,
2126
- title: ''
2127
- },
2128
- init: function (config) {
2129
- var _this = this;
2130
- var loadedValues = null;
2131
- var dt = this.dt();
2132
- // The search can be applied from a stored start at start up before the options are
2133
- // available. It can also be applied by user input, so it is generalised into this function.
2134
- var applySearch = function (values) {
2135
- // When SSP, don't do any client-side filtering
2136
- if (dt.page.info().serverSide) {
2137
- return;
2138
- }
2139
- var col = dt.column(_this.idx());
2140
- if (!values) {
2141
- return;
2142
- }
2143
- else if (values.length === 0) {
2144
- // Nothing selected - clear the filter
2145
- col.search.fixed('dtcc-list', '');
2146
- }
2147
- else {
2148
- // Find all matching options from the list of values
2149
- col.search.fixed('dtcc-list', function (val) {
2150
- return values.includes(val);
2151
- });
2152
- }
2153
- // If in a dropdown, set the parent levels as active
2154
- if (config._parents) {
2155
- config._parents.forEach(function (btn) { return btn.activeList(_this.unique(), !!values.length); });
2156
- }
2157
- };
2158
- var checkList = new CheckList(dt, this, {
2159
- search: config.search,
2160
- select: config.select
2161
- })
2162
- .searchListener(dt)
2163
- .title(dt
2164
- .i18n('columnControl.searchList', config.title)
2165
- .replace('[title]', dt.column(this.idx()).title()))
2166
- .handler(function (e, btn, btns, redraw) {
2167
- if (btn) {
2168
- btn.active(!btn.active());
2169
- }
2170
- applySearch(checkList.values());
2171
- if (redraw) {
2172
- dt.draw();
2173
- }
2174
- });
2175
- if (config.options) {
2176
- setOptions(checkList, config.options);
2177
- }
2178
- else {
2179
- dt.ready(function () {
2180
- reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
2181
- });
2182
- // Xhr event listener for updates of options
2183
- dt.on('xhr', function (e, s, json) {
2184
- // Need to wait for the draw to complete so the table has the latest data
2185
- dt.one('draw', function () {
2186
- reloadOptions(dt, config, _this.idx(), checkList, loadedValues);
2187
- });
2188
- });
2189
- }
2190
- // Data for server-side processing
2191
- if (dt.page.info().serverSide) {
2192
- dt.on('preXhr.DT', function (e, s, d) {
2193
- // The column has been removed from the submit data - can't do anything
2194
- if (!d.columns || !d.columns[_this.idx()]) {
2195
- return;
2196
- }
2197
- if (!d.columns[_this.idx()].columnControl) {
2198
- d.columns[_this.idx()].columnControl = {};
2199
- }
2200
- // We need the indexes in the HTTP parameter names (for .NET), so use an object.
2201
- d.columns[_this.idx()].columnControl.list = Object.assign({}, checkList.values());
2202
- });
2203
- }
2204
- // Unlike the SearchInput based search contents, CheckList does not handle state saving
2205
- // (since the mechanism for column visibility is different), so state saving is handled
2206
- // here.
2207
- dt.on('stateLoaded', function (e, s, state) {
2208
- var values = getState(_this.idx(), state);
2209
- if (values) {
2210
- checkList.values(values);
2211
- applySearch(values);
2212
- }
2213
- });
2214
- dt.on('stateSaveParams', function (e, s, data) {
2215
- var idx = _this.idx();
2216
- if (!data.columnControl) {
2217
- data.columnControl = {};
2218
- }
2219
- if (!data.columnControl[idx]) {
2220
- data.columnControl[idx] = {};
2221
- }
2222
- // If the table isn't yet ready, then the options for the list won't have been
2223
- // populated (above) and therefore there can't be an values. In such a case
2224
- // use the last saved values and this will refresh on the next draw.
2225
- data.columnControl[idx].searchList = dt.ready()
2226
- ? checkList.values()
2227
- : loadedValues;
2228
- });
2229
- dt.settings()[0].aoColumns[this.idx()].columnControlSearchList = function (options) {
2230
- if (options === 'refresh') {
2231
- reloadOptions(dt, config, _this.idx(), checkList, null);
2232
- }
2233
- else {
2234
- setOptions(checkList, options);
2235
- }
2236
- };
2237
- loadedValues = getState(this.idx(), dt.state.loaded());
2238
- applySearch(loadedValues);
2239
- return checkList.element();
2240
- }
2241
- };
2242
-
2243
- var searchNumber = {
2244
- defaults: {
2245
- clear: true,
2246
- placeholder: '',
2247
- title: '',
2248
- titleAttr: ''
2249
- },
2250
- init: function (config) {
2251
- var _this = this;
2252
- var dt = this.dt();
2253
- var i18nBase = 'columnControl.search.number.';
2254
- var searchInput = new SearchInput(dt, this.idx())
2255
- .type('num')
2256
- .addClass('dtcc-searchNumber')
2257
- .clearable(config.clear)
2258
- .placeholder(config.placeholder)
2259
- .title(config.title)
2260
- .titleAttr(config.titleAttr)
2261
- .options([
2262
- { label: dt.i18n(i18nBase + 'equal', 'Equals'), value: 'equal' },
2263
- { label: dt.i18n(i18nBase + 'notEqual', 'Does not equal'), value: 'notEqual' },
2264
- { label: dt.i18n(i18nBase + 'greater', 'Greater than'), value: 'greater' },
2265
- {
2266
- label: dt.i18n(i18nBase + 'greaterOrEqual', 'Greater or equal'),
2267
- value: 'greaterOrEqual'
2268
- },
2269
- { label: dt.i18n(i18nBase + 'less', 'Less than'), value: 'less' },
2270
- { label: dt.i18n(i18nBase + 'lessOrEqual', 'Less or equal'), value: 'lessOrEqual' },
2271
- { label: dt.i18n(i18nBase + 'empty', 'Empty'), value: 'empty' },
2272
- { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
2273
- ])
2274
- .search(function (searchType, searchTerm, loadingState) {
2275
- // When SSP, don't apply a filter here, SearchInput will add to the submit data
2276
- if (dt.page.info().serverSide) {
2277
- if (!loadingState) {
2278
- dt.draw();
2279
- }
2280
- return;
2281
- }
2282
- var column = dt.column(_this.idx());
2283
- if (searchType === 'empty') {
2284
- column.search.fixed('dtcc', function (haystack) { return !haystack; });
2285
- }
2286
- else if (searchType === 'notEmpty') {
2287
- column.search.fixed('dtcc', function (haystack) { return !!haystack; });
2288
- }
2289
- else if (column.search.fixed('dtcc') === '' && searchTerm === '') {
2290
- // No change - don't do anything
2291
- return;
2292
- }
2293
- else if (searchTerm === '') {
2294
- // Clear search
2295
- column.search.fixed('dtcc', '');
2296
- }
2297
- else if (searchType === 'equal') {
2298
- // Use a function for matching - weak typing
2299
- column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) == searchTerm; });
2300
- }
2301
- else if (searchType === 'notEqual') {
2302
- column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) != searchTerm; });
2303
- }
2304
- else if (searchType === 'greater') {
2305
- column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) > searchTerm; });
2306
- }
2307
- else if (searchType === 'greaterOrEqual') {
2308
- column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) >= searchTerm; });
2309
- }
2310
- else if (searchType === 'less') {
2311
- column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) < searchTerm; });
2312
- }
2313
- else if (searchType === 'lessOrEqual') {
2314
- column.search.fixed('dtcc', function (haystack) { return stringToNum(haystack) <= searchTerm; });
2315
- }
2316
- // If in a dropdown, set the parents as active
2317
- if (config._parents) {
2318
- config._parents.forEach(function (btn) {
2319
- return btn.activeList(_this.unique(), !!column.search.fixed('dtcc'));
2320
- });
2321
- }
2322
- if (!loadingState) {
2323
- column.draw();
2324
- }
2325
- });
2326
- // Set a numeric input type, per BBC's guidelines
2327
- searchInput.input().setAttribute('inputmode', 'numeric');
2328
- searchInput.input().setAttribute('pattern', '[0-9]*');
2329
- return searchInput.element();
2330
- }
2331
- };
2332
- var _re_html = /<([^>]*>)/g;
2333
- var _re_formatted_numeric = /['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
2334
- function stringToNum(d) {
2335
- if (d !== 0 && (!d || d === '-')) {
2336
- return -Infinity;
2337
- }
2338
- var type = typeof d;
2339
- if (type === 'number' || type === 'bigint') {
2340
- return d;
2341
- }
2342
- if (d.replace) {
2343
- d = d.replace(_re_html, '').replace(_re_formatted_numeric, '');
2344
- }
2345
- return d * 1;
2346
- }
2347
-
2348
- var searchText = {
2349
- defaults: {
2350
- clear: true,
2351
- placeholder: '',
2352
- title: '',
2353
- titleAttr: ''
2354
- },
2355
- init: function (config) {
2356
- var _this = this;
2357
- var dt = this.dt();
2358
- var i18nBase = 'columnControl.search.text.';
2359
- var searchInput = new SearchInput(dt, this.idx())
2360
- .addClass('dtcc-searchText')
2361
- .clearable(config.clear)
2362
- .placeholder(config.placeholder)
2363
- .title(config.title)
2364
- .titleAttr(config.titleAttr)
2365
- .options([
2366
- { label: dt.i18n(i18nBase + 'contains', 'Contains'), value: 'contains' },
2367
- {
2368
- label: dt.i18n(i18nBase + 'notContains', 'Does not contain'),
2369
- value: 'notContains'
2370
- },
2371
- { label: dt.i18n(i18nBase + 'equal', 'Equals'), value: 'equal' },
2372
- { label: dt.i18n(i18nBase + 'notEqual', 'Does not equal'), value: 'notEqual' },
2373
- { label: dt.i18n(i18nBase + 'starts', 'Starts'), value: 'starts' },
2374
- { label: dt.i18n(i18nBase + 'ends', 'Ends'), value: 'ends' },
2375
- { label: dt.i18n(i18nBase + 'empty', 'Empty'), value: 'empty' },
2376
- { label: dt.i18n(i18nBase + 'notEmpty', 'Not empty'), value: 'notEmpty' }
2377
- ])
2378
- .search(function (searchType, searchTerm, loadingState) {
2379
- // When SSP, don't apply a filter here, SearchInput will add to the submit data
2380
- if (dt.page.info().serverSide) {
2381
- if (!loadingState) {
2382
- dt.draw();
2383
- }
2384
- return;
2385
- }
2386
- var column = dt.column(_this.idx());
2387
- searchTerm = searchTerm.toLowerCase();
2388
- if (searchType === 'empty') {
2389
- column.search.fixed('dtcc', function (haystack) { return !haystack; });
2390
- }
2391
- else if (searchType === 'notEmpty') {
2392
- column.search.fixed('dtcc', function (haystack) { return !!haystack; });
2393
- }
2394
- else if (column.search.fixed('dtcc') === '' && searchTerm === '') {
2395
- // No change - don't do anything
2396
- return;
2397
- }
2398
- else if (searchTerm === '') {
2399
- // Clear search
2400
- column.search.fixed('dtcc', '');
2401
- }
2402
- else if (searchType === 'equal') {
2403
- // Use a function for exact matching
2404
- column.search.fixed('dtcc', function (haystack) { return haystack.toLowerCase() == searchTerm; });
2405
- }
2406
- else if (searchType === 'notEqual') {
2407
- column.search.fixed('dtcc', function (haystack) { return haystack.toLowerCase() != searchTerm; });
2408
- }
2409
- else if (searchType === 'contains') {
2410
- // Use the built in smart search
2411
- column.search.fixed('dtcc', searchTerm);
2412
- }
2413
- else if (searchType === 'notContains') {
2414
- // Use the built in smart search
2415
- column.search.fixed('dtcc', function (haystack) { return !haystack.toLowerCase().includes(searchTerm); });
2416
- }
2417
- else if (searchType === 'starts') {
2418
- // Use a function for startsWith case insensitive search
2419
- column.search.fixed('dtcc', function (haystack) {
2420
- return haystack.toLowerCase().startsWith(searchTerm);
2421
- });
2422
- }
2423
- else if (searchType === 'ends') {
2424
- column.search.fixed('dtcc', function (haystack) {
2425
- return haystack.toLowerCase().endsWith(searchTerm);
2426
- });
2427
- }
2428
- // If in a dropdown, set the parent levels as active
2429
- if (config._parents) {
2430
- config._parents.forEach(function (btn) {
2431
- return btn.activeList(_this.unique(), !!column.search.fixed('dtcc'));
2432
- });
2433
- }
2434
- if (!loadingState) {
2435
- column.draw();
2436
- }
2437
- });
2438
- return searchInput.element();
2439
- }
2440
- };
2441
-
2442
- var search = {
2443
- defaults: {
2444
- allowSearchList: false
2445
- },
2446
- init: function (config) {
2447
- var _this = this;
2448
- var _a, _b, _c;
2449
- var dt = this.dt();
2450
- var idx = this.idx();
2451
- var displayEl;
2452
- 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;
2453
- var initType = function (type) {
2454
- var json = getJsonOptions(dt, idx);
2455
- // Attempt to match what type of search should be shown
2456
- if (config.allowSearchList && json) {
2457
- // We've got a list of JSON options, and are allowed to show the searchList
2458
- return searchList.init.call(_this, Object.assign({}, searchList.defaults, config));
2459
- }
2460
- else if (type === 'date' || type.startsWith('datetime')) {
2461
- // Date types
2462
- return searchDateTime.init.call(_this, Object.assign({}, searchDateTime.defaults, config));
2463
- }
2464
- else if (type.includes('num')) {
2465
- // Number types
2466
- return searchNumber.init.call(_this, Object.assign({}, searchNumber.defaults, config));
2467
- }
2468
- else {
2469
- // Everything else
2470
- return searchText.init.call(_this, Object.assign({}, searchText.defaults, config));
2471
- }
2472
- };
2473
- // If we know the type from the saved state, we can load it immediately. This is required
2474
- // to allow the state to be applied to the table and the first draw to have a filter
2475
- // applied (if it is needed).
2476
- if (loadedState) {
2477
- displayEl = initType(loadedState.type);
2478
- }
2479
- else {
2480
- // Wait until we can get the data type for the column and the run the corresponding type
2481
- displayEl = document.createElement('div');
2482
- dt.ready(function () {
2483
- var column = dt.column(idx);
2484
- var display = initType(column.type());
2485
- displayEl.replaceWith(display);
2486
- });
2487
- }
2488
- return displayEl;
2489
- }
2490
- };
2491
-
2492
- var searchClear$1 = {
2493
- defaults: {
2494
- className: 'searchClear',
2495
- icon: 'searchClear',
2496
- text: 'Clear Search'
2497
- },
2498
- init: function (config) {
2499
- var _this = this;
2500
- var dt = this.dt();
2501
- var btn = new Button(dt, this)
2502
- .text(dt.i18n('columnControl.searchClear', config.text))
2503
- .icon(config.icon)
2504
- .className(config.className)
2505
- .handler(function () {
2506
- dt.column(_this.idx()).columnControl.searchClear().draw();
2507
- })
2508
- .enable(false);
2509
- dt.on('draw', function () {
2510
- // change enable state
2511
- var search = dt.column(_this.idx()).search.fixed('dtcc');
2512
- var searchList = dt.column(_this.idx()).search.fixed('dtcc-list');
2513
- btn.enable(!!(search || searchList));
2514
- });
2515
- return btn.element();
2516
- }
2517
- };
2518
-
2519
- var searchDropdown = {
2520
- defaults: {
2521
- ajaxOnly: true,
2522
- allowSearchList: true,
2523
- className: 'searchDropdown',
2524
- clear: true,
2525
- columns: '',
2526
- hidable: true,
2527
- options: null,
2528
- orthogonal: 'display',
2529
- placeholder: '',
2530
- search: true,
2531
- select: true,
2532
- text: 'Search',
2533
- title: '',
2534
- titleAttr: ''
2535
- },
2536
- extend: function (config) {
2537
- var dt = this.dt();
2538
- return {
2539
- extend: 'dropdown',
2540
- icon: 'search',
2541
- text: dt.i18n('columnControl.searchDropdown', config.text),
2542
- content: [
2543
- Object.assign(config, {
2544
- extend: 'search'
2545
- })
2546
- ]
2547
- };
2548
- }
2549
- };
2550
-
2551
- var spacer = {
2552
- defaults: {
2553
- className: 'dtcc-spacer',
2554
- text: ''
2555
- },
2556
- init: function (config) {
2557
- var dt = this.dt();
2558
- var spacer = createElement('div', config.className, dt.i18n('columnControl.spacer', config.text));
2559
- spacer.setAttribute('role', 'separator');
2560
- return spacer;
2561
- }
2562
- };
2563
-
2564
- var title = {
2565
- defaults: {
2566
- className: 'dtcc-title',
2567
- text: null
2568
- },
2569
- init: function (config) {
2570
- var dt = this.dt();
2571
- var title = dt.column(this.idx()).title();
2572
- var text = config.text === null ? '[title]' : config.text;
2573
- var el = createElement('div', config.className, text.replace('[title]', title));
2574
- return el;
2575
- }
2576
- };
2577
-
2578
- var contentTypes = {
2579
- colVis: colVis,
2580
- colVisDropdown: colVisDropdown,
2581
- dropdown: dropdownContent,
2582
- reorder: reorder,
2583
- reorderLeft: reorderLeft,
2584
- reorderRight: reorderRight,
2585
- rowGroup: rowGroup,
2586
- rowGroupAdd: rowGroupAdd,
2587
- rowGroupClear: rowGroupClear,
2588
- rowGroupRemove: rowGroupRemove,
2589
- order: order,
2590
- orderAddAsc: orderAddAsc,
2591
- orderAddDesc: orderAddDesc,
2592
- orderAsc: orderAsc,
2593
- orderClear: orderClear,
2594
- orderDesc: orderDesc,
2595
- orderRemove: orderRemove,
2596
- orderStatus: orderStatus,
2597
- search: search,
2598
- searchClear: searchClear$1,
2599
- searchDropdown: searchDropdown,
2600
- searchDateTime: searchDateTime,
2601
- searchList: searchList,
2602
- searchNumber: searchNumber,
2603
- searchText: searchText,
2604
- spacer: spacer,
2605
- title: title
2606
- };
2607
-
2608
- /**
2609
- *
2610
- */
2611
- var ColumnControl = /** @class */ (function () {
2612
- /**
2613
- * Create a new ColumnControl instance to control a DataTables column.
2614
- *
2615
- * @param dt DataTables API instance
2616
- * @param columnIdx Column index to operation on
2617
- * @param opts Configuration options
2618
- */
2619
- function ColumnControl(dt, columnIdx, opts) {
2620
- var _this = this;
2621
- this._dom = {
2622
- target: null,
2623
- wrapper: null
2624
- };
2625
- this._c = {};
2626
- this._s = {
2627
- columnIdx: null,
2628
- unique: null,
2629
- toDestroy: []
2630
- };
2631
- this._dt = dt;
2632
- this._s.columnIdx = columnIdx;
2633
- this._s.unique = Math.random();
2634
- var originalIdx = columnIdx;
2635
- Object.assign(this._c, ColumnControl.defaults, opts);
2636
- this._dom.target = this._target();
2637
- if (opts.className) {
2638
- addClass(this._dom.target.closest('tr'), opts.className);
2639
- }
2640
- if (this._c.content) {
2641
- // If column reordering can be done, we reassign the column index here, and before the
2642
- // plugins can add their own listeners.
2643
- dt.on('columns-reordered', function (e, details) {
2644
- _this._s.columnIdx = dt.colReorder.transpose(originalIdx, 'fromOriginal');
2645
- });
2646
- this._dom.wrapper = document.createElement('span');
2647
- this._dom.wrapper.classList.add('dtcc');
2648
- this._dom.target.appendChild(this._dom.wrapper);
2649
- this._c.content.forEach(function (content) {
2650
- var _a = _this.resolve(content), plugin = _a.plugin, config = _a.config;
2651
- var el = plugin.init.call(_this, config);
2652
- _this._dom.wrapper.appendChild(el);
2653
- });
2654
- dt.on('destroy', function () {
2655
- _this._s.toDestroy.slice().forEach(function (el) {
2656
- el.destroy();
2657
- });
2658
- _this._dom.wrapper.remove();
2659
- });
2660
- }
2661
- }
2662
- /**
2663
- * Add a component to the destroy list. This is so there is a single destroy event handler,
2664
- * which is much better for performance.
2665
- *
2666
- * @param component Any instance with a `destroy` method
2667
- */
2668
- ColumnControl.prototype.destroyAdd = function (component) {
2669
- this._s.toDestroy.push(component);
2670
- };
2671
- /**
2672
- * Remove an instance from the destroy list (it has been destroyed itself)
2673
- *
2674
- * @param component Any instance with a `destroy` method
2675
- */
2676
- ColumnControl.prototype.destroyRemove = function (component) {
2677
- var idx = this._s.toDestroy.indexOf(component);
2678
- if (idx !== -1) {
2679
- this._s.toDestroy.splice(idx, 1);
2680
- }
2681
- };
2682
- /**
2683
- * Get the DataTables API instance that hosts this instance of ColumnControl
2684
- *
2685
- * @returns DataTables API instance
2686
- */
2687
- ColumnControl.prototype.dt = function () {
2688
- return this._dt;
2689
- };
2690
- /**
2691
- * Get what column index this instance of ColumnControl is operating on
2692
- *
2693
- * @returns Column index
2694
- */
2695
- ColumnControl.prototype.idx = function () {
2696
- return this._s.columnIdx;
2697
- };
2698
- /**
2699
- * Covert the options from `content` in the DataTable initialisation for this instance into a
2700
- * resolved plugin and options.
2701
- *
2702
- * @param content The dev's supplied configuration for the content
2703
- * @returns Resolved plugin information
2704
- */
2705
- ColumnControl.prototype.resolve = function (content) {
2706
- var plugin = null;
2707
- var config = null;
2708
- var type = null;
2709
- if (typeof content === 'string') {
2710
- // Simple content - uses default options
2711
- type = content;
2712
- plugin = ColumnControl.content[type];
2713
- config = Object.assign({}, plugin === null || plugin === void 0 ? void 0 : plugin.defaults);
2714
- }
2715
- else if (Array.isArray(content)) {
2716
- // An array is a shorthand for a dropdown with its default options
2717
- type = 'dropdown';
2718
- plugin = ColumnControl.content[type];
2719
- config = Object.assign({}, plugin === null || plugin === void 0 ? void 0 : plugin.defaults, {
2720
- content: content
2721
- });
2722
- }
2723
- else if (content.extend) {
2724
- // Content with custom options
2725
- type = content.extend;
2726
- plugin = ColumnControl.content[type];
2727
- config = Object.assign({}, plugin === null || plugin === void 0 ? void 0 : plugin.defaults, content);
2728
- }
2729
- if (!plugin) {
2730
- throw new Error('Unknown ColumnControl content type: ' + type);
2731
- }
2732
- // If the plugin is a wrapper around another type - e.g. the colVisDropdown
2733
- if (plugin.extend) {
2734
- var self_1 = plugin.extend.call(this, config);
2735
- return this.resolve(self_1);
2736
- }
2737
- return {
2738
- config: config,
2739
- type: type,
2740
- plugin: plugin
2741
- };
2742
- };
2743
- /**
2744
- * Get the unique id for the instance
2745
- *
2746
- * @returns Instant unique id
2747
- */
2748
- ColumnControl.prototype.unique = function () {
2749
- return this._s.unique;
2750
- };
2751
- /**
2752
- * Resolve the configured target into a DOM element
2753
- */
2754
- ColumnControl.prototype._target = function () {
2755
- var target = this._c.target;
2756
- var column = this._dt.column(this._s.columnIdx);
2757
- var node;
2758
- var className = 'header';
2759
- // Header row index
2760
- if (typeof target === 'number') {
2761
- node = column.header(target);
2762
- }
2763
- else {
2764
- var parts = target.split(':');
2765
- var isHeader = parts[0] === 'tfoot' ? false : true;
2766
- var row = parts[1] ? parseInt(parts[1]) : 0;
2767
- if (isHeader) {
2768
- node = column.header(row);
2769
- }
2770
- else {
2771
- node = column.footer(row);
2772
- className = 'footer';
2773
- }
2774
- }
2775
- return node.querySelector('div.dt-column-' + className);
2776
- };
2777
- // Classes for common UI
2778
- ColumnControl.Button = Button;
2779
- ColumnControl.CheckList = CheckList;
2780
- ColumnControl.SearchInput = SearchInput;
2781
- /** Content plugins */
2782
- ColumnControl.content = contentTypes;
2783
- /** Defaults for ColumnControl */
2784
- ColumnControl.defaults = {
2785
- className: '',
2786
- content: null,
2787
- target: 0,
2788
- };
2789
- /** SVG icons that can be used by the content plugins */
2790
- ColumnControl.icons = icons;
2791
- /** Version */
2792
- ColumnControl.version = '1.1.1';
2793
- return ColumnControl;
2794
- }());
2795
-
2796
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2797
- * DataTables API integration
2798
- */
2799
- DataTable.ColumnControl = ColumnControl;
2800
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2801
- * DataTables listeners for initialisation
2802
- */
2803
- // Create header / footer rows that don't exist, but have been referenced in the ColumnControl
2804
- // targets. This needs to be done _before_ the header / footer structure is detected.
2805
- $(document).on('i18n.dt', function (e, settings) {
2806
- if (e.namespace !== 'dt') {
2807
- return;
2808
- }
2809
- var api = new DataTable.Api(settings);
2810
- var thead = api.table().header();
2811
- var tableInit = settings.oInit.columnControl;
2812
- var defaultInit = ColumnControl.defaults;
2813
- var baseTargets = [];
2814
- var ackTargets = {};
2815
- // Determine if there is only one header row initially. If there is, we might append more
2816
- // after it. Mark the top row as the header row using `titleRow` in the DataTables configuration
2817
- if (thead.querySelectorAll('tr').length <= 1 && settings.titleRow === null) {
2818
- settings.titleRow = 0;
2819
- }
2820
- identifyTargets(baseTargets, tableInit);
2821
- if (ColumnControl.defaults.content) {
2822
- identifyTargets(baseTargets, defaultInit);
2823
- }
2824
- api.columns().every(function (i) {
2825
- var columnInit = this.init().columnControl;
2826
- identifyTargets(baseTargets, columnInit);
2827
- });
2828
- for (var i = 0; i < baseTargets.length; i++) {
2829
- assetTarget(ackTargets, baseTargets[i], api);
2830
- }
2831
- });
2832
- // Initialisation of ColumnControl instances - has to be done _after_ the header / footer structure
2833
- // is detected by DataTables.
2834
- $(document).on('preInit.dt', function (e, settings) {
2835
- if (e.namespace !== 'dt') {
2836
- return;
2837
- }
2838
- var api = new DataTable.Api(settings);
2839
- var tableInit = settings.oInit.columnControl;
2840
- var defaultInit = ColumnControl.defaults;
2841
- var baseTargets = [];
2842
- identifyTargets(baseTargets, tableInit);
2843
- // Only add the default target if there is actually content for it
2844
- if (ColumnControl.defaults.content) {
2845
- identifyTargets(baseTargets, defaultInit);
2846
- }
2847
- api.columns().every(function (i) {
2848
- var columnInit = this.init().columnControl;
2849
- var targets = identifyTargets(baseTargets.slice(), columnInit);
2850
- for (var i_1 = 0; i_1 < targets.length; i_1++) {
2851
- // Each of the column, table and defaults configuration can be an array of config
2852
- // objects, an array of content, or a configuration object. There might be multiple
2853
- // targets for each one, and they might not exist! Therefore this is more complex
2854
- // than it might be desirable.
2855
- var columnTargetInit = getOptionsForTarget(targets[i_1], columnInit);
2856
- var tableTargetInit = getOptionsForTarget(targets[i_1], tableInit);
2857
- var defaultTargetInit = getOptionsForTarget(targets[i_1], defaultInit);
2858
- if (defaultTargetInit || tableTargetInit || columnTargetInit) {
2859
- new ColumnControl(api, this.index(), Object.assign({}, defaultTargetInit || {}, tableTargetInit || {}, columnTargetInit || {}));
2860
- }
2861
- }
2862
- });
2863
- });
2864
- function searchClear() {
2865
- var ctx = this;
2866
- return this.iterator('column', function (settings, idx) {
2867
- // Note that the listeners for this will not redraw the table.
2868
- ctx.trigger('cc-search-clear', [idx]);
2869
- });
2870
- }
2871
- DataTable.Api.registerPlural('columns().columnControl.searchClear()', 'column().columnControl.searchClear()', searchClear);
2872
- // Legacy (1.0.x)) - was never documented, but was mentioned in the forum
2873
- DataTable.Api.registerPlural('columns().ccSearchClear()', 'column().ccSearchClear()', searchClear);
2874
- DataTable.Api.registerPlural('columns().columnControl.searchList()', 'column().columnControl.searchList()', function (options) {
2875
- return this.iterator('column', function (settings, idx) {
2876
- var fn = settings.aoColumns[idx].columnControlSearchList;
2877
- if (fn) {
2878
- fn(options);
2879
- }
2880
- });
2881
- });
2882
- DataTable.ext.buttons.ccSearchClear = {
2883
- text: function (dt) {
2884
- return dt.i18n('columnControl.buttons.searchClear', 'Clear search');
2885
- },
2886
- init: function (dt, node, config) {
2887
- var _this = this;
2888
- dt.on('draw.DT', function () {
2889
- var enabled = false;
2890
- var glob = !!dt.search();
2891
- // No point in wasting clock cycles if we already know it will be enabled
2892
- if (!glob) {
2893
- dt.columns().every(function () {
2894
- if (this.search.fixed('dtcc') || this.search.fixed('dtcc-list')) {
2895
- enabled = true;
2896
- }
2897
- });
2898
- }
2899
- _this.enable(glob || enabled);
2900
- });
2901
- this.enable(false);
2902
- },
2903
- action: function (e, dt, node, config) {
2904
- dt.search('');
2905
- dt.columns().columnControl.searchClear();
2906
- dt.draw();
2907
- }
2908
- };
2909
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2910
- * Initialisation support - this is more involved than normal as targets might
2911
- * need to be created, and also options needs to be resolved into a standard
2912
- * ColumnControl configuration object, from the various forms allowed in the
2913
- * DataTables configuration.
2914
- */
2915
- /**
2916
- * Given a ColumnControl target, make sure that it exists. If not, create it.
2917
- *
2918
- * @param ackTargets Cache for list of targets that have already been found or created
2919
- * @param target Current target
2920
- * @param dt DataTable API
2921
- * @returns Void
2922
- */
2923
- function assetTarget(ackTargets, target, dt) {
2924
- // Check if we already know about the target - if so, we know that it must already be in place
2925
- if (ackTargets[target]) {
2926
- return;
2927
- }
2928
- var isHeader = true; // false for footer
2929
- var row = 0;
2930
- if (typeof target === 'number') {
2931
- row = target;
2932
- }
2933
- else {
2934
- var parts = target.split(':');
2935
- if (parts[0] === 'tfoot') {
2936
- isHeader = false;
2937
- }
2938
- if (parts[1]) {
2939
- row = parseInt(parts[1]);
2940
- }
2941
- }
2942
- // The header / footer have not yet had their structure read, so they aren't available via
2943
- // the API. As such we need to do our own DOM tweaking
2944
- var node = isHeader ? dt.table().header() : dt.table().footer();
2945
- // If the node doesn't exist yet, we need to create it
2946
- if (!node.querySelectorAll('tr')[row]) {
2947
- var columns = dt.columns().count();
2948
- var tr = createElement('tr');
2949
- tr.setAttribute('data-dt-order', 'disable');
2950
- for (var i = 0; i < columns; i++) {
2951
- tr.appendChild(createElement('td'));
2952
- }
2953
- node.appendChild(tr);
2954
- }
2955
- ackTargets[target] = true;
2956
- }
2957
- /**
2958
- * Given a target, get the config object for it from the parameter passed in
2959
- *
2960
- * @param target ColumnControl target
2961
- * @param input The dev's configuration
2962
- * @returns The resolved config object, if found
2963
- */
2964
- function getOptionsForTarget(target, input) {
2965
- var defaultTarget = ColumnControl.defaults.target;
2966
- var selfTarget;
2967
- if (isIContentArray(input)) {
2968
- // Top level content array - e.g. `columnControl: ['order']`
2969
- if (defaultTarget === target) {
2970
- return {
2971
- target: defaultTarget,
2972
- content: input
2973
- };
2974
- }
2975
- }
2976
- else if (Array.isArray(input)) {
2977
- // Top level array, some items of which will be configuration objects (possibly not all)
2978
- for (var i = 0; i < input.length; i++) {
2979
- var item = input[i];
2980
- if (isIContentArray(item)) {
2981
- // A content array, e.g. the inner array from: `columnControl: [['order']]
2982
- if (defaultTarget === target) {
2983
- return {
2984
- target: defaultTarget,
2985
- content: item
2986
- };
2987
- }
2988
- }
2989
- else if (isIConfig(item)) {
2990
- // A config object, e.g. the object from: `columnControl: [{content: []}]`
2991
- selfTarget = item.target !== undefined ? item.target : defaultTarget;
2992
- if (target === selfTarget) {
2993
- return item;
2994
- }
2995
- }
2996
- else {
2997
- // A content object
2998
- if (target === defaultTarget) {
2999
- return {
3000
- target: defaultTarget,
3001
- content: input
3002
- };
3003
- }
3004
- }
3005
- }
3006
- }
3007
- else if (typeof input === 'object') {
3008
- // An object can be either a config object, or an extending content object
3009
- if (isIConfig(input)) {
3010
- // Config object: columnControl: {content: []}
3011
- selfTarget = input.target !== undefined ? input.target : defaultTarget;
3012
- if (target === selfTarget) {
3013
- return input;
3014
- }
3015
- }
3016
- else {
3017
- // content object: columnControl: [{extend: 'order'}]
3018
- if (target === defaultTarget) {
3019
- return {
3020
- target: defaultTarget,
3021
- content: input
3022
- };
3023
- }
3024
- }
3025
- }
3026
- }
3027
- /**
3028
- * Get a list of all targets from the configuration objects / arrays
3029
- *
3030
- * @param targets Established list of targets - mutated
3031
- * @param input Configuration object / array
3032
- * @returns Updated array
3033
- */
3034
- function identifyTargets(targets, input) {
3035
- function add(target) {
3036
- if (!targets.includes(target)) {
3037
- targets.push(target);
3038
- }
3039
- }
3040
- if (Array.isArray(input)) {
3041
- if (input.length === 0) {
3042
- // Empty array - assume it is empty content
3043
- add(ColumnControl.defaults.target);
3044
- }
3045
- else {
3046
- // Array of options, or an array of content
3047
- input.forEach(function (item) {
3048
- add(typeof item === 'object' && item.target !== undefined
3049
- ? item.target
3050
- : ColumnControl.defaults.target);
3051
- });
3052
- }
3053
- }
3054
- else if (typeof input === 'object') {
3055
- // Full options defined: { target: x, content: [] }
3056
- add(input.target !== undefined ? input.target : ColumnControl.defaults.target);
3057
- }
3058
- return targets;
3059
- }
3060
- /**
3061
- * Check if an item is a configuration object or not
3062
- *
3063
- * @param item Item to check
3064
- * @returns true if it is a config object
3065
- */
3066
- function isIConfig(item) {
3067
- return typeof item === 'object' && item.target !== undefined ? true : false;
3068
- }
3069
- /**
3070
- * Determine if an array contains only content items or not
3071
- *
3072
- * @param arr Array to check
3073
- * @returns true if is content only, false if not (i.e. is an array with configuration objects).
3074
- */
3075
- function isIContentArray(arr) {
3076
- var detectedConfig = false;
3077
- if (!Array.isArray(arr)) {
3078
- return false;
3079
- }
3080
- for (var i = 0; i < arr.length; i++) {
3081
- if (isIConfig(arr[i])) {
3082
- detectedConfig = true;
3083
- break;
3084
- }
3085
- }
3086
- return !detectedConfig;
3087
- }
3088
-
3089
-
3090
- return DataTable;
3091
- }));