GPQAPP

Форк
0
/
dataTables.searchPanes.js 
3171 строка · 153.8 Кб
1
/*! SearchPanes 1.4.0
2
 * 2019-2020 SpryMedia Ltd - datatables.net/license
3
 */
4
(function () {
5
    'use strict';
6

7
    var $;
8
    var dataTable;
9
    function setJQuery(jq) {
10
        $ = jq;
11
        dataTable = jq.fn.dataTable;
12
    }
13
    var SearchPane = /** @class */ (function () {
14
        /**
15
         * Creates the panes, sets up the search function
16
         *
17
         * @param paneSettings The settings for the searchPanes
18
         * @param opts The options for the default features
19
         * @param idx the index of the column for this pane
20
         * @returns {object} the pane that has been created, including the table and the index of the pane
21
         */
22
        function SearchPane(paneSettings, opts, idx, layout, panesContainer, panes) {
23
            var _this = this;
24
            if (panes === void 0) { panes = null; }
25
            // Check that the required version of DataTables is included
26
            if (!dataTable || !dataTable.versionCheck || !dataTable.versionCheck('1.10.0')) {
27
                throw new Error('SearchPane requires DataTables 1.10 or newer');
28
            }
29
            // Check that Select is included
30
            // eslint-disable-next-line no-extra-parens
31
            if (!dataTable.select) {
32
                throw new Error('SearchPane requires Select');
33
            }
34
            var table = new dataTable.Api(paneSettings);
35
            this.classes = $.extend(true, {}, SearchPane.classes);
36
            // Get options from user
37
            this.c = $.extend(true, {}, SearchPane.defaults, opts);
38
            if (opts !== undefined && opts.hideCount !== undefined && opts.viewCount === undefined) {
39
                this.c.viewCount = !this.c.hideCount;
40
            }
41
            this.customPaneSettings = panes;
42
            this.s = {
43
                cascadeRegen: false,
44
                clearing: false,
45
                colOpts: [],
46
                deselect: false,
47
                displayed: false,
48
                dt: table,
49
                dtPane: undefined,
50
                filteringActive: false,
51
                firstSet: true,
52
                forceViewTotal: false,
53
                index: idx,
54
                indexes: [],
55
                lastCascade: false,
56
                lastSelect: false,
57
                listSet: false,
58
                name: undefined,
59
                redraw: false,
60
                rowData: {
61
                    arrayFilter: [],
62
                    arrayOriginal: [],
63
                    arrayTotals: [],
64
                    bins: {},
65
                    binsOriginal: {},
66
                    binsTotal: {},
67
                    filterMap: new Map(),
68
                    totalOptions: 0
69
                },
70
                scrollTop: 0,
71
                searchFunction: undefined,
72
                selectPresent: false,
73
                serverSelect: [],
74
                serverSelecting: false,
75
                showFiltered: false,
76
                tableLength: null,
77
                updating: false
78
            };
79
            var rowLength = table.columns().eq(0).toArray().length;
80
            this.colExists = this.s.index < rowLength;
81
            // Add extra elements to DOM object including clear and hide buttons
82
            this.c.layout = layout;
83
            var layVal = parseInt(layout.split('-')[1], 10);
84
            this.dom = {
85
                buttonGroup: $('<div/>').addClass(this.classes.buttonGroup),
86
                clear: $('<button type="button">&#215;</button>')
87
                    .addClass(this.classes.disabledButton)
88
                    .attr('disabled', 'true')
89
                    .addClass(this.classes.paneButton)
90
                    .addClass(this.classes.clearButton),
91
                collapseButton: $('<button type="button"><span class="dtsp-caret">&#x5e;</span></button>')
92
                    .addClass(this.classes.paneButton)
93
                    .addClass(this.classes.collapseButton),
94
                container: $('<div/>')
95
                    .addClass(this.classes.container)
96
                    .addClass(this.classes.layout +
97
                    (layVal < 10 ? layout : layout.split('-')[0] + '-9')),
98
                countButton: $('<button type="button"></button>')
99
                    .addClass(this.classes.paneButton)
100
                    .addClass(this.classes.countButton),
101
                dtP: $('<table><thead><tr><th>' +
102
                    (this.colExists
103
                        ? $(table.column(this.colExists ? this.s.index : 0).header()).text()
104
                        : this.customPaneSettings.header || 'Custom Pane') + '</th><th/></tr></thead></table>'),
105
                lower: $('<div/>').addClass(this.classes.subRow2).addClass(this.classes.narrowButton),
106
                nameButton: $('<button type="button"></button>')
107
                    .addClass(this.classes.paneButton)
108
                    .addClass(this.classes.nameButton),
109
                panesContainer: panesContainer,
110
                searchBox: $('<input/>').addClass(this.classes.paneInputButton).addClass(this.classes.search),
111
                searchButton: $('<button type = "button" class="' + this.classes.searchIcon + '"></button>')
112
                    .addClass(this.classes.paneButton),
113
                searchCont: $('<div/>').addClass(this.classes.searchCont),
114
                searchLabelCont: $('<div/>').addClass(this.classes.searchLabelCont),
115
                topRow: $('<div/>').addClass(this.classes.topRow),
116
                upper: $('<div/>').addClass(this.classes.subRow1).addClass(this.classes.narrowSearch)
117
            };
118
            this.s.displayed = false;
119
            table = this.s.dt;
120
            this.selections = [];
121
            this.s.colOpts = this.colExists ? this._getOptions() : this._getBonusOptions();
122
            var colOpts = this.s.colOpts;
123
            var clear = $('<button type="button">X</button>').addClass(this.classes.paneButton);
124
            clear.text(table.i18n('searchPanes.clearPane', this.c.i18n.clearPane));
125
            this.dom.container.addClass(colOpts.className);
126
            this.dom.container.addClass(this.customPaneSettings !== null && this.customPaneSettings.className !== undefined
127
                ? this.customPaneSettings.className
128
                : '');
129
            // Set the value of name incase ordering is desired
130
            if (this.s.colOpts.name !== undefined) {
131
                this.s.name = this.s.colOpts.name;
132
            }
133
            else if (this.customPaneSettings !== null && this.customPaneSettings.name !== undefined) {
134
                this.s.name = this.customPaneSettings.name;
135
            }
136
            else {
137
                this.s.name = this.colExists ?
138
                    $(table.column(this.s.index).header()).text() :
139
                    this.customPaneSettings.header || 'Custom Pane';
140
            }
141
            $(panesContainer).append(this.dom.container);
142
            var tableNode = table.table(0).node();
143
            // Custom search function for table
144
            this.s.searchFunction = function (settings, searchData, dataIndex, origData) {
145
                // If no data has been selected then show all
146
                if (_this.selections.length === 0) {
147
                    return true;
148
                }
149
                if (settings.nTable !== tableNode) {
150
                    return true;
151
                }
152
                var filter = null;
153
                if (_this.colExists) {
154
                    // Get the current filtered data
155
                    filter = searchData[_this.s.index];
156
                    if (colOpts.orthogonal.filter !== 'filter') {
157
                        // get the filter value from the map
158
                        filter = _this.s.rowData.filterMap.get(dataIndex);
159
                        if (filter instanceof $.fn.dataTable.Api) {
160
                            // eslint-disable-next-line no-extra-parens
161
                            filter = filter.toArray();
162
                        }
163
                    }
164
                }
165
                return _this._search(filter, dataIndex);
166
            };
167
            $.fn.dataTable.ext.search.push(this.s.searchFunction);
168
            // If the clear button for this pane is clicked clear the selections
169
            if (this.c.clear) {
170
                clear.on('click', function () {
171
                    var searches = _this.dom.container.find('.' + _this.classes.search.replace(/\s+/g, '.'));
172
                    searches.each(function () {
173
                        $(this).val('');
174
                        $(this).trigger('input');
175
                    });
176
                    _this.clearPane();
177
                });
178
            }
179
            // Sometimes the top row of the panes containing the search box and ordering buttons appears
180
            //  weird if the width of the panes is lower than expected, this fixes the design.
181
            // Equally this may occur when the table is resized.
182
            table.on('draw.dtsp', function () {
183
                _this.adjustTopRow();
184
            });
185
            table.on('buttons-action', function () {
186
                _this.adjustTopRow();
187
            });
188
            // When column-reorder is present and the columns are moved, it is necessary to
189
            //  reassign all of the panes indexes to the new index of the column.
190
            table.on('column-reorder.dtsp', function (e, settings, details) {
191
                _this.s.index = details.mapping[_this.s.index];
192
            });
193
            return this;
194
        }
195
        /**
196
         * Adds a row to the panes table
197
         *
198
         * @param display the value to be displayed to the user
199
         * @param filter the value to be filtered on when searchpanes is implemented
200
         * @param shown the number of rows in the table that are currently visible matching this criteria
201
         * @param total the total number of rows in the table that match this criteria
202
         * @param sort the value to be sorted in the pane table
203
         * @param type the value of which the type is to be derived from
204
         */
205
        SearchPane.prototype.addRow = function (display, filter, shown, total, sort, type, className) {
206
            var index;
207
            for (var _i = 0, _a = this.s.indexes; _i < _a.length; _i++) {
208
                var entry = _a[_i];
209
                if (entry.filter === filter) {
210
                    index = entry.index;
211
                }
212
            }
213
            if (index === undefined) {
214
                index = this.s.indexes.length;
215
                this.s.indexes.push({ filter: filter, index: index });
216
            }
217
            return this.s.dtPane.row.add({
218
                className: className,
219
                display: display !== '' ?
220
                    display :
221
                    this.emptyMessage(),
222
                filter: filter,
223
                index: index,
224
                shown: shown,
225
                sort: sort,
226
                total: total,
227
                type: type
228
            });
229
        };
230
        /**
231
         * Adjusts the layout of the top row when the screen is resized
232
         */
233
        SearchPane.prototype.adjustTopRow = function () {
234
            var subContainers = this.dom.container.find('.' + this.classes.subRowsContainer.replace(/\s+/g, '.'));
235
            var subRow1 = this.dom.container.find('.' + this.classes.subRow1.replace(/\s+/g, '.'));
236
            var subRow2 = this.dom.container.find('.' + this.classes.subRow2.replace(/\s+/g, '.'));
237
            var topRow = this.dom.container.find('.' + this.classes.topRow.replace(/\s+/g, '.'));
238
            // If the width is 0 then it is safe to assume that the pane has not yet been displayed.
239
            //  Even if it has, if the width is 0 it won't make a difference if it has the narrow class or not
240
            if (($(subContainers[0]).width() < 252 || $(topRow[0]).width() < 252) && $(subContainers[0]).width() !== 0) {
241
                $(subContainers[0]).addClass(this.classes.narrow);
242
                $(subRow1[0]).addClass(this.classes.narrowSub).removeClass(this.classes.narrowSearch);
243
                $(subRow2[0]).addClass(this.classes.narrowSub).removeClass(this.classes.narrowButton);
244
            }
245
            else {
246
                $(subContainers[0]).removeClass(this.classes.narrow);
247
                $(subRow1[0]).removeClass(this.classes.narrowSub).addClass(this.classes.narrowSearch);
248
                $(subRow2[0]).removeClass(this.classes.narrowSub).addClass(this.classes.narrowButton);
249
            }
250
        };
251
        /**
252
         * In the case of a rebuild there is potential for new data to have been included or removed
253
         * so all of the rowData must be reset as a precaution.
254
         */
255
        SearchPane.prototype.clearData = function () {
256
            this.s.rowData = {
257
                arrayFilter: [],
258
                arrayOriginal: [],
259
                arrayTotals: [],
260
                bins: {},
261
                binsOriginal: {},
262
                binsTotal: {},
263
                filterMap: new Map(),
264
                totalOptions: 0
265
            };
266
        };
267
        /**
268
         * Clear the selections in the pane
269
         */
270
        SearchPane.prototype.clearPane = function () {
271
            // Deselect all rows which are selected and update the table and filter count.
272
            this.s.dtPane.rows({ selected: true }).deselect();
273
            this.updateTable();
274
            return this;
275
        };
276
        /**
277
         * Collapses the pane so that only the header is displayed
278
         */
279
        SearchPane.prototype.collapse = function () {
280
            var _this = this;
281
            if (!this.s.displayed ||
282
                (!this.c.collapse && this.s.colOpts.collapse !== true ||
283
                    this.s.colOpts.collapse === false)) {
284
                return;
285
            }
286
            this.dom.collapseButton.addClass(this.classes.rotated);
287
            $(this.s.dtPane.table().container()).addClass(this.classes.hidden);
288
            this.dom.topRow.addClass(this.classes.bordered);
289
            this.dom.countButton.addClass(this.classes.disabledButton);
290
            this.dom.nameButton.addClass(this.classes.disabledButton);
291
            this.dom.searchButton.addClass(this.classes.disabledButton);
292
            this.dom.topRow.one('click', function () {
293
                _this.show();
294
            });
295
        };
296
        /**
297
         * Strips all of the SearchPanes elements from the document and turns all of the listeners for the buttons off
298
         */
299
        SearchPane.prototype.destroy = function () {
300
            if (this.s.dtPane !== undefined) {
301
                this.s.dtPane.off('.dtsp');
302
            }
303
            this.dom.nameButton.off('.dtsp');
304
            this.dom.collapseButton.off('.dtsp');
305
            this.dom.countButton.off('.dtsp');
306
            this.dom.clear.off('.dtsp');
307
            this.dom.searchButton.off('.dtsp');
308
            this.dom.container.remove();
309
            var searchIdx = $.fn.dataTable.ext.search.indexOf(this.s.searchFunction);
310
            while (searchIdx !== -1) {
311
                $.fn.dataTable.ext.search.splice(searchIdx, 1);
312
                searchIdx = $.fn.dataTable.ext.search.indexOf(this.s.searchFunction);
313
            }
314
            // If the datatables have been defined for the panes then also destroy these
315
            if (this.s.dtPane !== undefined) {
316
                this.s.dtPane.destroy();
317
            }
318
            this.s.listSet = false;
319
        };
320
        /**
321
         * Getting the legacy message is a little complex due a legacy parameter
322
         */
323
        SearchPane.prototype.emptyMessage = function () {
324
            var def = this.c.i18n.emptyMessage;
325
            // Legacy parameter support
326
            if (this.c.emptyMessage) {
327
                def = this.c.emptyMessage;
328
            }
329
            // Override per column
330
            if (this.s.colOpts.emptyMessage !== false && this.s.colOpts.emptyMessage !== null) {
331
                def = this.s.colOpts.emptyMessage;
332
            }
333
            return this.s.dt.i18n('searchPanes.emptyMessage', def);
334
        };
335
        /**
336
         * Updates the number of filters that have been applied in the title
337
         */
338
        SearchPane.prototype.getPaneCount = function () {
339
            return this.s.dtPane !== undefined ?
340
                this.s.dtPane.rows({ selected: true }).data().toArray().length :
341
                0;
342
        };
343
        /**
344
         * Rebuilds the panes from the start having deleted the old ones
345
         *
346
         * @param? last boolean to indicate if this is the last pane a selection was made in
347
         * @param? dataIn data to be used in buildPane
348
         * @param? init Whether this is the initial draw or not
349
         * @param? maintainSelection Whether the current selections are to be maintained over rebuild
350
         */
351
        SearchPane.prototype.rebuildPane = function (last, dataIn, init, maintainSelection) {
352
            if (last === void 0) { last = false; }
353
            if (dataIn === void 0) { dataIn = null; }
354
            if (init === void 0) { init = null; }
355
            if (maintainSelection === void 0) { maintainSelection = false; }
356
            this.clearData();
357
            var selectedRows = [];
358
            this.s.serverSelect = [];
359
            var prevEl = null;
360
            // When rebuilding strip all of the HTML Elements out of the container and start from scratch
361
            if (this.s.dtPane !== undefined) {
362
                if (maintainSelection) {
363
                    if (!this.s.dt.page.info().serverSide) {
364
                        selectedRows = this.s.dtPane.rows({ selected: true }).data().toArray();
365
                    }
366
                    else {
367
                        this.s.serverSelect = this.s.dtPane.rows({ selected: true }).data().toArray();
368
                    }
369
                }
370
                this.s.dtPane.clear().destroy();
371
                prevEl = this.dom.container.prev();
372
                this.destroy();
373
                this.s.dtPane = undefined;
374
                $.fn.dataTable.ext.search.push(this.s.searchFunction);
375
            }
376
            this.dom.container.removeClass(this.classes.hidden);
377
            this.s.displayed = false;
378
            this._buildPane(!this.s.dt.page.info().serverSide ?
379
                selectedRows :
380
                this.s.serverSelect, last, dataIn, init, prevEl);
381
            return this;
382
        };
383
        /**
384
         * removes the pane from the page and sets the displayed property to false.
385
         */
386
        SearchPane.prototype.removePane = function () {
387
            this.s.displayed = false;
388
            this.dom.container.hide();
389
        };
390
        /**
391
         * Resizes the pane based on the layout that is passed in
392
         *
393
         * @param layout the layout to be applied to this pane
394
         */
395
        SearchPane.prototype.resize = function (layout) {
396
            this.c.layout = layout;
397
            var layVal = parseInt(layout.split('-')[1], 10);
398
            this.dom.container
399
                .removeClass()
400
                .addClass(this.classes.container)
401
                .addClass(this.classes.layout +
402
                (layVal < 10 ? layout : layout.split('-')[0] + '-9'))
403
                .addClass(this.s.colOpts.className)
404
                .addClass(this.customPaneSettings !== null && this.customPaneSettings.className !== undefined
405
                ? this.customPaneSettings.className
406
                : '')
407
                .addClass(this.classes.show);
408
            this.adjustTopRow();
409
        };
410
        /**
411
         * Sets the cascadeRegen property of the pane. Accessible from above because as SearchPanes.ts
412
         * deals with the rebuilds.
413
         *
414
         * @param val the boolean value that the cascadeRegen property is to be set to
415
         */
416
        SearchPane.prototype.setCascadeRegen = function (val) {
417
            this.s.cascadeRegen = val;
418
        };
419
        /**
420
         * This function allows the clearing property to be assigned. This is used when implementing cascadePane.
421
         * In setting this to true for the clearing of the panes selection on the deselects it forces the pane to
422
         * repopulate from the entire dataset not just the displayed values.
423
         *
424
         * @param val the boolean value which the clearing property is to be assigned
425
         */
426
        SearchPane.prototype.setClear = function (val) {
427
            this.s.clearing = val;
428
        };
429
        /**
430
         * Expands the pane from the collapsed state
431
         */
432
        SearchPane.prototype.show = function () {
433
            if (!this.s.displayed) {
434
                return;
435
            }
436
            this.dom.collapseButton.removeClass(this.classes.rotated);
437
            $(this.s.dtPane.table().container()).removeClass(this.classes.hidden);
438
            this.dom.topRow.removeClass(this.classes.bordered);
439
            this.dom.countButton.removeClass(this.classes.disabledButton);
440
            this.dom.nameButton.removeClass(this.classes.disabledButton);
441
            this.dom.searchButton.removeClass(this.classes.disabledButton);
442
        };
443
        /**
444
         * Updates the values of all of the panes
445
         *
446
         * @param draw whether this has been triggered by a draw event or not
447
         */
448
        SearchPane.prototype.updatePane = function (draw) {
449
            if (draw === void 0) { draw = false; }
450
            this.s.updating = true;
451
            this._updateCommon(draw);
452
            this.s.updating = false;
453
        };
454
        /**
455
         * Updates the panes if one of the options to do so has been set to true
456
         * rather than the filtered message when using viewTotal.
457
         */
458
        SearchPane.prototype.updateTable = function () {
459
            var selectedRows = this.s.dtPane.rows({ selected: true }).data().toArray();
460
            this.selections = selectedRows;
461
            this._searchExtras();
462
            // If either of the options that effect how the panes are displayed are selected then update the Panes
463
            if (this.c.cascadePanes || this.c.viewTotal) {
464
                this.updatePane();
465
            }
466
        };
467
        /**
468
         * Sets the listeners for the pane.
469
         *
470
         * Having it in it's own function makes it easier to only set them once
471
         */
472
        SearchPane.prototype._setListeners = function () {
473
            var _this = this;
474
            var rowData = this.s.rowData;
475
            var t0;
476
            // When an item is selected on the pane, add these to the array which holds selected items.
477
            // Custom search will perform.
478
            this.s.dtPane.off('select.dtsp');
479
            this.s.dtPane.on('select.dtsp', function () {
480
                clearTimeout(t0);
481
                if (_this.s.dt.page.info().serverSide && !_this.s.updating) {
482
                    if (!_this.s.serverSelecting) {
483
                        _this.s.serverSelect = _this.s.dtPane.rows({ selected: true }).data().toArray();
484
                        _this.s.scrollTop = $(_this.s.dtPane.table().node()).parent()[0].scrollTop;
485
                        _this.s.selectPresent = true;
486
                        _this.s.dt.draw(false);
487
                    }
488
                }
489
                else if (!_this.s.updating) {
490
                    _this.s.selectPresent = true;
491
                    _this._makeSelection();
492
                    _this.s.selectPresent = false;
493
                }
494
                _this.dom.clear.removeClass(_this.classes.disabledButton).removeAttr('disabled');
495
            });
496
            // When an item is deselected on the pane, re add the currently selected items to the array
497
            // which holds selected items. Custom search will be performed.
498
            this.s.dtPane.off('deselect.dtsp');
499
            this.s.dtPane.on('deselect.dtsp', function () {
500
                t0 = setTimeout(function () {
501
                    _this.s.scrollTop = $(_this.s.dtPane.table().node()).parent()[0].scrollTop;
502
                    if (_this.s.dt.page.info().serverSide && !_this.s.updating) {
503
                        if (!_this.s.serverSelecting) {
504
                            _this.s.serverSelect = _this.s.dtPane.rows({ selected: true }).data().toArray();
505
                            _this.s.deselect = true;
506
                            _this.s.dt.draw(false);
507
                        }
508
                    }
509
                    else {
510
                        _this.s.deselect = true;
511
                        _this._makeSelection();
512
                        _this.s.deselect = false;
513
                    }
514
                    if (_this.s.dtPane.rows({ selected: true }).data().toArray().length === 0) {
515
                        _this.dom.clear.addClass(_this.classes.disabledButton).attr('disabled', 'true');
516
                    }
517
                }, 50);
518
            });
519
            // If we attempty to turn off this event then it will ruin behaviour in other panes
520
            //  so need to make sure that it is only done once
521
            if (this.s.firstSet) {
522
                this.s.firstSet = false;
523
                // When saving the state store all of the selected rows for preselection next time around
524
                this.s.dt.on('stateSaveParams.dtsp', function (e, settings, data) {
525
                    // If the data being passed in is empty then state clear must have occured
526
                    // so clear the panes state as well
527
                    if ($.isEmptyObject(data)) {
528
                        _this.s.dtPane.state.clear();
529
                        return;
530
                    }
531
                    var selected = [];
532
                    var searchTerm;
533
                    var order;
534
                    var bins;
535
                    var arrayFilter;
536
                    var collapsed;
537
                    // Get all of the data needed for the state save from the pane
538
                    if (_this.s.dtPane !== undefined) {
539
                        selected = _this.s.dtPane
540
                            .rows({ selected: true })
541
                            .data()
542
                            .map(function (item) { return item.filter.toString(); })
543
                            .toArray();
544
                        searchTerm = _this.dom.searchBox.val();
545
                        order = _this.s.dtPane.order();
546
                        bins = rowData.binsOriginal;
547
                        arrayFilter = rowData.arrayOriginal;
548
                        collapsed = _this.dom.collapseButton.hasClass(_this.classes.rotated);
549
                    }
550
                    if (data.searchPanes === undefined) {
551
                        data.searchPanes = {};
552
                    }
553
                    if (data.searchPanes.panes === undefined) {
554
                        data.searchPanes.panes = [];
555
                    }
556
                    for (var i = 0; i < data.searchPanes.panes.length; i++) {
557
                        if (data.searchPanes.panes[i].id === _this.s.index) {
558
                            data.searchPanes.panes.splice(i, 1);
559
                            i--;
560
                        }
561
                    }
562
                    // Add the panes data to the state object
563
                    data.searchPanes.panes.push({
564
                        arrayFilter: arrayFilter,
565
                        bins: bins,
566
                        collapsed: collapsed,
567
                        id: _this.s.index,
568
                        order: order,
569
                        searchTerm: searchTerm,
570
                        selected: selected
571
                    });
572
                });
573
            }
574
            this.s.dtPane.off('user-select.dtsp');
575
            this.s.dtPane.on('user-select.dtsp', function (e, _dt, type, cell, originalEvent) {
576
                originalEvent.stopPropagation();
577
            });
578
            this.s.dtPane.off('draw.dtsp');
579
            this.s.dtPane.on('draw.dtsp', function () {
580
                _this.adjustTopRow();
581
            });
582
            // When the button to order by the name of the options is clicked then
583
            //  change the ordering to whatever it isn't currently
584
            this.dom.nameButton.off('click.dtsp');
585
            this.dom.nameButton.on('click.dtsp', function () {
586
                var currentOrder = _this.s.dtPane.order()[0][1];
587
                _this.s.dtPane.order([0, currentOrder === 'asc' ? 'desc' : 'asc']).draw();
588
                // This state save is required so that the ordering of the panes is maintained
589
                _this.s.dt.state.save();
590
            });
591
            // When the button to order by the number of entries in the column is clicked then
592
            //  change the ordering to whatever it isn't currently
593
            this.dom.countButton.off('click.dtsp');
594
            this.dom.countButton.on('click.dtsp', function () {
595
                var currentOrder = _this.s.dtPane.order()[0][1];
596
                _this.s.dtPane.order([1, currentOrder === 'asc' ? 'desc' : 'asc']).draw();
597
                // This state save is required so that the ordering of the panes is maintained
598
                _this.s.dt.state.save();
599
            });
600
            // When the button to order by the number of entries in the column is clicked then
601
            //  change the ordering to whatever it isn't currently
602
            this.dom.collapseButton.off('click.dtsp');
603
            this.dom.collapseButton.on('click.dtsp', function (e) {
604
                e.stopPropagation();
605
                var container = $(_this.s.dtPane.table().container());
606
                // Toggle the classes
607
                _this.dom.collapseButton.toggleClass(_this.classes.rotated);
608
                container.toggleClass(_this.classes.hidden);
609
                _this.dom.topRow.toggleClass(_this.classes.bordered);
610
                _this.dom.countButton.toggleClass(_this.classes.disabledButton);
611
                _this.dom.nameButton.toggleClass(_this.classes.disabledButton);
612
                _this.dom.searchButton.toggleClass(_this.classes.disabledButton);
613
                if (container.hasClass(_this.classes.hidden)) {
614
                    _this.dom.topRow.on('click', function () { return _this.dom.collapseButton.click(); });
615
                }
616
                else {
617
                    _this.dom.topRow.off('click');
618
                }
619
                _this.s.dt.state.save();
620
                return;
621
            });
622
            // When the clear button is clicked reset the pane
623
            this.dom.clear.off('click.dtsp');
624
            this.dom.clear.on('click.dtsp', function () {
625
                var searches = _this.dom.container.find('.' + _this.classes.search.replace(/ /g, '.'));
626
                searches.each(function () {
627
                    // set the value of the search box to be an empty string and then search on that, effectively reseting
628
                    $(this).val('');
629
                    $(this).trigger('input');
630
                });
631
                _this.clearPane();
632
            });
633
            // When the search button is clicked then draw focus to the search box
634
            this.dom.searchButton.off('click.dtsp');
635
            this.dom.searchButton.on('click.dtsp', function () {
636
                _this.dom.searchBox.focus();
637
            });
638
            // When a character is inputted into the searchbox search the pane for matching values.
639
            // Doing it this way means that no button has to be clicked to trigger a search, it is done asynchronously
640
            this.dom.searchBox.off('click.dtsp');
641
            this.dom.searchBox.on('input.dtsp', function () {
642
                var searchval = _this.dom.searchBox.val();
643
                _this.s.dtPane.search(searchval).draw();
644
                if (typeof searchval === 'string' &&
645
                    (searchval.length > 0 ||
646
                        searchval.length === 0 && _this.s.dtPane.rows({ selected: true }).data().toArray().length > 0)) {
647
                    _this.dom.clear.removeClass(_this.classes.disabledButton).removeAttr('disabled');
648
                }
649
                else {
650
                    _this.dom.clear.addClass(_this.classes.disabledButton).attr('disabled', 'true');
651
                }
652
                // This state save is required so that the searching on the panes is maintained
653
                _this.s.dt.state.save();
654
            });
655
            return true;
656
        };
657
        /**
658
         * Takes in potentially undetected rows and adds them to the array if they are not yet featured
659
         *
660
         * @param filter the filter value of the potential row
661
         * @param display the display value of the potential row
662
         * @param sort the sort value of the potential row
663
         * @param type the type value of the potential row
664
         * @param arrayFilter the array to be populated
665
         * @param bins the bins to be populated
666
         */
667
        SearchPane.prototype._addOption = function (filter, display, sort, type, arrayFilter, bins) {
668
            // If the filter is an array then take a note of this, and add the elements to the arrayFilter array
669
            if (Array.isArray(filter) || filter instanceof dataTable.Api) {
670
                // Convert to an array so that we can work with it
671
                if (filter instanceof dataTable.Api) {
672
                    filter = filter.toArray();
673
                    display = display.toArray();
674
                }
675
                if (filter.length === display.length) {
676
                    for (var i = 0; i < filter.length; i++) {
677
                        // If we haven't seen this row before add it
678
                        if (!bins[filter[i]]) {
679
                            bins[filter[i]] = 1;
680
                            arrayFilter.push({
681
                                display: display[i],
682
                                filter: filter[i],
683
                                sort: sort[i],
684
                                type: type[i]
685
                            });
686
                        }
687
                        // Otherwise just increment the count
688
                        else {
689
                            bins[filter[i]]++;
690
                        }
691
                        this.s.rowData.totalOptions++;
692
                    }
693
                    return;
694
                }
695
                else {
696
                    throw new Error('display and filter not the same length');
697
                }
698
            }
699
            // If the values were affected by othogonal data and are not an array then check if it is already present
700
            else if (typeof this.s.colOpts.orthogonal === 'string') {
701
                if (!bins[filter]) {
702
                    bins[filter] = 1;
703
                    arrayFilter.push({
704
                        display: display,
705
                        filter: filter,
706
                        sort: sort,
707
                        type: type
708
                    });
709
                    this.s.rowData.totalOptions++;
710
                }
711
                else {
712
                    bins[filter]++;
713
                    this.s.rowData.totalOptions++;
714
                    return;
715
                }
716
            }
717
            // Otherwise we must just be adding an option
718
            else {
719
                arrayFilter.push({
720
                    display: display,
721
                    filter: filter,
722
                    sort: sort,
723
                    type: type
724
                });
725
            }
726
        };
727
        /**
728
         * Method to construct the actual pane.
729
         *
730
         * @param selectedRows previously selected Rows to be reselected
731
         * @last boolean to indicate whether this pane was the last one to have a selection made
732
         */
733
        SearchPane.prototype._buildPane = function (selectedRows, last, dataIn, init, prevEl) {
734
            var _this = this;
735
            if (selectedRows === void 0) { selectedRows = []; }
736
            if (last === void 0) { last = false; }
737
            if (dataIn === void 0) { dataIn = null; }
738
            if (init === void 0) { init = null; }
739
            if (prevEl === void 0) { prevEl = null; }
740
            // Aliases
741
            this.selections = [];
742
            var table = this.s.dt;
743
            var column = table.column(this.colExists ? this.s.index : 0);
744
            var colOpts = this.s.colOpts;
745
            var rowData = this.s.rowData;
746
            // Other Variables
747
            var countMessage = table.i18n('searchPanes.count', this.c.i18n.count);
748
            var filteredMessage = table.i18n('searchPanes.countFiltered', this.c.i18n.countFiltered);
749
            var loadedFilter = table.state.loaded();
750
            // If the listeners have not been set yet then using the latest state may result in funny errors
751
            if (this.s.listSet) {
752
                loadedFilter = table.state();
753
            }
754
            // If it is not a custom pane in place
755
            if (this.colExists) {
756
                var idx = -1;
757
                if (loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.panes) {
758
                    for (var i = 0; i < loadedFilter.searchPanes.panes.length; i++) {
759
                        if (loadedFilter.searchPanes.panes[i].id === this.s.index) {
760
                            idx = i;
761
                            break;
762
                        }
763
                    }
764
                }
765
                // Perform checks that do not require populate pane to run
766
                if ((colOpts.show === false ||
767
                    colOpts.show !== undefined && colOpts.show !== true) &&
768
                    idx === -1) {
769
                    this.dom.container.addClass(this.classes.hidden);
770
                    this.s.displayed = false;
771
                    return false;
772
                }
773
                else if (colOpts.show === true || idx !== -1) {
774
                    this.s.displayed = true;
775
                }
776
                if (!this.s.dt.page.info().serverSide &&
777
                    (dataIn === null ||
778
                        dataIn.searchPanes === null ||
779
                        dataIn.searchPanes.options === null)) {
780
                    // Only run populatePane if the data has not been collected yet
781
                    if (rowData.arrayFilter.length === 0) {
782
                        this._populatePane(last);
783
                        this.s.rowData.totalOptions = 0;
784
                        this._detailsPane();
785
                        rowData.arrayOriginal = rowData.arrayTotals;
786
                        rowData.binsOriginal = rowData.binsTotal;
787
                    }
788
                    var binLength = Object.keys(rowData.binsOriginal).length;
789
                    var uniqueRatio = this._uniqueRatio(binLength, table.rows()[0].length);
790
                    // Don't show the pane if there isn't enough variance in the data, or there is only 1 entry
791
                    //  for that pane
792
                    if (this.s.displayed === false &&
793
                        ((colOpts.show === undefined && colOpts.threshold === null ?
794
                            uniqueRatio > this.c.threshold :
795
                            uniqueRatio > colOpts.threshold) ||
796
                            colOpts.show !== true && binLength <= 1)) {
797
                        this.dom.container.addClass(this.classes.hidden);
798
                        this.s.displayed = false;
799
                        return;
800
                    }
801
                    // If the option viewTotal is true then find
802
                    // the total count for the whole table to display alongside the displayed count
803
                    if (this.c.viewTotal && rowData.arrayTotals.length === 0) {
804
                        this.s.rowData.totalOptions = 0;
805
                        this._detailsPane();
806
                    }
807
                    else {
808
                        rowData.binsTotal = rowData.bins;
809
                    }
810
                    this.dom.container.addClass(this.classes.show);
811
                    this.s.displayed = true;
812
                }
813
                else if (dataIn !== null && dataIn.searchPanes !== null && dataIn.searchPanes.options !== null) {
814
                    if (dataIn.tableLength !== undefined) {
815
                        this.s.tableLength = dataIn.tableLength;
816
                        this.s.rowData.totalOptions = this.s.tableLength;
817
                    }
818
                    else if (this.s.tableLength === null || table.rows()[0].length > this.s.tableLength) {
819
                        this.s.tableLength = table.rows()[0].length;
820
                        this.s.rowData.totalOptions = this.s.tableLength;
821
                    }
822
                    var colTitle = table.column(this.s.index).dataSrc();
823
                    if (dataIn.searchPanes.options[colTitle] !== undefined) {
824
                        for (var _i = 0, _a = dataIn.searchPanes.options[colTitle]; _i < _a.length; _i++) {
825
                            var dataPoint = _a[_i];
826
                            this.s.rowData.arrayFilter.push({
827
                                display: dataPoint.label,
828
                                filter: dataPoint.value,
829
                                sort: dataPoint.label,
830
                                type: dataPoint.label
831
                            });
832
                            this.s.rowData.bins[dataPoint.value] = this.c.viewTotal || this.c.cascadePanes ?
833
                                dataPoint.count :
834
                                dataPoint.total;
835
                            this.s.rowData.binsTotal[dataPoint.value] = dataPoint.total;
836
                        }
837
                    }
838
                    var binLength = Object.keys(rowData.binsTotal).length;
839
                    var uniqueRatio = this._uniqueRatio(binLength, this.s.tableLength);
840
                    // Don't show the pane if there isnt enough variance in the data, or there is only 1 entry for that pane
841
                    if (this.s.displayed === false &&
842
                        ((colOpts.show === undefined && colOpts.threshold === null ?
843
                            uniqueRatio > this.c.threshold :
844
                            uniqueRatio > colOpts.threshold) ||
845
                            colOpts.show !== true && binLength <= 1)) {
846
                        this.dom.container.addClass(this.classes.hidden);
847
                        this.s.displayed = false;
848
                        return;
849
                    }
850
                    this.s.rowData.arrayOriginal = this.s.rowData.arrayFilter;
851
                    this.s.rowData.binsOriginal = this.s.rowData.bins;
852
                    this.s.displayed = true;
853
                }
854
            }
855
            else {
856
                this.s.displayed = true;
857
            }
858
            // If the variance is accceptable then display the search pane
859
            this._displayPane();
860
            if (!this.s.listSet) {
861
                // Here, when the state is loaded if the data object on the original table is empty,
862
                //  then a state.clear() must have occurred, so delete all of the panes tables state objects too.
863
                this.dom.dtP.on('stateLoadParams.dt', function (e, settings, data) {
864
                    if ($.isEmptyObject(table.state.loaded())) {
865
                        $.each(data, function (index, value) {
866
                            delete data[index];
867
                        });
868
                    }
869
                });
870
            }
871
            // Add the container to the document in its original location
872
            if (prevEl !== null && this.dom.panesContainer.has(prevEl).length > 0) {
873
                this.dom.container.insertAfter(prevEl);
874
            }
875
            else {
876
                this.dom.panesContainer.prepend(this.dom.container);
877
            }
878
            // Declare the datatable for the pane
879
            var errMode = $.fn.dataTable.ext.errMode;
880
            $.fn.dataTable.ext.errMode = 'none';
881
            // eslint-disable-next-line no-extra-parens
882
            var haveScroller = dataTable.Scroller;
883
            this.s.dtPane = this.dom.dtP.DataTable($.extend(true, {
884
                columnDefs: [
885
                    {
886
                        className: 'dtsp-nameColumn',
887
                        data: 'display',
888
                        render: function (data, type, row) {
889
                            if (type === 'sort') {
890
                                return row.sort;
891
                            }
892
                            else if (type === 'type') {
893
                                return row.type;
894
                            }
895
                            var message;
896
                            message =
897
                                (_this.s.filteringActive || _this.s.showFiltered) && _this.c.viewTotal ||
898
                                    _this.c.viewTotal && _this.s.forceViewTotal ?
899
                                    filteredMessage.replace(/{total}/, row.total) :
900
                                    countMessage.replace(/{total}/, row.total);
901
                            message = message.replace(/{shown}/, row.shown);
902
                            while (message.includes('{total}')) {
903
                                message = message.replace(/{total}/, row.total);
904
                            }
905
                            while (message.includes('{shown}')) {
906
                                message = message.replace(/{shown}/, row.shown);
907
                            }
908
                            // We are displaying the count in the same columne as the name of the search option.
909
                            // This is so that there is not need to call columns.adjust()
910
                            //  which in turn speeds up the code
911
                            var pill = '<span class="' + _this.classes.pill + '">' + message + '</span>';
912
                            if (!_this.c.viewCount || !colOpts.viewCount) {
913
                                pill = '';
914
                            }
915
                            if (type === 'filter') {
916
                                return typeof data === 'string' && data.match(/<[^>]*>/) !== null ?
917
                                    data.replace(/<[^>]*>/g, '') :
918
                                    data;
919
                            }
920
                            return '<div class="' + _this.classes.nameCont + '"><span title="' +
921
                                (typeof data === 'string' && data.match(/<[^>]*>/) !== null ?
922
                                    data.replace(/<[^>]*>/g, '') :
923
                                    data) +
924
                                '" class="' + _this.classes.name + '">' +
925
                                data + '</span>' +
926
                                pill + '</div>';
927
                        },
928
                        targets: 0,
929
                        // Accessing the private datatables property to set type based on the original table.
930
                        // This is null if not defined by the user, meaning that automatic type detection
931
                        //  would take place
932
                        type: table.settings()[0].aoColumns[this.s.index] !== undefined ?
933
                            table.settings()[0].aoColumns[this.s.index]._sManualType :
934
                            null
935
                    },
936
                    {
937
                        className: 'dtsp-countColumn ' + this.classes.badgePill,
938
                        data: 'shown',
939
                        orderData: [1, 2],
940
                        searchable: false,
941
                        targets: 1,
942
                        visible: false
943
                    },
944
                    {
945
                        data: 'total',
946
                        searchable: false,
947
                        targets: 2,
948
                        visible: false
949
                    }
950
                ],
951
                deferRender: true,
952
                dom: 't',
953
                info: false,
954
                language: this.s.dt.settings()[0].oLanguage,
955
                paging: haveScroller ? true : false,
956
                scrollX: false,
957
                scrollY: '200px',
958
                scroller: haveScroller ? true : false,
959
                select: true,
960
                stateSave: table.settings()[0].oFeatures.bStateSave ? true : false
961
            }, this.c.dtOpts, colOpts !== undefined ? colOpts.dtOpts : {}, this.s.colOpts.options !== undefined || !this.colExists ?
962
                {
963
                    createdRow: function (row, data, dataIndex) {
964
                        $(row).addClass(data.className);
965
                    }
966
                } :
967
                undefined, this.customPaneSettings !== null && this.customPaneSettings.dtOpts !== undefined ?
968
                this.customPaneSettings.dtOpts :
969
                {}, $.fn.dataTable.versionCheck('2')
970
                ? {
971
                    layout: {
972
                        bottomLeft: null,
973
                        bottomRight: null,
974
                        topLeft: null,
975
                        topRight: null
976
                    }
977
                }
978
                : {}));
979
            this.dom.dtP.addClass(this.classes.table);
980
            // Getting column titles is a little messy
981
            var headerText = 'Custom Pane';
982
            if (this.customPaneSettings && this.customPaneSettings.header) {
983
                headerText = this.customPaneSettings.header;
984
            }
985
            else if (colOpts.header) {
986
                headerText = colOpts.header;
987
            }
988
            else if (this.colExists) {
989
                headerText = $.fn.dataTable.versionCheck('2')
990
                    ? table.column(this.s.index).title()
991
                    : table.settings()[0].aoColumns[this.s.index].sTitle;
992
            }
993
            this.dom.searchBox.attr('placeholder', headerText);
994
            // As the pane table is not in the document yet we must initialise select ourselves
995
            // eslint-disable-next-line no-extra-parens
996
            $.fn.dataTable.select.init(this.s.dtPane);
997
            $.fn.dataTable.ext.errMode = errMode;
998
            // If it is not a custom pane
999
            if (this.colExists) {
1000
                // On initialisation, do we need to set a filtering value from a
1001
                // saved state or init option?
1002
                var search = column.search();
1003
                search = search ? search.substr(1, search.length - 2).split('|') : [];
1004
                // Count the number of empty cells
1005
                var count_1 = 0;
1006
                rowData.arrayFilter.forEach(function (element) {
1007
                    if (element.filter === '') {
1008
                        count_1++;
1009
                    }
1010
                });
1011
                // Add all of the search options to the pane
1012
                for (var i = 0, ien = rowData.arrayFilter.length; i < ien; i++) {
1013
                    var selected = false;
1014
                    for (var _b = 0, _c = this.s.serverSelect; _b < _c.length; _b++) {
1015
                        var option = _c[_b];
1016
                        if (option.filter === rowData.arrayFilter[i].filter) {
1017
                            selected = true;
1018
                        }
1019
                    }
1020
                    if (this.s.dt.page.info().serverSide &&
1021
                        (!this.c.cascadePanes ||
1022
                            this.c.cascadePanes && rowData.bins[rowData.arrayFilter[i].filter] !== 0 ||
1023
                            this.c.cascadePanes && init !== null ||
1024
                            selected)) {
1025
                        var row = this.addRow(rowData.arrayFilter[i].display, rowData.arrayFilter[i].filter, init ?
1026
                            rowData.binsTotal[rowData.arrayFilter[i].filter] :
1027
                            rowData.bins[rowData.arrayFilter[i].filter], this.c.viewTotal || init
1028
                            ? String(rowData.binsTotal[rowData.arrayFilter[i].filter])
1029
                            : rowData.bins[rowData.arrayFilter[i].filter], rowData.arrayFilter[i].sort, rowData.arrayFilter[i].type);
1030
                        for (var _d = 0, _e = this.s.serverSelect; _d < _e.length; _d++) {
1031
                            var option = _e[_d];
1032
                            if (option.filter === rowData.arrayFilter[i].filter) {
1033
                                this.s.serverSelecting = true;
1034
                                row.select();
1035
                                this.s.serverSelecting = false;
1036
                            }
1037
                        }
1038
                    }
1039
                    else if (!this.s.dt.page.info().serverSide &&
1040
                        rowData.arrayFilter[i] &&
1041
                        (rowData.bins[rowData.arrayFilter[i].filter] !== undefined || !this.c.cascadePanes)) {
1042
                        this.addRow(rowData.arrayFilter[i].display, rowData.arrayFilter[i].filter, rowData.bins[rowData.arrayFilter[i].filter], rowData.binsTotal[rowData.arrayFilter[i].filter], rowData.arrayFilter[i].sort, rowData.arrayFilter[i].type);
1043
                    }
1044
                    else if (!this.s.dt.page.info().serverSide) {
1045
                        // Just pass an empty string as the message will be calculated based on that in addRow()
1046
                        this.addRow('', count_1, count_1, '', '', '');
1047
                    }
1048
                }
1049
            }
1050
            // eslint-disable-next-line no-extra-parens
1051
            dataTable.select.init(this.s.dtPane);
1052
            // If there are custom options set or it is a custom pane then get them
1053
            if (colOpts.options !== undefined ||
1054
                this.customPaneSettings !== null && this.customPaneSettings.options !== undefined) {
1055
                this._getComparisonRows();
1056
            }
1057
            // Display the pane
1058
            this.s.dtPane.draw();
1059
            this.s.dtPane.table().node().parentNode.scrollTop = this.s.scrollTop;
1060
            this.adjustTopRow();
1061
            if (!this.s.listSet) {
1062
                this._setListeners();
1063
                this.s.listSet = true;
1064
            }
1065
            for (var _f = 0, selectedRows_1 = selectedRows; _f < selectedRows_1.length; _f++) {
1066
                var selection = selectedRows_1[_f];
1067
                if (selection !== undefined) {
1068
                    for (var _g = 0, _h = this.s.dtPane.rows().indexes().toArray(); _g < _h.length; _g++) {
1069
                        var row = _h[_g];
1070
                        if (this.s.dtPane.row(row).data() !== undefined &&
1071
                            selection.filter === this.s.dtPane.row(row).data().filter) {
1072
                            // If this is happening when serverSide processing is happening then
1073
                            //  different behaviour is needed
1074
                            if (this.s.dt.page.info().serverSide) {
1075
                                this.s.serverSelecting = true;
1076
                                this.s.dtPane.row(row).select();
1077
                                this.s.serverSelecting = false;
1078
                            }
1079
                            else {
1080
                                this.s.dtPane.row(row).select();
1081
                            }
1082
                        }
1083
                    }
1084
                }
1085
            }
1086
            //  If SSP and the table is ready, apply the search for the pane
1087
            if (this.s.dt.page.info().serverSide) {
1088
                this.s.dtPane.search(this.dom.searchBox.val()).draw();
1089
            }
1090
            if ((this.c.initCollapsed && this.s.colOpts.initCollapsed !== false ||
1091
                this.s.colOpts.initCollapsed) &&
1092
                (this.c.collapse && this.s.colOpts.collapse !== false ||
1093
                    this.s.colOpts.collapse)) {
1094
                this.collapse();
1095
            }
1096
            // Reload the selection, searchbox entry and ordering from the previous state
1097
            // Need to check here if SSP that this is the first draw, otherwise it will infinite loop
1098
            if (loadedFilter &&
1099
                loadedFilter.searchPanes &&
1100
                loadedFilter.searchPanes.panes &&
1101
                (dataIn === null ||
1102
                    dataIn.draw === 1)) {
1103
                if (!this.c.cascadePanes) {
1104
                    this._reloadSelect(loadedFilter);
1105
                }
1106
                for (var _j = 0, _k = loadedFilter.searchPanes.panes; _j < _k.length; _j++) {
1107
                    var pane = _k[_j];
1108
                    if (pane.id === this.s.index) {
1109
                        // Save some time by only triggering an input if there is a value
1110
                        if (pane.searchTerm && pane.searchTerm.length > 0) {
1111
                            this.dom.searchBox.val(pane.searchTerm);
1112
                            this.dom.searchBox.trigger('input');
1113
                        }
1114
                        this.s.dtPane.order(pane.order).draw();
1115
                        // Is the pane to be hidden or shown?
1116
                        if (pane.collapsed) {
1117
                            this.collapse();
1118
                        }
1119
                        else {
1120
                            this.show();
1121
                        }
1122
                    }
1123
                }
1124
            }
1125
            return true;
1126
        };
1127
        /**
1128
         * Update the array which holds the display and filter values for the table
1129
         */
1130
        SearchPane.prototype._detailsPane = function () {
1131
            var table = this.s.dt;
1132
            this.s.rowData.arrayTotals = [];
1133
            this.s.rowData.binsTotal = {};
1134
            var settings = this.s.dt.settings()[0];
1135
            var indexArray = table.rows().indexes();
1136
            if (!this.s.dt.page.info().serverSide) {
1137
                for (var _i = 0, indexArray_1 = indexArray; _i < indexArray_1.length; _i++) {
1138
                    var rowIdx = indexArray_1[_i];
1139
                    this._populatePaneArray(rowIdx, this.s.rowData.arrayTotals, settings, this.s.rowData.binsTotal);
1140
                }
1141
            }
1142
        };
1143
        /**
1144
         * Appends all of the HTML elements to their relevant parent Elements
1145
         */
1146
        SearchPane.prototype._displayPane = function () {
1147
            var container = this.dom.container;
1148
            var colOpts = this.s.colOpts;
1149
            var layVal = parseInt(this.c.layout.split('-')[1], 10);
1150
            // Empty everything to start again
1151
            this.dom.topRow.empty();
1152
            this.dom.dtP.empty();
1153
            this.dom.topRow.addClass(this.classes.topRow);
1154
            // If there are more than 3 columns defined then make there be a smaller gap between the panes
1155
            if (layVal > 3) {
1156
                this.dom.container.addClass(this.classes.smallGap);
1157
            }
1158
            this.dom.topRow.addClass(this.classes.subRowsContainer);
1159
            this.dom.upper.appendTo(this.dom.topRow);
1160
            this.dom.lower.appendTo(this.dom.topRow);
1161
            this.dom.searchCont.appendTo(this.dom.upper);
1162
            this.dom.buttonGroup.appendTo(this.dom.lower);
1163
            // If no selections have been made in the pane then disable the clear button
1164
            if (this.c.dtOpts.searching === false ||
1165
                colOpts.dtOpts !== undefined && colOpts.dtOpts.searching === false ||
1166
                (!this.c.controls || !colOpts.controls) ||
1167
                this.customPaneSettings !== null &&
1168
                    this.customPaneSettings.dtOpts !== undefined &&
1169
                    this.customPaneSettings.dtOpts.searching !== undefined &&
1170
                    !this.customPaneSettings.dtOpts.searching) {
1171
                this.dom.searchBox
1172
                    .removeClass(this.classes.paneInputButton)
1173
                    .addClass(this.classes.disabledButton)
1174
                    .attr('disabled', 'true');
1175
            }
1176
            this.dom.searchBox.appendTo(this.dom.searchCont);
1177
            // Create the contents of the searchCont div. Worth noting that this function will change when using semantic ui
1178
            this._searchContSetup();
1179
            // If the clear button is allowed to show then display it
1180
            if (this.c.clear && this.c.controls && colOpts.controls) {
1181
                this.dom.clear.appendTo(this.dom.buttonGroup);
1182
            }
1183
            if (this.c.orderable && colOpts.orderable && this.c.controls && colOpts.controls) {
1184
                this.dom.nameButton.appendTo(this.dom.buttonGroup);
1185
            }
1186
            // If the count column is hidden then don't display the ordering button for it
1187
            if (this.c.viewCount &&
1188
                colOpts.viewCount &&
1189
                this.c.orderable &&
1190
                colOpts.orderable &&
1191
                this.c.controls &&
1192
                colOpts.controls) {
1193
                this.dom.countButton.appendTo(this.dom.buttonGroup);
1194
            }
1195
            if ((this.c.collapse && this.s.colOpts.collapse !== false ||
1196
                this.s.colOpts.collapse) &&
1197
                this.c.controls && colOpts.controls) {
1198
                this.dom.collapseButton.appendTo(this.dom.buttonGroup);
1199
            }
1200
            this.dom.topRow.prependTo(this.dom.container);
1201
            container.append(this.dom.dtP);
1202
            container.show();
1203
        };
1204
        /**
1205
         * Gets the options for the row for the customPanes
1206
         *
1207
         * @returns {object} The options for the row extended to include the options from the user.
1208
         */
1209
        SearchPane.prototype._getBonusOptions = function () {
1210
            // We need to reset the thresholds as if they have a value in colOpts then that value will be used
1211
            var defaultMutator = {
1212
                orthogonal: {
1213
                    threshold: null
1214
                },
1215
                threshold: null
1216
            };
1217
            return $.extend(true, {}, SearchPane.defaults, defaultMutator, this.c !== undefined ? this.c : {});
1218
        };
1219
        /**
1220
         * Adds the custom options to the pane
1221
         *
1222
         * @returns {Array} Returns the array of rows which have been added to the pane
1223
         */
1224
        SearchPane.prototype._getComparisonRows = function () {
1225
            var colOpts = this.s.colOpts;
1226
            // Find the appropriate options depending on whether this is a pane for a specific column or a custom pane
1227
            var options = colOpts.options !== undefined
1228
                ? colOpts.options
1229
                : this.customPaneSettings !== null && this.customPaneSettings.options !== undefined
1230
                    ? this.customPaneSettings.options
1231
                    : undefined;
1232
            if (options === undefined) {
1233
                return;
1234
            }
1235
            var tableVals = this.s.dt.rows({ search: 'applied' }).data().toArray();
1236
            var appRows = this.s.dt.rows({ search: 'applied' });
1237
            var tableValsTotal = this.s.dt.rows().data().toArray();
1238
            var allRows = this.s.dt.rows();
1239
            var rows = [];
1240
            // Clear all of the other rows from the pane, only custom options are to be displayed when they are defined
1241
            this.s.dtPane.clear();
1242
            for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
1243
                var comp = options_1[_i];
1244
                // Initialise the object which is to be placed in the row
1245
                var insert = comp.label !== '' ?
1246
                    comp.label :
1247
                    this.emptyMessage();
1248
                var comparisonObj = {
1249
                    className: comp.className,
1250
                    display: insert,
1251
                    filter: typeof comp.value === 'function' ? comp.value : [],
1252
                    shown: 0,
1253
                    sort: insert,
1254
                    total: 0,
1255
                    type: insert
1256
                };
1257
                // If a custom function is in place
1258
                if (typeof comp.value === 'function') {
1259
                    // Count the number of times the function evaluates to true for the data currently being displayed
1260
                    for (var tVal = 0; tVal < tableVals.length; tVal++) {
1261
                        if (comp.value.call(this.s.dt, tableVals[tVal], appRows[0][tVal])) {
1262
                            comparisonObj.shown++;
1263
                        }
1264
                    }
1265
                    // Count the number of times the function evaluates to true for the original data in the Table
1266
                    for (var i = 0; i < tableValsTotal.length; i++) {
1267
                        if (comp.value.call(this.s.dt, tableValsTotal[i], allRows[0][i])) {
1268
                            comparisonObj.total++;
1269
                        }
1270
                    }
1271
                    // Update the comparisonObj
1272
                    if (typeof comparisonObj.filter !== 'function') {
1273
                        comparisonObj.filter.push(comp.filter);
1274
                    }
1275
                }
1276
                // If cascadePanes is not active or if it is and the comparisonObj should be shown then add it to the pane
1277
                if (!this.c.cascadePanes || this.c.cascadePanes && comparisonObj.shown !== 0) {
1278
                    rows.push(this.addRow(comparisonObj.display, comparisonObj.filter, comparisonObj.shown, comparisonObj.total, comparisonObj.sort, comparisonObj.type, comparisonObj.className));
1279
                }
1280
            }
1281
            return rows;
1282
        };
1283
        /**
1284
         * Gets the options for the row for the customPanes
1285
         *
1286
         * @returns {object} The options for the row extended to include the options from the user.
1287
         */
1288
        SearchPane.prototype._getOptions = function () {
1289
            var table = this.s.dt;
1290
            // We need to reset the thresholds as if they have a value in colOpts then that value will be used
1291
            var defaultMutator = {
1292
                collapse: null,
1293
                emptyMessage: false,
1294
                initCollapsed: null,
1295
                orthogonal: {
1296
                    threshold: null
1297
                },
1298
                threshold: null
1299
            };
1300
            var columnOptions = table.settings()[0].aoColumns[this.s.index].searchPanes;
1301
            var colOpts = $.extend(true, {}, SearchPane.defaults, defaultMutator, columnOptions);
1302
            if (columnOptions !== undefined &&
1303
                columnOptions.hideCount !== undefined &&
1304
                columnOptions.viewCount === undefined) {
1305
                colOpts.viewCount = !columnOptions.hideCount;
1306
            }
1307
            return colOpts;
1308
        };
1309
        /**
1310
         * This method allows for changes to the panes and table to be made when a selection or a deselection occurs
1311
         *
1312
         * @param select Denotes whether a selection has been made or not
1313
         */
1314
        SearchPane.prototype._makeSelection = function () {
1315
            this.updateTable();
1316
            this.s.updating = true;
1317
            this.s.dt.draw();
1318
            this.s.updating = false;
1319
        };
1320
        /**
1321
         * Fill the array with the values that are currently being displayed in the table
1322
         *
1323
         * @param last boolean to indicate whether this was the last pane a selection was made in
1324
         */
1325
        SearchPane.prototype._populatePane = function (last) {
1326
            if (last === void 0) { last = false; }
1327
            var table = this.s.dt;
1328
            this.s.rowData.arrayFilter = [];
1329
            this.s.rowData.bins = {};
1330
            var settings = this.s.dt.settings()[0];
1331
            // If cascadePanes or viewTotal are active it is necessary to get the data which is currently
1332
            // being displayed for their functionality.
1333
            // Also make sure that this was not the last pane to have a selection made
1334
            if (!this.s.dt.page.info().serverSide) {
1335
                var indexArray = (this.c.cascadePanes || this.c.viewTotal) && (!this.s.clearing && !last) ?
1336
                    table.rows({ search: 'applied' }).indexes() :
1337
                    table.rows().indexes();
1338
                for (var _i = 0, _a = indexArray.toArray(); _i < _a.length; _i++) {
1339
                    var index = _a[_i];
1340
                    this._populatePaneArray(index, this.s.rowData.arrayFilter, settings);
1341
                }
1342
            }
1343
        };
1344
        /**
1345
         * Populates an array with all of the data for the table
1346
         *
1347
         * @param rowIdx The current row index to be compared
1348
         * @param arrayFilter The array that is to be populated with row Details
1349
         * @param bins The bins object that is to be populated with the row counts
1350
         */
1351
        SearchPane.prototype._populatePaneArray = function (rowIdx, arrayFilter, settings, bins) {
1352
            if (bins === void 0) { bins = this.s.rowData.bins; }
1353
            var colOpts = this.s.colOpts;
1354
            // Retrieve the rendered data from the cell using the fnGetCellData function
1355
            // rather than the cell().render API method for optimisation
1356
            if (typeof colOpts.orthogonal === 'string') {
1357
                var rendered = settings.oApi._fnGetCellData(settings, rowIdx, this.s.index, colOpts.orthogonal);
1358
                this.s.rowData.filterMap.set(rowIdx, rendered);
1359
                this._addOption(rendered, rendered, rendered, rendered, arrayFilter, bins);
1360
            }
1361
            else {
1362
                var filter = settings.oApi._fnGetCellData(settings, rowIdx, this.s.index, colOpts.orthogonal.search);
1363
                // Null and empty string are to be considered the same value
1364
                if (filter === null) {
1365
                    filter = '';
1366
                }
1367
                if (typeof filter === 'string') {
1368
                    filter = filter.replace(/<[^>]*>/g, '');
1369
                }
1370
                this.s.rowData.filterMap.set(rowIdx, filter);
1371
                if (!bins[filter]) {
1372
                    bins[filter] = 1;
1373
                    this._addOption(filter, settings.oApi._fnGetCellData(settings, rowIdx, this.s.index, colOpts.orthogonal.display), settings.oApi._fnGetCellData(settings, rowIdx, this.s.index, colOpts.orthogonal.sort), settings.oApi._fnGetCellData(settings, rowIdx, this.s.index, colOpts.orthogonal.type), arrayFilter, bins);
1374
                    this.s.rowData.totalOptions++;
1375
                }
1376
                else {
1377
                    bins[filter]++;
1378
                    this.s.rowData.totalOptions++;
1379
                    return;
1380
                }
1381
            }
1382
        };
1383
        /**
1384
         * Reloads all of the previous selects into the panes
1385
         *
1386
         * @param loadedFilter The loaded filters from a previous state
1387
         */
1388
        SearchPane.prototype._reloadSelect = function (loadedFilter) {
1389
            // If the state was not saved don't selected any
1390
            if (loadedFilter === undefined) {
1391
                return;
1392
            }
1393
            var idx;
1394
            // For each pane, check that the loadedFilter list exists and is not null,
1395
            // find the id of each search item and set it to be selected.
1396
            for (var i = 0; i < loadedFilter.searchPanes.panes.length; i++) {
1397
                if (loadedFilter.searchPanes.panes[i].id === this.s.index) {
1398
                    idx = i;
1399
                    break;
1400
                }
1401
            }
1402
            if (idx !== undefined) {
1403
                var table = this.s.dtPane;
1404
                var rows = table.rows({ order: 'index' }).data().map(function (item) { return item.filter !== null ?
1405
                    item.filter.toString() :
1406
                    null; }).toArray();
1407
                for (var _i = 0, _a = loadedFilter.searchPanes.panes[idx].selected; _i < _a.length; _i++) {
1408
                    var filter = _a[_i];
1409
                    var id = -1;
1410
                    if (filter !== null) {
1411
                        id = rows.indexOf(filter.toString());
1412
                    }
1413
                    if (id > -1) {
1414
                        this.s.serverSelecting = true;
1415
                        table.row(id).select();
1416
                        this.s.serverSelecting = false;
1417
                    }
1418
                }
1419
            }
1420
        };
1421
        /**
1422
         * This method decides whether a row should contribute to the pane or not
1423
         *
1424
         * @param filter the value that the row is to be filtered on
1425
         * @param dataIndex the row index
1426
         */
1427
        SearchPane.prototype._search = function (filter, dataIndex) {
1428
            var colOpts = this.s.colOpts;
1429
            var table = this.s.dt;
1430
            // For each item selected in the pane, check if it is available in the cell
1431
            for (var _i = 0, _a = this.selections; _i < _a.length; _i++) {
1432
                var colSelect = _a[_i];
1433
                if (typeof colSelect.filter === 'string' && typeof filter === 'string') {
1434
                    // The filter value will not have the &amp; in place but a &,
1435
                    // so we need to do a replace to make sure that they will match
1436
                    colSelect.filter = colSelect.filter
1437
                        .replace(/&amp;/g, '&')
1438
                        .replace(/&lt;/g, '<')
1439
                        .replace(/&gt;/g, '>')
1440
                        .replace(/&quot;/g, '"');
1441
                }
1442
                // if the filter is an array then is the column present in it
1443
                if (Array.isArray(filter)) {
1444
                    if (filter.includes(colSelect.filter)) {
1445
                        return true;
1446
                    }
1447
                }
1448
                // if the filter is a function then does it meet the criteria of that function or not
1449
                else if (typeof colSelect.filter === 'function') {
1450
                    if (colSelect.filter.call(table, table.row(dataIndex).data(), dataIndex)) {
1451
                        if (colOpts.combiner === 'or') {
1452
                            return true;
1453
                        }
1454
                    }
1455
                    // If the combiner is an "and" then we need to check against all possible selections
1456
                    // so if it fails here then the and is not met and return false
1457
                    else if (colOpts.combiner === 'and') {
1458
                        return false;
1459
                    }
1460
                }
1461
                // otherwise if the two filter values are equal then return true
1462
                else if (filter === colSelect.filter ||
1463
                    // Loose type checking incase number type in column comparing to a string
1464
                    // eslint-disable-next-line eqeqeq
1465
                    !(typeof filter === 'string' && filter.length === 0) && filter == colSelect.filter ||
1466
                    colSelect.filter === null && typeof filter === 'string' && filter === '') {
1467
                    return true;
1468
                }
1469
            }
1470
            // If the combiner is an and then we need to check against all possible selections
1471
            // so return true here if so because it would have returned false earlier if it had failed
1472
            if (colOpts.combiner === 'and') {
1473
                return true;
1474
            }
1475
            // Otherwise it hasn't matched with anything by this point so it must be false
1476
            else {
1477
                return false;
1478
            }
1479
        };
1480
        /**
1481
         * Creates the contents of the searchCont div
1482
         *
1483
         * NOTE This is overridden when semantic ui styling in order to integrate the search button into the text box.
1484
         */
1485
        SearchPane.prototype._searchContSetup = function () {
1486
            if (this.c.controls && this.s.colOpts.controls) {
1487
                this.dom.searchButton.appendTo(this.dom.searchLabelCont);
1488
            }
1489
            if (!(this.c.dtOpts.searching === false ||
1490
                this.s.colOpts.dtOpts.searching === false ||
1491
                this.customPaneSettings !== null &&
1492
                    this.customPaneSettings.dtOpts !== undefined &&
1493
                    this.customPaneSettings.dtOpts.searching !== undefined &&
1494
                    !this.customPaneSettings.dtOpts.searching)) {
1495
                this.dom.searchLabelCont.appendTo(this.dom.searchCont);
1496
            }
1497
        };
1498
        /**
1499
         * Adds outline to the pane when a selection has been made
1500
         */
1501
        SearchPane.prototype._searchExtras = function () {
1502
            var updating = this.s.updating;
1503
            this.s.updating = true;
1504
            var filters = this.s.dtPane.rows({ selected: true }).data().pluck('filter').toArray();
1505
            var nullIndex = filters.indexOf(this.emptyMessage());
1506
            var container = $(this.s.dtPane.table().container());
1507
            // If null index is found then search for empty cells as a filter.
1508
            if (nullIndex > -1) {
1509
                filters[nullIndex] = '';
1510
            }
1511
            // If a filter has been applied then outline the respective pane, remove it when it no longer is.
1512
            if (filters.length > 0) {
1513
                container.addClass(this.classes.selected);
1514
            }
1515
            else if (filters.length === 0) {
1516
                container.removeClass(this.classes.selected);
1517
            }
1518
            this.s.updating = updating;
1519
        };
1520
        /**
1521
         * Finds the ratio of the number of different options in the table to the number of rows
1522
         *
1523
         * @param bins the number of different options in the table
1524
         * @param rowCount the total number of rows in the table
1525
         * @returns {number} returns the ratio
1526
         */
1527
        SearchPane.prototype._uniqueRatio = function (bins, rowCount) {
1528
            if (rowCount > 0 &&
1529
                (this.s.rowData.totalOptions > 0 && !this.s.dt.page.info().serverSide ||
1530
                    this.s.dt.page.info().serverSide && this.s.tableLength > 0)) {
1531
                return bins / this.s.rowData.totalOptions;
1532
            }
1533
            else {
1534
                return 1;
1535
            }
1536
        };
1537
        /**
1538
         * updates the options within the pane
1539
         *
1540
         * @param draw a flag to define whether this has been called due to a draw event or not
1541
         */
1542
        SearchPane.prototype._updateCommon = function (draw) {
1543
            if (draw === void 0) { draw = false; }
1544
            // Update the panes if doing a deselect. if doing a select then
1545
            // update all of the panes except for the one causing the change
1546
            if (!this.s.dt.page.info().serverSide &&
1547
                this.s.dtPane !== undefined &&
1548
                (!this.s.filteringActive || this.c.cascadePanes || draw === true) &&
1549
                (this.c.cascadePanes !== true || this.s.selectPresent !== true) &&
1550
                (!this.s.lastSelect || !this.s.lastCascade)) {
1551
                var colOpts = this.s.colOpts;
1552
                var selected = this.s.dtPane.rows({ selected: true }).data().toArray();
1553
                var rowData = this.s.rowData;
1554
                // Clear the pane in preparation for adding the updated search options
1555
                this.s.dtPane.clear();
1556
                // If it is not a custom pane
1557
                if (this.colExists) {
1558
                    // Only run populatePane if the data has not been collected yet
1559
                    if (rowData.arrayFilter.length === 0) {
1560
                        this._populatePane(!this.s.filteringActive);
1561
                    }
1562
                    // If cascadePanes is active and the table has returned to its default state then
1563
                    // there is a need to update certain parts ofthe rowData.
1564
                    else if (this.c.cascadePanes &&
1565
                        this.s.dt.rows().data().toArray().length ===
1566
                            this.s.dt.rows({ search: 'applied' }).data().toArray().length) {
1567
                        rowData.arrayFilter = rowData.arrayOriginal;
1568
                        rowData.bins = rowData.binsOriginal;
1569
                    }
1570
                    // Otherwise if viewTotal or cascadePanes is active then the data from the table must be read.
1571
                    else if (this.c.viewTotal || this.c.cascadePanes) {
1572
                        this._populatePane(!this.s.filteringActive);
1573
                    }
1574
                    // If the viewTotal option is selected then find the totals for the table
1575
                    if (this.c.viewTotal) {
1576
                        this._detailsPane();
1577
                    }
1578
                    else {
1579
                        rowData.binsTotal = rowData.bins;
1580
                    }
1581
                    if (this.c.viewTotal && !this.c.cascadePanes) {
1582
                        rowData.arrayFilter = rowData.arrayTotals;
1583
                    }
1584
                    var _loop_1 = function (dataP) {
1585
                        // If both view Total and cascadePanes have been selected and the count of the row
1586
                        // is not 0 then add it to pane
1587
                        // Do this also if the viewTotal option has been selected and cascadePanes has not
1588
                        if (dataP &&
1589
                            (rowData.bins[dataP.filter] !== undefined &&
1590
                                rowData.bins[dataP.filter] !== 0 &&
1591
                                this_1.c.cascadePanes ||
1592
                                !this_1.c.cascadePanes ||
1593
                                this_1.s.clearing)) {
1594
                            var row = this_1.addRow(dataP.display, dataP.filter, !this_1.c.viewTotal ?
1595
                                rowData.bins[dataP.filter] :
1596
                                rowData.bins[dataP.filter] !== undefined ?
1597
                                    rowData.bins[dataP.filter] :
1598
                                    0, this_1.c.viewTotal ?
1599
                                String(rowData.binsTotal[dataP.filter]) :
1600
                                rowData.bins[dataP.filter], dataP.sort, dataP.type);
1601
                            // Find out if the filter was selected in the previous search,
1602
                            // if so select it and remove from array.
1603
                            var selectIndex = selected.findIndex(function (element) {
1604
                                return element.filter === dataP.filter;
1605
                            });
1606
                            if (selectIndex !== -1) {
1607
                                row.select();
1608
                                selected.splice(selectIndex, 1);
1609
                            }
1610
                        }
1611
                    };
1612
                    var this_1 = this;
1613
                    for (var _i = 0, _a = rowData.arrayFilter; _i < _a.length; _i++) {
1614
                        var dataP = _a[_i];
1615
                        _loop_1(dataP);
1616
                    }
1617
                }
1618
                if (colOpts.searchPanes !== undefined && colOpts.searchPanes.options !== undefined ||
1619
                    colOpts.options !== undefined ||
1620
                    this.customPaneSettings !== null && this.customPaneSettings.options !== undefined) {
1621
                    var rows = this._getComparisonRows();
1622
                    var _loop_2 = function (row) {
1623
                        var selectIndex = selected.findIndex(function (element) {
1624
                            if (element.display === row.data().display) {
1625
                                return true;
1626
                            }
1627
                        });
1628
                        if (selectIndex !== -1) {
1629
                            row.select();
1630
                            selected.splice(selectIndex, 1);
1631
                        }
1632
                    };
1633
                    for (var _b = 0, rows_1 = rows; _b < rows_1.length; _b++) {
1634
                        var row = rows_1[_b];
1635
                        _loop_2(row);
1636
                    }
1637
                }
1638
                // Add search options which were previously selected but whos results are no
1639
                // longer present in the resulting data set.
1640
                for (var _c = 0, selected_1 = selected; _c < selected_1.length; _c++) {
1641
                    var selectedEl = selected_1[_c];
1642
                    var row = this.addRow(selectedEl.display, selectedEl.filter, 0, this.c.viewTotal
1643
                        ? selectedEl.total
1644
                        : 0, selectedEl.display, selectedEl.display);
1645
                    this.s.updating = true;
1646
                    row.select();
1647
                    this.s.updating = false;
1648
                }
1649
                this.s.dtPane.draw();
1650
                this.s.dtPane.table().node().parentNode.scrollTop = this.s.scrollTop;
1651
            }
1652
        };
1653
        SearchPane.version = '1.3.0';
1654
        SearchPane.classes = {
1655
            bordered: 'dtsp-bordered',
1656
            buttonGroup: 'dtsp-buttonGroup',
1657
            buttonSub: 'dtsp-buttonSub',
1658
            clear: 'dtsp-clear',
1659
            clearAll: 'dtsp-clearAll',
1660
            clearButton: 'clearButton',
1661
            collapseAll: 'dtsp-collapseAll',
1662
            collapseButton: 'dtsp-collapseButton',
1663
            container: 'dtsp-searchPane',
1664
            countButton: 'dtsp-countButton',
1665
            disabledButton: 'dtsp-disabledButton',
1666
            hidden: 'dtsp-hidden',
1667
            hide: 'dtsp-hide',
1668
            layout: 'dtsp-',
1669
            name: 'dtsp-name',
1670
            nameButton: 'dtsp-nameButton',
1671
            nameCont: 'dtsp-nameCont',
1672
            narrow: 'dtsp-narrow',
1673
            paneButton: 'dtsp-paneButton',
1674
            paneInputButton: 'dtsp-paneInputButton',
1675
            pill: 'dtsp-pill',
1676
            rotated: 'dtsp-rotated',
1677
            search: 'dtsp-search',
1678
            searchCont: 'dtsp-searchCont',
1679
            searchIcon: 'dtsp-searchIcon',
1680
            searchLabelCont: 'dtsp-searchButtonCont',
1681
            selected: 'dtsp-selected',
1682
            smallGap: 'dtsp-smallGap',
1683
            subRow1: 'dtsp-subRow1',
1684
            subRow2: 'dtsp-subRow2',
1685
            subRowsContainer: 'dtsp-subRowsContainer',
1686
            title: 'dtsp-title',
1687
            topRow: 'dtsp-topRow'
1688
        };
1689
        // Define SearchPanes default options
1690
        SearchPane.defaults = {
1691
            cascadePanes: false,
1692
            clear: true,
1693
            collapse: true,
1694
            combiner: 'or',
1695
            container: function (dt) {
1696
                return dt.table().container();
1697
            },
1698
            controls: true,
1699
            dtOpts: {},
1700
            emptyMessage: null,
1701
            hideCount: false,
1702
            i18n: {
1703
                clearPane: '&times;',
1704
                count: '{total}',
1705
                countFiltered: '{shown} ({total})',
1706
                emptyMessage: '<em>No data</em>'
1707
            },
1708
            initCollapsed: false,
1709
            layout: 'auto',
1710
            name: undefined,
1711
            orderable: true,
1712
            orthogonal: {
1713
                display: 'display',
1714
                filter: 'filter',
1715
                hideCount: false,
1716
                search: 'filter',
1717
                show: undefined,
1718
                sort: 'sort',
1719
                threshold: 0.6,
1720
                type: 'type',
1721
                viewCount: true
1722
            },
1723
            preSelect: [],
1724
            threshold: 0.6,
1725
            viewCount: true,
1726
            viewTotal: false
1727
        };
1728
        return SearchPane;
1729
    }());
1730

1731
    var $$1;
1732
    var dataTable$1;
1733
    function setJQuery$1(jq) {
1734
        $$1 = jq;
1735
        dataTable$1 = jq.fn.dataTable;
1736
    }
1737
    var SearchPanes = /** @class */ (function () {
1738
        function SearchPanes(paneSettings, opts, fromInit) {
1739
            var _this = this;
1740
            if (fromInit === void 0) { fromInit = false; }
1741
            this.regenerating = false;
1742
            // Check that the required version of DataTables is included
1743
            if (!dataTable$1 || !dataTable$1.versionCheck || !dataTable$1.versionCheck('1.10.0')) {
1744
                throw new Error('SearchPane requires DataTables 1.10 or newer');
1745
            }
1746
            // Check that Select is included
1747
            // eslint-disable-next-line no-extra-parens
1748
            if (!dataTable$1.select) {
1749
                throw new Error('SearchPane requires Select');
1750
            }
1751
            var table = new dataTable$1.Api(paneSettings);
1752
            this.classes = $$1.extend(true, {}, SearchPanes.classes);
1753
            // Get options from user
1754
            this.c = $$1.extend(true, {}, SearchPanes.defaults, opts);
1755
            // Add extra elements to DOM object including clear
1756
            this.dom = {
1757
                clearAll: $$1('<button type="button">Clear All</button>').addClass(this.classes.clearAll),
1758
                collapseAll: $$1('<button type="button">Collapse All</button>').addClass(this.classes.collapseAll),
1759
                container: $$1('<div/>').addClass(this.classes.panes).text(table.i18n('searchPanes.loadMessage', this.c.i18n.loadMessage)),
1760
                emptyMessage: $$1('<div/>').addClass(this.classes.emptyMessage),
1761
                options: $$1('<div/>').addClass(this.classes.container),
1762
                panes: $$1('<div/>').addClass(this.classes.container),
1763
                showAll: $$1('<button type="button">Show All</button>')
1764
                    .addClass(this.classes.showAll)
1765
                    .addClass(this.classes.disabledButton)
1766
                    .attr('disabled', 'true'),
1767
                title: $$1('<div/>').addClass(this.classes.title),
1768
                titleRow: $$1('<div/>').addClass(this.classes.titleRow),
1769
                wrapper: $$1('<div/>')
1770
            };
1771
            this.s = {
1772
                colOpts: [],
1773
                dt: table,
1774
                filterCount: 0,
1775
                filterPane: -1,
1776
                page: 0,
1777
                paging: false,
1778
                panes: [],
1779
                selectionList: [],
1780
                serverData: {},
1781
                stateRead: false,
1782
                updating: false
1783
            };
1784
            if (table.settings()[0]._searchPanes !== undefined) {
1785
                return;
1786
            }
1787
            this._getState();
1788
            if (this.s.dt.page.info().serverSide) {
1789
                table.on('preXhr.dt', function (e, settings, data) {
1790
                    if (data.searchPanes === undefined) {
1791
                        data.searchPanes = {};
1792
                    }
1793
                    if (data.searchPanes_null === undefined) {
1794
                        data.searchPanes_null = {};
1795
                    }
1796
                    for (var _i = 0, _a = _this.s.selectionList; _i < _a.length; _i++) {
1797
                        var selection = _a[_i];
1798
                        var src = _this.s.dt.column(selection.index).dataSrc();
1799
                        if (data.searchPanes[src] === undefined) {
1800
                            data.searchPanes[src] = {};
1801
                        }
1802
                        if (data.searchPanes_null[src] === undefined) {
1803
                            data.searchPanes_null[src] = {};
1804
                        }
1805
                        for (var i = 0; i < selection.rows.length; i++) {
1806
                            data.searchPanes[src][i] = selection.rows[i].filter;
1807
                            if (data.searchPanes[src][i] === null) {
1808
                                data.searchPanes_null[src][i] = true;
1809
                            }
1810
                        }
1811
                    }
1812
                });
1813
            }
1814
            // We are using the xhr event to rebuild the panes if required due to viewTotal being enabled
1815
            // If viewTotal is not enabled then we simply update the data from the server
1816
            table.on('xhr', function (e, settings, json, xhr) {
1817
                if (json && json.searchPanes && json.searchPanes.options) {
1818
                    _this.s.serverData = json;
1819
                    _this.s.serverData.tableLength = json.recordsTotal;
1820
                    _this._serverTotals();
1821
                }
1822
            });
1823
            table.settings()[0]._searchPanes = this;
1824
            this.dom.clearAll.text(table.i18n('searchPanes.clearMessage', this.c.i18n.clearMessage));
1825
            this.dom.collapseAll.text(table.i18n('searchPanes.collapseMessage', this.c.i18n.collapseMessage));
1826
            this.dom.showAll.text(table.i18n('searchPanes.showMessage', this.c.i18n.showMessage));
1827
            if (this.s.dt.settings()[0]._bInitComplete || fromInit) {
1828
                this._paneDeclare(table, paneSettings, opts);
1829
            }
1830
            else {
1831
                table.one('preInit.dt', function (settings) {
1832
                    _this._paneDeclare(table, paneSettings, opts);
1833
                });
1834
            }
1835
            return this;
1836
        }
1837
        /**
1838
         * Clear the selections of all of the panes
1839
         */
1840
        SearchPanes.prototype.clearSelections = function () {
1841
            // Load in all of the searchBoxes in the documents
1842
            var searches = this.dom.container.find('.' + this.classes.search.replace(/\s+/g, '.'));
1843
            // For each searchBox set the input text to be empty and then trigger
1844
            // an input on them so that they no longer filter the panes
1845
            searches.each(function () {
1846
                $$1(this).val('');
1847
                $$1(this).trigger('input');
1848
            });
1849
            var returnArray = [];
1850
            // Clear the selectionList to prevent cascadePanes from reselecting rows
1851
            this.s.selectionList = [];
1852
            // For every pane, clear the selections in the pane
1853
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
1854
                var pane = _a[_i];
1855
                if (pane.s.dtPane !== undefined) {
1856
                    returnArray.push(pane.clearPane());
1857
                }
1858
            }
1859
            return returnArray;
1860
        };
1861
        /**
1862
         * returns the container node for the searchPanes
1863
         */
1864
        SearchPanes.prototype.getNode = function () {
1865
            return this.dom.container;
1866
        };
1867
        /**
1868
         * rebuilds all of the panes
1869
         */
1870
        SearchPanes.prototype.rebuild = function (targetIdx, maintainSelection) {
1871
            if (targetIdx === void 0) { targetIdx = false; }
1872
            if (maintainSelection === void 0) { maintainSelection = false; }
1873
            this.dom.emptyMessage.remove();
1874
            // As a rebuild from scratch is required, empty the searchpanes container.
1875
            var returnArray = [];
1876
            // Rebuild each pane individually, if a specific pane has been selected then only rebuild that one
1877
            if (targetIdx === false) {
1878
                this.dom.panes.empty();
1879
            }
1880
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
1881
                var pane = _a[_i];
1882
                if (targetIdx !== false && pane.s.index !== targetIdx) {
1883
                    continue;
1884
                }
1885
                pane.clearData();
1886
                returnArray.push(
1887
                // Pass a boolean to say whether this is the last choice made for maintaining selections when rebuilding
1888
                pane.rebuildPane(this.s.selectionList[this.s.selectionList.length - 1] !== undefined ?
1889
                    pane.s.index === this.s.selectionList[this.s.selectionList.length - 1].index :
1890
                    false, this.s.dt.page.info().serverSide ?
1891
                    this.s.serverData :
1892
                    undefined, null, maintainSelection));
1893
                this.dom.panes.append(pane.dom.container);
1894
            }
1895
            if (this.c.cascadePanes || this.c.viewTotal) {
1896
                this.redrawPanes(true);
1897
            }
1898
            else {
1899
                this._updateSelection();
1900
            }
1901
            // Attach panes, clear buttons, and title bar to the document
1902
            this._updateFilterCount();
1903
            this._attachPaneContainer();
1904
            // If the selections are to be maintained, then it is safe to assume that paging is also to be maintained
1905
            // Otherwise, the paging should be reset
1906
            this.s.dt.draw(!maintainSelection);
1907
            // Resize the panes incase there has been a change
1908
            this.resizePanes();
1909
            // If a single pane has been rebuilt then return only that pane
1910
            if (returnArray.length === 1) {
1911
                return returnArray[0];
1912
            }
1913
            // Otherwise return all of the panes that have been rebuilt
1914
            else {
1915
                return returnArray;
1916
            }
1917
        };
1918
        /**
1919
         * Redraws all of the panes
1920
         */
1921
        SearchPanes.prototype.redrawPanes = function (rebuild) {
1922
            if (rebuild === void 0) { rebuild = false; }
1923
            var table = this.s.dt;
1924
            // Only do this if the redraw isn't being triggered by the panes updating themselves
1925
            if (!this.s.updating && !this.s.dt.page.info().serverSide) {
1926
                var filterActive = true;
1927
                var filterPane = this.s.filterPane;
1928
                var selectTotal = null;
1929
                for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
1930
                    var pane = _a[_i];
1931
                    if (pane.s.dtPane !== undefined) {
1932
                        selectTotal += pane.s.dtPane.rows({ selected: true }).data().toArray().length;
1933
                    }
1934
                }
1935
                // If the number of rows currently visible is equal to the number of rows in the table
1936
                // then there can't be any filtering taking place
1937
                if (selectTotal === 0 &&
1938
                    table.rows({ search: 'applied' }).data().toArray().length === table.rows().data().toArray().length) {
1939
                    filterActive = false;
1940
                }
1941
                // Otherwise if viewTotal is active then it is necessary to determine which panes a select is present in.
1942
                // If there is only one pane with a selection present then it should not show the filtered message as
1943
                // more selections may be made in that pane.
1944
                else if (this.c.viewTotal) {
1945
                    for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
1946
                        var pane = _c[_b];
1947
                        if (pane.s.dtPane !== undefined) {
1948
                            var selectLength = pane.s.dtPane.rows({ selected: true }).data().toArray().length;
1949
                            if (selectLength === 0) {
1950
                                for (var _d = 0, _e = this.s.selectionList; _d < _e.length; _d++) {
1951
                                    var selection = _e[_d];
1952
                                    if (selection.index === pane.s.index && selection.rows.length !== 0) {
1953
                                        selectLength = selection.rows.length;
1954
                                    }
1955
                                }
1956
                            }
1957
                            // If filterPane === -1 then a pane with a selection has not been found yet,
1958
                            // so set filterPane to that panes index
1959
                            if (selectLength > 0 && filterPane === -1) {
1960
                                filterPane = pane.s.index;
1961
                            }
1962
                            // Then if another pane is found with a selection then set filterPane to null to
1963
                            // show that multiple panes have selections present
1964
                            else if (selectLength > 0) {
1965
                                filterPane = null;
1966
                            }
1967
                        }
1968
                    }
1969
                    // If the searchbox is in place and filtering is applied then need to cascade down anyway
1970
                    if (selectTotal === 0) {
1971
                        filterPane = null;
1972
                    }
1973
                }
1974
                var deselectIdx = void 0;
1975
                var newSelectionList = [];
1976
                // Don't run this if it is due to the panes regenerating
1977
                if (!this.regenerating) {
1978
                    for (var _f = 0, _g = this.s.panes; _f < _g.length; _f++) {
1979
                        var pane = _g[_f];
1980
                        // Identify the pane where a selection or deselection has been made and add it to the list.
1981
                        if (pane.s.selectPresent) {
1982
                            this.s.selectionList.push({
1983
                                index: pane.s.index,
1984
                                protect: false,
1985
                                rows: pane.s.dtPane.rows({ selected: true }).data().toArray()
1986
                            });
1987
                            break;
1988
                        }
1989
                        else if (pane.s.deselect) {
1990
                            deselectIdx = pane.s.index;
1991
                            var selectedData = pane.s.dtPane.rows({ selected: true }).data().toArray();
1992
                            if (selectedData.length > 0) {
1993
                                this.s.selectionList.push({
1994
                                    index: pane.s.index,
1995
                                    protect: true,
1996
                                    rows: selectedData
1997
                                });
1998
                            }
1999
                        }
2000
                    }
2001
                    if (this.s.selectionList.length > 0) {
2002
                        var last = this.s.selectionList[this.s.selectionList.length - 1].index;
2003
                        for (var _h = 0, _j = this.s.panes; _h < _j.length; _h++) {
2004
                            var pane = _j[_h];
2005
                            pane.s.lastSelect = pane.s.index === last;
2006
                        }
2007
                    }
2008
                    // Remove selections from the list from the pane where a deselect has taken place
2009
                    for (var i = 0; i < this.s.selectionList.length; i++) {
2010
                        if (this.s.selectionList[i].index !== deselectIdx || this.s.selectionList[i].protect === true) {
2011
                            var further = false;
2012
                            // Find out if this selection is the last one in the list for that pane
2013
                            for (var j = i + 1; j < this.s.selectionList.length; j++) {
2014
                                if (this.s.selectionList[j].index === this.s.selectionList[i].index) {
2015
                                    further = true;
2016
                                }
2017
                            }
2018
                            // If there are no selections for this pane in the list then just push this one
2019
                            if (!further) {
2020
                                newSelectionList.push(this.s.selectionList[i]);
2021
                                this.s.selectionList[i].protect = false;
2022
                            }
2023
                        }
2024
                    }
2025
                    var solePane = -1;
2026
                    if (newSelectionList.length === 1 && selectTotal !== null && selectTotal !== 0) {
2027
                        solePane = newSelectionList[0].index;
2028
                    }
2029
                    // Update all of the panes to reflect the current state of the filters
2030
                    for (var _k = 0, _l = this.s.panes; _k < _l.length; _k++) {
2031
                        var pane = _l[_k];
2032
                        if (pane.s.dtPane !== undefined) {
2033
                            var tempFilter = true;
2034
                            pane.s.filteringActive = true;
2035
                            if (filterPane !== -1 && filterPane !== null && filterPane === pane.s.index ||
2036
                                filterActive === false ||
2037
                                pane.s.index === solePane) {
2038
                                tempFilter = false;
2039
                                pane.s.filteringActive = false;
2040
                            }
2041
                            pane.updatePane(!tempFilter ? false : filterActive);
2042
                        }
2043
                    }
2044
                    // If the length of the selections are different then some of them have been
2045
                    // removed and a deselect has occured
2046
                    if (newSelectionList.length > 0 && (newSelectionList.length < this.s.selectionList.length || rebuild)) {
2047
                        this._cascadeRegen(newSelectionList, selectTotal);
2048
                        var last = newSelectionList[newSelectionList.length - 1].index;
2049
                        for (var _m = 0, _o = this.s.panes; _m < _o.length; _m++) {
2050
                            var pane = _o[_m];
2051
                            pane.s.lastSelect = pane.s.index === last;
2052
                        }
2053
                    }
2054
                    else if (newSelectionList.length > 0) {
2055
                        // Update all of the other panes as you would just making a normal selection
2056
                        for (var _p = 0, _q = this.s.panes; _p < _q.length; _p++) {
2057
                            var paneUpdate = _q[_p];
2058
                            if (paneUpdate.s.dtPane !== undefined) {
2059
                                var tempFilter = true;
2060
                                paneUpdate.s.filteringActive = true;
2061
                                if (filterPane !== -1 && filterPane !== null && filterPane === paneUpdate.s.index ||
2062
                                    filterActive === false ||
2063
                                    paneUpdate.s.index === solePane) {
2064
                                    tempFilter = false;
2065
                                    paneUpdate.s.filteringActive = false;
2066
                                }
2067
                                paneUpdate.updatePane(!tempFilter ? tempFilter : filterActive);
2068
                            }
2069
                        }
2070
                    }
2071
                    // Update the label that shows how many filters are in place
2072
                    this._updateFilterCount();
2073
                }
2074
                else {
2075
                    var solePane = -1;
2076
                    if (newSelectionList.length === 1 && selectTotal !== null && selectTotal !== 0) {
2077
                        solePane = newSelectionList[0].index;
2078
                    }
2079
                    for (var _r = 0, _s = this.s.panes; _r < _s.length; _r++) {
2080
                        var pane = _s[_r];
2081
                        if (pane.s.dtPane !== undefined) {
2082
                            var tempFilter = true;
2083
                            pane.s.filteringActive = true;
2084
                            if (filterPane !== -1 && filterPane !== null && filterPane === pane.s.index ||
2085
                                filterActive === false ||
2086
                                pane.s.index === solePane) {
2087
                                tempFilter = false;
2088
                                pane.s.filteringActive = false;
2089
                            }
2090
                            pane.updatePane(!tempFilter ? tempFilter : filterActive);
2091
                        }
2092
                    }
2093
                    // Update the label that shows how many filters are in place
2094
                    this._updateFilterCount();
2095
                }
2096
                if (!filterActive || selectTotal === 0) {
2097
                    this.s.selectionList = [];
2098
                }
2099
            }
2100
        };
2101
        /**
2102
         * Resizes all of the panes
2103
         */
2104
        SearchPanes.prototype.resizePanes = function () {
2105
            if (this.c.layout === 'auto') {
2106
                var contWidth = $$1(this.s.dt.searchPanes.container()).width();
2107
                var target = Math.floor(contWidth / 260.0); // The neatest number of panes per row
2108
                var highest = 1;
2109
                var highestmod = 0;
2110
                var dispIndex = [];
2111
                // Get the indexes of all of the displayed panes
2112
                for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2113
                    var pane = _a[_i];
2114
                    if (pane.s.displayed) {
2115
                        dispIndex.push(pane.s.index);
2116
                    }
2117
                }
2118
                var displayCount = dispIndex.length;
2119
                // If the neatest number is the number we have then use this.
2120
                if (target === displayCount) {
2121
                    highest = target;
2122
                }
2123
                else {
2124
                    // Go from the target down and find the value with the most panes left over, this will be the best fit
2125
                    for (var ppr = target; ppr > 1; ppr--) {
2126
                        var rem = displayCount % ppr;
2127
                        if (rem === 0) {
2128
                            highest = ppr;
2129
                            highestmod = 0;
2130
                            break;
2131
                        }
2132
                        // If there are more left over at this amount of panes per row (ppr)
2133
                        // then it fits better so new values
2134
                        else if (rem > highestmod) {
2135
                            highest = ppr;
2136
                            highestmod = rem;
2137
                        }
2138
                    }
2139
                }
2140
                // If there is a perfect fit then none are to be wider
2141
                var widerIndexes = highestmod !== 0 ? dispIndex.slice(dispIndex.length - highestmod, dispIndex.length) : [];
2142
                for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
2143
                    var pane = _c[_b];
2144
                    // Resize the pane with the new layout
2145
                    if (pane.s.displayed) {
2146
                        var layout = 'columns-' + (!widerIndexes.includes(pane.s.index) ? highest : highestmod);
2147
                        pane.resize(layout);
2148
                    }
2149
                }
2150
            }
2151
            else {
2152
                for (var _d = 0, _e = this.s.panes; _d < _e.length; _d++) {
2153
                    var pane = _e[_d];
2154
                    pane.adjustTopRow();
2155
                }
2156
            }
2157
            return this;
2158
        };
2159
        /**
2160
         * Attach the panes, buttons and title to the document
2161
         */
2162
        SearchPanes.prototype._attach = function () {
2163
            var _this = this;
2164
            this.dom.container.removeClass(this.classes.hide);
2165
            this.dom.titleRow.removeClass(this.classes.hide);
2166
            this.dom.titleRow.remove();
2167
            this.dom.title.appendTo(this.dom.titleRow);
2168
            // If the clear button is permitted attach it
2169
            if (this.c.clear) {
2170
                this.dom.clearAll.appendTo(this.dom.titleRow);
2171
                this.dom.clearAll.on('click.dtsps', function () {
2172
                    _this.clearSelections();
2173
                });
2174
            }
2175
            if (this.c.collapse) {
2176
                this._setCollapseListener();
2177
            }
2178
            this.dom.titleRow.appendTo(this.dom.container);
2179
            // Attach the container for each individual pane to the overall container
2180
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2181
                var pane = _a[_i];
2182
                pane.dom.container.appendTo(this.dom.panes);
2183
            }
2184
            // Attach everything to the document
2185
            this.dom.panes.appendTo(this.dom.container);
2186
            if ($$1('div.' + this.classes.container).length === 0) {
2187
                this.dom.container.prependTo(this.s.dt);
2188
            }
2189
            return this.dom.container;
2190
        };
2191
        /**
2192
         * Attach the top row containing the filter count and clear all button
2193
         */
2194
        SearchPanes.prototype._attachExtras = function () {
2195
            this.dom.container.removeClass(this.classes.hide);
2196
            this.dom.titleRow.removeClass(this.classes.hide);
2197
            this.dom.titleRow.remove();
2198
            this.dom.title.appendTo(this.dom.titleRow);
2199
            // If the clear button is permitted attach it
2200
            if (this.c.clear) {
2201
                this.dom.clearAll.appendTo(this.dom.titleRow);
2202
            }
2203
            // If collapsing is permitted attach those buttons
2204
            if (this.c.collapse) {
2205
                this.dom.showAll.appendTo(this.dom.titleRow);
2206
                this.dom.collapseAll.appendTo(this.dom.titleRow);
2207
            }
2208
            this.dom.titleRow.appendTo(this.dom.container);
2209
            return this.dom.container;
2210
        };
2211
        /**
2212
         * If there are no panes to display then this method is called to either
2213
         * display a message in their place or hide them completely.
2214
         */
2215
        SearchPanes.prototype._attachMessage = function () {
2216
            // Create a message to display on the screen
2217
            var message;
2218
            try {
2219
                message = this.s.dt.i18n('searchPanes.emptyPanes', this.c.i18n.emptyPanes);
2220
            }
2221
            catch (error) {
2222
                message = null;
2223
            }
2224
            // If the message is an empty string then searchPanes.emptyPanes is undefined,
2225
            // therefore the pane container should be removed from the display
2226
            if (message === null) {
2227
                this.dom.container.addClass(this.classes.hide);
2228
                this.dom.titleRow.removeClass(this.classes.hide);
2229
                return;
2230
            }
2231
            else {
2232
                this.dom.container.removeClass(this.classes.hide);
2233
                this.dom.titleRow.addClass(this.classes.hide);
2234
            }
2235
            // Otherwise display the message
2236
            this.dom.emptyMessage.text(message);
2237
            this.dom.emptyMessage.appendTo(this.dom.container);
2238
            return this.dom.container;
2239
        };
2240
        /**
2241
         * Attaches the panes to the document and displays a message or hides if there are none
2242
         */
2243
        SearchPanes.prototype._attachPaneContainer = function () {
2244
            // If a pane is to be displayed then attach the normal pane output
2245
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2246
                var pane = _a[_i];
2247
                if (pane.s.displayed === true) {
2248
                    return this._attach();
2249
                }
2250
            }
2251
            // Otherwise attach the custom message or remove the container from the display
2252
            return this._attachMessage();
2253
        };
2254
        /**
2255
         * Prepares the panes for selections to be made when cascade is active and a deselect has occured
2256
         *
2257
         * @param newSelectionList the list of selections which are to be made
2258
         */
2259
        SearchPanes.prototype._cascadeRegen = function (newSelectionList, selectTotal) {
2260
            // Set this to true so that the actions taken do not cause this to run until it is finished
2261
            this.regenerating = true;
2262
            // If only one pane has been selected then take note of its index
2263
            var solePane = -1;
2264
            if (newSelectionList.length === 1 && selectTotal !== null && selectTotal !== 0) {
2265
                solePane = newSelectionList[0].index;
2266
            }
2267
            // Let the pane know that a cascadeRegen is taking place to avoid unexpected behaviour
2268
            // and clear all of the previous selections in the pane
2269
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2270
                var pane = _a[_i];
2271
                pane.setCascadeRegen(true);
2272
                pane.setClear(true);
2273
                // If this is the same as the pane with the only selection then pass it as a parameter into clearPane
2274
                if (pane.s.dtPane !== undefined && pane.s.index === solePane || pane.s.dtPane !== undefined) {
2275
                    pane.clearPane();
2276
                }
2277
                pane.setClear(false);
2278
            }
2279
            // Rebin panes
2280
            this.s.dt.draw();
2281
            // While all of the selections have been removed, check the table lengths
2282
            // If they are different, another filter is in place and we need to force viewTotal to be used
2283
            var noSelectionsTableLength = this.s.dt.rows({ search: 'applied' }).data().toArray().length;
2284
            var tableLength = this.s.dt.rows().data().toArray().length;
2285
            if (tableLength !== noSelectionsTableLength) {
2286
                for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
2287
                    var pane = _c[_b];
2288
                    pane.s.forceViewTotal = true;
2289
                }
2290
            }
2291
            for (var _d = 0, _e = this.s.panes; _d < _e.length; _d++) {
2292
                var pane = _e[_d];
2293
                pane.updatePane(true);
2294
            }
2295
            // Remake Selections
2296
            this._makeCascadeSelections(newSelectionList);
2297
            // Set the selection list property to be the list without the selections from the deselect pane
2298
            this.s.selectionList = newSelectionList;
2299
            // The regeneration of selections is over so set it back to false
2300
            for (var _f = 0, _g = this.s.panes; _f < _g.length; _f++) {
2301
                var pane = _g[_f];
2302
                pane.setCascadeRegen(false);
2303
            }
2304
            this.regenerating = false;
2305
            // ViewTotal has already been forced at this point so can cancel that for future
2306
            if (tableLength !== noSelectionsTableLength) {
2307
                for (var _h = 0, _j = this.s.panes; _h < _j.length; _h++) {
2308
                    var pane = _j[_h];
2309
                    pane.s.forceViewTotal = false;
2310
                }
2311
            }
2312
        };
2313
        /**
2314
         * Attaches the message to the document but does not add any panes
2315
         */
2316
        SearchPanes.prototype._checkMessage = function () {
2317
            // If a pane is to be displayed then attach the normal pane output
2318
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2319
                var pane = _a[_i];
2320
                if (pane.s.displayed === true) {
2321
                    // Ensure that the empty message is removed if a pane is displayed
2322
                    this.dom.emptyMessage.remove();
2323
                    this.dom.titleRow.removeClass(this.classes.hide);
2324
                    return;
2325
                }
2326
            }
2327
            // Otherwise attach the custom message or remove the container from the display
2328
            return this._attachMessage();
2329
        };
2330
        /**
2331
         * Checks which panes are collapsed and then performs relevant actions to the collapse/show all buttons
2332
         *
2333
         * @param pane The pane to be checked
2334
         */
2335
        SearchPanes.prototype._checkCollapse = function () {
2336
            var disableClose = true;
2337
            var disableShow = true;
2338
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2339
                var pane = _a[_i];
2340
                if (pane.s.displayed) {
2341
                    // It the pane is not collapsed
2342
                    if (!pane.dom.collapseButton.hasClass(pane.classes.rotated)) {
2343
                        // Enable the collapse all button
2344
                        this.dom.collapseAll.removeClass(this.classes.disabledButton).removeAttr('disabled');
2345
                        disableClose = false;
2346
                    }
2347
                    else {
2348
                        // Otherwise enable the show all button
2349
                        this.dom.showAll.removeClass(this.classes.disabledButton).removeAttr('disabled');
2350
                        disableShow = false;
2351
                    }
2352
                }
2353
            }
2354
            // If this flag is still true, no panes are open so the close button should be disabled
2355
            if (disableClose) {
2356
                this.dom.collapseAll.addClass(this.classes.disabledButton).attr('disabled', 'true');
2357
            }
2358
            // If this flag is still true, no panes are closed so the show button should be disabled
2359
            if (disableShow) {
2360
                this.dom.showAll.addClass(this.classes.disabledButton).attr('disabled', 'true');
2361
            }
2362
        };
2363
        /**
2364
         * Collapses all of the panes
2365
         */
2366
        SearchPanes.prototype._collapseAll = function () {
2367
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2368
                var pane = _a[_i];
2369
                pane.collapse();
2370
            }
2371
        };
2372
        /**
2373
         * Gets the selection list from the previous state and stores it in the selectionList Property
2374
         */
2375
        SearchPanes.prototype._getState = function () {
2376
            var loadedFilter = this.s.dt.state.loaded();
2377
            if (loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.selectionList !== undefined) {
2378
                this.s.selectionList = loadedFilter.searchPanes.selectionList;
2379
            }
2380
        };
2381
        /**
2382
         * Makes all of the selections when cascade is active
2383
         *
2384
         * @param newSelectionList the list of selections to be made, in the order they were originally selected
2385
         */
2386
        SearchPanes.prototype._makeCascadeSelections = function (newSelectionList) {
2387
            // make selections in the order they were made previously,
2388
            // excluding those from the pane where a deselect was made
2389
            for (var i = 0; i < newSelectionList.length; i++) {
2390
                var _loop_1 = function (pane) {
2391
                    if (pane.s.index === newSelectionList[i].index && pane.s.dtPane !== undefined) {
2392
                        // When regenerating the cascade selections we need this flag so that
2393
                        // the panes are only ignored if it
2394
                        // is the last selection and the pane for that selection
2395
                        if (i === newSelectionList.length - 1) {
2396
                            pane.s.lastCascade = true;
2397
                        }
2398
                        // if there are any selections currently in the pane then
2399
                        // deselect them as we are about to make our new selections
2400
                        if (pane.s.dtPane.rows({ selected: true }).data().toArray().length > 0 && pane.s.dtPane !== undefined) {
2401
                            pane.setClear(true);
2402
                            pane.clearPane();
2403
                            pane.setClear(false);
2404
                        }
2405
                        var _loop_2 = function (row) {
2406
                            var found = false;
2407
                            pane.s.dtPane.rows().every(function (rowIdx) {
2408
                                if (pane.s.dtPane.row(rowIdx).data() !== undefined &&
2409
                                    row !== undefined &&
2410
                                    pane.s.dtPane.row(rowIdx).data().filter === row.filter) {
2411
                                    found = true;
2412
                                    pane.s.dtPane.row(rowIdx).select();
2413
                                }
2414
                            });
2415
                            if (!found) {
2416
                                var newRow = pane.addRow(row.display, row.filter, 0, row.total, row.sort, row.type, row.className);
2417
                                newRow.select();
2418
                            }
2419
                        };
2420
                        // select every row in the pane that was selected previously
2421
                        for (var _i = 0, _a = newSelectionList[i].rows; _i < _a.length; _i++) {
2422
                            var row = _a[_i];
2423
                            _loop_2(row);
2424
                        }
2425
                        pane.s.scrollTop = $$1(pane.s.dtPane.table().node()).parent()[0].scrollTop;
2426
                        pane.s.dtPane.draw();
2427
                        pane.s.dtPane.table().node().parentNode.scrollTop = pane.s.scrollTop;
2428
                        pane.s.lastCascade = false;
2429
                    }
2430
                };
2431
                // As the selections may have been made across the panes
2432
                // in a different order to the pane index we must identify
2433
                // which pane has the index of the selection. This is also important for colreorder etc
2434
                for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2435
                    var pane = _a[_i];
2436
                    _loop_1(pane);
2437
                }
2438
            }
2439
        };
2440
        /**
2441
         * Declares the instances of individual searchpanes dependant on the number of columns.
2442
         * It is necessary to run this once preInit has completed otherwise no panes will be
2443
         * created as the column count will be 0.
2444
         *
2445
         * @param table the DataTable api for the parent table
2446
         * @param paneSettings the settings passed into the constructor
2447
         * @param opts the options passed into the constructor
2448
         */
2449
        SearchPanes.prototype._paneDeclare = function (table, paneSettings, opts) {
2450
            var _this = this;
2451
            // Create Panes
2452
            table
2453
                .columns(this.c.columns.length > 0 ? this.c.columns : undefined)
2454
                .eq(0)
2455
                .each(function (idx) {
2456
                _this.s.panes.push(new SearchPane(paneSettings, opts, idx, _this.c.layout, _this.dom.panes));
2457
            });
2458
            // If there is any extra custom panes defined then create panes for them too
2459
            var rowLength = table.columns().eq(0).toArray().length;
2460
            var paneLength = this.c.panes.length;
2461
            for (var i = 0; i < paneLength; i++) {
2462
                var id = rowLength + i;
2463
                this.s.panes.push(new SearchPane(paneSettings, opts, id, this.c.layout, this.dom.panes, this.c.panes[i]));
2464
            }
2465
            // If a custom ordering is being used
2466
            if (this.c.order.length > 0) {
2467
                // Make a new Array of panes based upon the order
2468
                var newPanes = this.c.order.map(function (name, index, values) { return _this._findPane(name); });
2469
                // Remove the old panes from the dom
2470
                this.dom.panes.empty();
2471
                this.s.panes = newPanes;
2472
                // Append the panes in the correct order
2473
                for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2474
                    var pane = _a[_i];
2475
                    this.dom.panes.append(pane.dom.container);
2476
                }
2477
            }
2478
            // If this internal property is true then the DataTable has been initialised already
2479
            if (this.s.dt.settings()[0]._bInitComplete) {
2480
                this._startup(table);
2481
            }
2482
            else {
2483
                // Otherwise add the paneStartup function to the list of functions
2484
                // that are to be run when the table is initialised. This will garauntee that the
2485
                // panes are initialised before the init event and init Complete callback is fired
2486
                this.s.dt.settings()[0].aoInitComplete.push({ fn: function () {
2487
                        _this._startup(table);
2488
                    } });
2489
            }
2490
        };
2491
        /**
2492
         * Finds a pane based upon the name of that pane
2493
         *
2494
         * @param name string representing the name of the pane
2495
         * @returns SearchPane The pane which has that name
2496
         */
2497
        SearchPanes.prototype._findPane = function (name) {
2498
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2499
                var pane = _a[_i];
2500
                if (name === pane.s.name) {
2501
                    return pane;
2502
                }
2503
            }
2504
        };
2505
        /**
2506
         * Works out which panes to update when data is recieved from the server and viewTotal is active
2507
         */
2508
        SearchPanes.prototype._serverTotals = function () {
2509
            var selectPresent = false;
2510
            var deselectPresent = false;
2511
            var table = this.s.dt;
2512
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2513
                var pane = _a[_i];
2514
                // Identify the pane where a selection or deselection has been made and add it to the list.
2515
                if (pane.s.selectPresent) {
2516
                    this.s.selectionList.push({
2517
                        index: pane.s.index,
2518
                        protect: false,
2519
                        rows: pane.s.dtPane.rows({ selected: true }).data().toArray()
2520
                    });
2521
                    pane.s.selectPresent = false;
2522
                    selectPresent = true;
2523
                    break;
2524
                }
2525
                else if (pane.s.deselect) {
2526
                    var selectedData = pane.s.dtPane.rows({ selected: true }).data().toArray();
2527
                    if (selectedData.length > 0) {
2528
                        this.s.selectionList.push({
2529
                            index: pane.s.index,
2530
                            protect: true,
2531
                            rows: selectedData
2532
                        });
2533
                    }
2534
                    selectPresent = true;
2535
                    deselectPresent = true;
2536
                }
2537
            }
2538
            // Build an updated list based on any selections or deselections added
2539
            if (!selectPresent) {
2540
                this.s.selectionList = [];
2541
            }
2542
            else {
2543
                var newSelectionList = [];
2544
                for (var i = 0; i < this.s.selectionList.length; i++) {
2545
                    var further = false;
2546
                    // Find out if this selection is the last one in the list for that pane
2547
                    for (var j = i + 1; j < this.s.selectionList.length; j++) {
2548
                        if (this.s.selectionList[j].index === this.s.selectionList[i].index) {
2549
                            further = true;
2550
                        }
2551
                    }
2552
                    // If there are no selections for this pane in the list then just push this one
2553
                    if (!further) {
2554
                        var push = false;
2555
                        for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
2556
                            var pane = _c[_b];
2557
                            if (pane.s.index === this.s.selectionList[i].index &&
2558
                                pane.s.dtPane.rows({ selected: true }).data().toArray().length > 0) {
2559
                                push = true;
2560
                            }
2561
                        }
2562
                        if (push) {
2563
                            newSelectionList.push(this.s.selectionList[i]);
2564
                        }
2565
                    }
2566
                }
2567
                this.s.selectionList = newSelectionList;
2568
            }
2569
            var initIdx = -1;
2570
            // If there has been a deselect and only one pane has a selection then update everything
2571
            if (deselectPresent && this.s.selectionList.length === 1) {
2572
                for (var _d = 0, _e = this.s.panes; _d < _e.length; _d++) {
2573
                    var pane = _e[_d];
2574
                    pane.s.lastSelect = false;
2575
                    pane.s.deselect = false;
2576
                    if (pane.s.dtPane !== undefined && pane.s.dtPane.rows({ selected: true }).data().toArray().length > 0) {
2577
                        initIdx = pane.s.index;
2578
                    }
2579
                }
2580
            }
2581
            // Otherwise if there are more 1 selections then find the last one and set it to not update that pane
2582
            else if (this.s.selectionList.length > 0) {
2583
                var last = this.s.selectionList[this.s.selectionList.length - 1].index;
2584
                for (var _f = 0, _g = this.s.panes; _f < _g.length; _f++) {
2585
                    var pane = _g[_f];
2586
                    pane.s.lastSelect = pane.s.index === last;
2587
                    pane.s.deselect = false;
2588
                }
2589
            }
2590
            // Otherwise if there are no selections then find where that took place and do not update to maintain scrolling
2591
            else if (this.s.selectionList.length === 0) {
2592
                for (var _h = 0, _j = this.s.panes; _h < _j.length; _h++) {
2593
                    var pane = _j[_h];
2594
                    // pane.s.lastSelect = (pane.s.deselect === true);
2595
                    pane.s.lastSelect = false;
2596
                    pane.s.deselect = false;
2597
                }
2598
            }
2599
            this.dom.panes.empty();
2600
            // Rebuild the desired panes
2601
            for (var _k = 0, _l = this.s.panes; _k < _l.length; _k++) {
2602
                var pane = _l[_k];
2603
                if (!pane.s.lastSelect) {
2604
                    pane.rebuildPane(undefined, this.s.dt.page.info().serverSide ? this.s.serverData : undefined, pane.s.index === initIdx ? true : null, true);
2605
                }
2606
                else {
2607
                    pane._setListeners();
2608
                }
2609
                // append all of the panes and enable select
2610
                this.dom.panes.append(pane.dom.container);
2611
                if (pane.s.dtPane !== undefined) {
2612
                    $$1(pane.s.dtPane.table().node()).parent()[0].scrollTop = pane.s.scrollTop;
2613
                    // eslint-disable-next-line no-extra-parens
2614
                    $$1.fn.dataTable.select.init(pane.s.dtPane);
2615
                }
2616
            }
2617
            this._updateSelection();
2618
        };
2619
        /**
2620
         * Sets the listeners for the collapse and show all buttons
2621
         * Also sets and performs checks on current panes to see if they are collapsed
2622
         */
2623
        SearchPanes.prototype._setCollapseListener = function () {
2624
            var _this = this;
2625
            this.dom.collapseAll.on('click.dtsps', function () {
2626
                _this._collapseAll();
2627
                _this.dom.collapseAll.addClass(_this.classes.disabledButton).attr('disabled', 'true');
2628
                _this.dom.showAll.removeClass(_this.classes.disabledButton).removeAttr('disabled');
2629
                _this.s.dt.state.save();
2630
            });
2631
            this.dom.showAll.on('click.dtsps', function () {
2632
                _this._showAll();
2633
                _this.dom.showAll.addClass(_this.classes.disabledButton).attr('disabled', 'true');
2634
                _this.dom.collapseAll.removeClass(_this.classes.disabledButton).removeAttr('disabled');
2635
                _this.s.dt.state.save();
2636
            });
2637
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2638
                var pane = _a[_i];
2639
                // We want to make the same check whenever there is a collapse/expand
2640
                pane.dom.collapseButton.on('click', function () { return _this._checkCollapse(); });
2641
            }
2642
            this._checkCollapse();
2643
        };
2644
        /**
2645
         * Shows all of the panes
2646
         */
2647
        SearchPanes.prototype._showAll = function () {
2648
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2649
                var pane = _a[_i];
2650
                pane.show();
2651
            }
2652
        };
2653
        /**
2654
         * Initialises the tables previous/preset selections and initialises callbacks for events
2655
         *
2656
         * @param table the parent table for which the searchPanes are being created
2657
         */
2658
        SearchPanes.prototype._startup = function (table) {
2659
            var _this = this;
2660
            this.dom.container.text('');
2661
            // Attach clear button and title bar to the document
2662
            this._attachExtras();
2663
            this.dom.container.append(this.dom.panes);
2664
            this.dom.panes.empty();
2665
            var loadedFilter = this.s.dt.state.loaded();
2666
            if (this.c.viewTotal && !this.c.cascadePanes) {
2667
                if (loadedFilter !== null &&
2668
                    loadedFilter !== undefined &&
2669
                    loadedFilter.searchPanes !== undefined &&
2670
                    loadedFilter.searchPanes.panes !== undefined) {
2671
                    var filterActive = false;
2672
                    for (var _i = 0, _a = loadedFilter.searchPanes.panes; _i < _a.length; _i++) {
2673
                        var pane = _a[_i];
2674
                        if (pane.selected.length > 0) {
2675
                            filterActive = true;
2676
                            break;
2677
                        }
2678
                    }
2679
                    if (filterActive) {
2680
                        for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
2681
                            var pane = _c[_b];
2682
                            pane.s.showFiltered = true;
2683
                        }
2684
                    }
2685
                }
2686
            }
2687
            for (var _d = 0, _e = this.s.panes; _d < _e.length; _d++) {
2688
                var pane = _e[_d];
2689
                pane.rebuildPane(undefined, Object.keys(this.s.serverData).length > 0 ? this.s.serverData : undefined);
2690
                this.dom.panes.append(pane.dom.container);
2691
            }
2692
            // If the layout is set to auto then the panes need to be resized to their best fit
2693
            if (this.c.layout === 'auto') {
2694
                this.resizePanes();
2695
            }
2696
            // Reset the paging if that has been saved in the state
2697
            if (!this.s.stateRead && loadedFilter !== null && loadedFilter !== undefined) {
2698
                this.s.dt.page(loadedFilter.start / this.s.dt.page.len());
2699
                this.s.dt.draw('page');
2700
            }
2701
            this.s.stateRead = true;
2702
            if (this.c.viewTotal && !this.c.cascadePanes) {
2703
                for (var _f = 0, _g = this.s.panes; _f < _g.length; _f++) {
2704
                    var pane = _g[_f];
2705
                    pane.updatePane();
2706
                }
2707
            }
2708
            this._checkMessage();
2709
            // When a draw is called on the DataTable, update all of the panes incase the data in the DataTable has changed
2710
            table.on('preDraw.dtsps', function () {
2711
                // Check that the panes are not updating to avoid infinite loops
2712
                // Also check that this draw is not due to paging
2713
                if (!_this.s.updating && !_this.s.paging) {
2714
                    if ((_this.c.cascadePanes || _this.c.viewTotal) && !_this.s.dt.page.info().serverSide) {
2715
                        _this.redrawPanes(_this.c.viewTotal);
2716
                    }
2717
                    else {
2718
                        _this._updateFilterCount();
2719
                        _this._updateSelection();
2720
                    }
2721
                    _this.s.filterPane = -1;
2722
                }
2723
                // Paging flag reset - we only need to dodge the draw once
2724
                _this.s.paging = false;
2725
            });
2726
            $$1(window).on('resize.dtsp', dataTable$1.util.throttle(function () {
2727
                _this.resizePanes();
2728
            }));
2729
            // Whenever a state save occurs store the selection list in the state object
2730
            this.s.dt.on('stateSaveParams.dtsp', function (e, settings, data) {
2731
                if (data.searchPanes === undefined) {
2732
                    data.searchPanes = {};
2733
                }
2734
                data.searchPanes.selectionList = _this.s.selectionList;
2735
            });
2736
            // Listener for paging on main table
2737
            table.off('page');
2738
            table.on('page', function () {
2739
                _this.s.paging = true;
2740
                _this.s.page = _this.s.dt.page();
2741
            });
2742
            if (this.s.dt.page.info().serverSide) {
2743
                table.off('preXhr.dt');
2744
                table.on('preXhr.dt', function (e, settings, data) {
2745
                    if (data.searchPanes === undefined) {
2746
                        data.searchPanes = {};
2747
                    }
2748
                    if (data.searchPanes_null === undefined) {
2749
                        data.searchPanes_null = {};
2750
                    }
2751
                    // Count how many filters are being applied
2752
                    var filterCount = 0;
2753
                    for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
2754
                        var pane = _a[_i];
2755
                        var src = _this.s.dt.column(pane.s.index).dataSrc();
2756
                        if (data.searchPanes[src] === undefined) {
2757
                            data.searchPanes[src] = {};
2758
                        }
2759
                        if (data.searchPanes_null[src] === undefined) {
2760
                            data.searchPanes_null[src] = {};
2761
                        }
2762
                        if (pane.s.dtPane !== undefined) {
2763
                            var rowData = pane.s.dtPane.rows({ selected: true }).data().toArray();
2764
                            for (var i = 0; i < rowData.length; i++) {
2765
                                data.searchPanes[src][i] = rowData[i].filter;
2766
                                if (data.searchPanes[src][i] === null) {
2767
                                    data.searchPanes_null[src][i] = true;
2768
                                }
2769
                                filterCount++;
2770
                            }
2771
                        }
2772
                    }
2773
                    if (_this.c.viewTotal) {
2774
                        _this._prepViewTotal(filterCount);
2775
                    }
2776
                    // If there is a filter to be applied, then we need to read from the start of the result set
2777
                    // and set the paging to 0. This matches the behaviour of client side processing
2778
                    if (filterCount > 0) {
2779
                        // If the number of filters has changed we need to read from the start of the
2780
                        // result set and reset the paging
2781
                        if (filterCount !== _this.s.filterCount) {
2782
                            data.start = 0;
2783
                            _this.s.page = 0;
2784
                        }
2785
                        // Otherwise it is a paging request and we need to read from whatever the paging has been set to
2786
                        else {
2787
                            data.start = _this.s.page * _this.s.dt.page.len();
2788
                        }
2789
                        _this.s.dt.page(_this.s.page);
2790
                        _this.s.filterCount = filterCount;
2791
                    }
2792
                });
2793
            }
2794
            else {
2795
                table.on('preXhr.dt', function (e, settings, data) {
2796
                    for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
2797
                        var pane = _a[_i];
2798
                        pane.clearData();
2799
                    }
2800
                });
2801
            }
2802
            // If the data is reloaded from the server then it is possible that it has changed completely,
2803
            // so we need to rebuild the panes
2804
            this.s.dt.on('xhr', function (e, settings, json, xhr) {
2805
                if (settings.nTable !== _this.s.dt.table().node()) {
2806
                    return;
2807
                }
2808
                var processing = false;
2809
                if (!_this.s.dt.page.info().serverSide) {
2810
                    _this.s.dt.one('preDraw', function () {
2811
                        if (processing) {
2812
                            return;
2813
                        }
2814
                        var page = _this.s.dt.page();
2815
                        processing = true;
2816
                        _this.s.updating = true;
2817
                        _this.dom.panes.empty();
2818
                        for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
2819
                            var pane = _a[_i];
2820
                            pane.clearData(); // Clears all of the bins and will mean that the data has to be re-read
2821
                            // Pass a boolean to say whether this is the last choice made for maintaining selections
2822
                            // when rebuilding
2823
                            pane.rebuildPane(_this.s.selectionList[_this.s.selectionList.length - 1] !== undefined ?
2824
                                pane.s.index === _this.s.selectionList[_this.s.selectionList.length - 1].index :
2825
                                false, undefined, undefined, true);
2826
                            _this.dom.panes.append(pane.dom.container);
2827
                        }
2828
                        if (!_this.s.dt.page.info().serverSide) {
2829
                            _this.s.dt.draw();
2830
                        }
2831
                        _this.s.updating = false;
2832
                        if (_this.c.cascadePanes || _this.c.viewTotal) {
2833
                            _this.redrawPanes(_this.c.cascadePanes);
2834
                        }
2835
                        else {
2836
                            _this._updateSelection();
2837
                        }
2838
                        _this._checkMessage();
2839
                        _this.s.dt.one('draw', function () {
2840
                            _this.s.updating = true;
2841
                            _this.s.dt.page(page).draw(false);
2842
                            _this.s.updating = false;
2843
                        });
2844
                    });
2845
                }
2846
            });
2847
            // PreSelect any selections which have been defined using the preSelect option
2848
            for (var _h = 0, _j = this.s.panes; _h < _j.length; _h++) {
2849
                var pane = _j[_h];
2850
                if (pane !== undefined &&
2851
                    pane.s.dtPane !== undefined &&
2852
                    (pane.s.colOpts.preSelect !== undefined && pane.s.colOpts.preSelect.length > 0 ||
2853
                        pane.customPaneSettings !== null &&
2854
                            pane.customPaneSettings.preSelect !== undefined &&
2855
                            pane.customPaneSettings.preSelect.length > 0)) {
2856
                    var tableLength = pane.s.dtPane.rows().data().toArray().length;
2857
                    for (var i = 0; i < tableLength; i++) {
2858
                        if (pane.s.colOpts.preSelect.includes(pane.s.dtPane.cell(i, 0).data()) ||
2859
                            pane.customPaneSettings !== null &&
2860
                                pane.customPaneSettings.preSelect !== undefined &&
2861
                                pane.customPaneSettings.preSelect.includes(pane.s.dtPane.cell(i, 0).data())) {
2862
                            pane.s.dtPane.row(i).select();
2863
                        }
2864
                    }
2865
                    pane.updateTable();
2866
                }
2867
            }
2868
            if (this.s.selectionList !== undefined && this.s.selectionList.length > 0) {
2869
                var last = this.s.selectionList[this.s.selectionList.length - 1].index;
2870
                for (var _k = 0, _l = this.s.panes; _k < _l.length; _k++) {
2871
                    var pane = _l[_k];
2872
                    pane.s.lastSelect = pane.s.index === last;
2873
                }
2874
            }
2875
            // If cascadePanes is active then make the previous selections in the order they were previously
2876
            if (this.s.selectionList.length > 0 && this.c.cascadePanes) {
2877
                this._cascadeRegen(this.s.selectionList, this.s.selectionList.length);
2878
            }
2879
            // Update the title bar to show how many filters have been selected
2880
            this._updateFilterCount();
2881
            // If the table is destroyed and restarted then clear the selections so that they do not persist.
2882
            table.on('destroy.dtsps', function () {
2883
                for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
2884
                    var pane = _a[_i];
2885
                    pane.destroy();
2886
                }
2887
                table.off('.dtsps');
2888
                _this.dom.collapseAll.off('.dtsps');
2889
                _this.dom.showAll.off('.dtsps');
2890
                _this.dom.clearAll.off('.dtsps');
2891
                _this.dom.container.remove();
2892
                _this.clearSelections();
2893
            });
2894
            if (this.c.collapse) {
2895
                this._setCollapseListener();
2896
            }
2897
            // When the clear All button has been pressed clear all of the selections in the panes
2898
            if (this.c.clear) {
2899
                this.dom.clearAll.on('click.dtsps', function () {
2900
                    _this.clearSelections();
2901
                });
2902
            }
2903
            table.settings()[0]._searchPanes = this;
2904
            // This state save is required so that state is maintained over multiple refreshes if no actions are made
2905
            this.s.dt.state.save();
2906
        };
2907
        SearchPanes.prototype._prepViewTotal = function (selectTotal) {
2908
            var filterPane = this.s.filterPane;
2909
            var filterActive = false;
2910
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2911
                var pane = _a[_i];
2912
                if (pane.s.dtPane !== undefined) {
2913
                    var selectLength = pane.s.dtPane.rows({ selected: true }).data().toArray().length;
2914
                    // If filterPane === -1 then a pane with a selection has not been found yet,
2915
                    // so set filterPane to that panes index
2916
                    if (selectLength > 0 && filterPane === -1) {
2917
                        filterPane = pane.s.index;
2918
                        filterActive = true;
2919
                    }
2920
                    // Then if another pane is found with a selection then set filterPane to null to
2921
                    // show that multiple panes have selections present
2922
                    else if (selectLength > 0) {
2923
                        filterPane = null;
2924
                    }
2925
                }
2926
            }
2927
            if (selectTotal !== null && selectTotal !== 0) {
2928
                filterPane = null;
2929
            }
2930
            // Update all of the panes to reflect the current state of the filters
2931
            for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
2932
                var pane = _c[_b];
2933
                if (pane.s.dtPane !== undefined) {
2934
                    pane.s.filteringActive = true;
2935
                    if (filterPane !== -1 && filterPane !== null && filterPane === pane.s.index ||
2936
                        filterActive === false) {
2937
                        pane.s.filteringActive = false;
2938
                    }
2939
                }
2940
            }
2941
        };
2942
        /**
2943
         * Updates the number of filters that have been applied in the title
2944
         */
2945
        SearchPanes.prototype._updateFilterCount = function () {
2946
            var filterCount = 0;
2947
            // Add the number of all of the filters throughout the panes
2948
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2949
                var pane = _a[_i];
2950
                if (pane.s.dtPane !== undefined) {
2951
                    filterCount += pane.getPaneCount();
2952
                }
2953
            }
2954
            // Run the message through the internationalisation method to improve readability
2955
            var message = this.s.dt.i18n('searchPanes.title', this.c.i18n.title, filterCount);
2956
            this.dom.title.text(message);
2957
            if (this.c.filterChanged !== undefined && typeof this.c.filterChanged === 'function') {
2958
                this.c.filterChanged.call(this.s.dt, filterCount);
2959
            }
2960
            if (filterCount === 0) {
2961
                this.dom.clearAll.addClass(this.classes.disabledButton).attr('disabled', 'true');
2962
            }
2963
            else {
2964
                this.dom.clearAll.removeClass(this.classes.disabledButton).removeAttr('disabled');
2965
            }
2966
        };
2967
        /**
2968
         * Updates the selectionList when cascade is not in place
2969
         */
2970
        SearchPanes.prototype._updateSelection = function () {
2971
            this.s.selectionList = [];
2972
            for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
2973
                var pane = _a[_i];
2974
                if (pane.s.dtPane !== undefined) {
2975
                    this.s.selectionList.push({
2976
                        index: pane.s.index,
2977
                        protect: false,
2978
                        rows: pane.s.dtPane.rows({ selected: true }).data().toArray()
2979
                    });
2980
                }
2981
            }
2982
        };
2983
        SearchPanes.version = '1.4.0';
2984
        SearchPanes.classes = {
2985
            clear: 'dtsp-clear',
2986
            clearAll: 'dtsp-clearAll',
2987
            collapseAll: 'dtsp-collapseAll',
2988
            container: 'dtsp-searchPanes',
2989
            disabledButton: 'dtsp-disabledButton',
2990
            emptyMessage: 'dtsp-emptyMessage',
2991
            hide: 'dtsp-hidden',
2992
            panes: 'dtsp-panesContainer',
2993
            search: 'dtsp-search',
2994
            showAll: 'dtsp-showAll',
2995
            title: 'dtsp-title',
2996
            titleRow: 'dtsp-titleRow'
2997
        };
2998
        // Define SearchPanes default options
2999
        SearchPanes.defaults = {
3000
            cascadePanes: false,
3001
            clear: true,
3002
            collapse: true,
3003
            columns: [],
3004
            container: function (dt) {
3005
                return dt.table().container();
3006
            },
3007
            filterChanged: undefined,
3008
            i18n: {
3009
                clearMessage: 'Clear All',
3010
                clearPane: '&times;',
3011
                collapse: {
3012
                    0: 'SearchPanes',
3013
                    _: 'SearchPanes (%d)'
3014
                },
3015
                collapseMessage: 'Collapse All',
3016
                count: '{total}',
3017
                countFiltered: '{shown} ({total})',
3018
                emptyMessage: '<em>No data</em>',
3019
                emptyPanes: 'No SearchPanes',
3020
                loadMessage: 'Loading Search Panes...',
3021
                showMessage: 'Show All',
3022
                title: 'Filters Active - %d'
3023
            },
3024
            layout: 'auto',
3025
            order: [],
3026
            panes: [],
3027
            viewTotal: false
3028
        };
3029
        return SearchPanes;
3030
    }());
3031

3032
    /*! SearchPanes 1.4.0
3033
     * 2019-2020 SpryMedia Ltd - datatables.net/license
3034
     */
3035
    // DataTables extensions common UMD. Note that this allows for AMD, CommonJS
3036
    // (with window and jQuery being allowed as parameters to the returned
3037
    // function) or just default browser loading.
3038
    (function (factory) {
3039
        if (typeof define === 'function' && define.amd) {
3040
            // AMD
3041
            define(['jquery', 'datatables.net'], function ($) {
3042
                return factory($, window, document);
3043
            });
3044
        }
3045
        else if (typeof exports === 'object') {
3046
            // CommonJS
3047
            module.exports = function (root, $) {
3048
                if (!root) {
3049
                    root = window;
3050
                }
3051
                if (!$ || !$.fn.dataTable) {
3052
                    // eslint-disable-next-line @typescript-eslint/no-var-requires
3053
                    $ = require('datatables.net')(root, $).$;
3054
                }
3055
                return factory($, root, root.document);
3056
            };
3057
        }
3058
        else {
3059
            // Browser - assume jQuery has already been loaded
3060
            // eslint-disable-next-line no-extra-parens
3061
            factory(window.jQuery, window, document);
3062
        }
3063
    }(function ($, window, document) {
3064
        setJQuery($);
3065
        setJQuery$1($);
3066
        var dataTable = $.fn.dataTable;
3067
        // eslint-disable-next-line no-extra-parens
3068
        $.fn.dataTable.SearchPanes = SearchPanes;
3069
        // eslint-disable-next-line no-extra-parens
3070
        $.fn.DataTable.SearchPanes = SearchPanes;
3071
        // eslint-disable-next-line no-extra-parens
3072
        $.fn.dataTable.SearchPane = SearchPane;
3073
        // eslint-disable-next-line no-extra-parens
3074
        $.fn.DataTable.SearchPane = SearchPane;
3075
        // eslint-disable-next-line no-extra-parens
3076
        var apiRegister = $.fn.dataTable.Api.register;
3077
        apiRegister('searchPanes()', function () {
3078
            return this;
3079
        });
3080
        apiRegister('searchPanes.clearSelections()', function () {
3081
            return this.iterator('table', function (ctx) {
3082
                if (ctx._searchPanes) {
3083
                    ctx._searchPanes.clearSelections();
3084
                }
3085
            });
3086
        });
3087
        apiRegister('searchPanes.rebuildPane()', function (targetIdx, maintainSelections) {
3088
            return this.iterator('table', function (ctx) {
3089
                if (ctx._searchPanes) {
3090
                    ctx._searchPanes.rebuild(targetIdx, maintainSelections);
3091
                }
3092
            });
3093
        });
3094
        apiRegister('searchPanes.resizePanes()', function () {
3095
            var ctx = this.context[0];
3096
            return ctx._searchPanes ?
3097
                ctx._searchPanes.resizePanes() :
3098
                null;
3099
        });
3100
        apiRegister('searchPanes.container()', function () {
3101
            var ctx = this.context[0];
3102
            return ctx._searchPanes
3103
                ? ctx._searchPanes.getNode()
3104
                : null;
3105
        });
3106
        $.fn.dataTable.ext.buttons.searchPanesClear = {
3107
            action: function (e, dt, node, config) {
3108
                dt.searchPanes.clearSelections();
3109
            },
3110
            text: 'Clear Panes'
3111
        };
3112
        $.fn.dataTable.ext.buttons.searchPanes = {
3113
            action: function (e, dt, node, config) {
3114
                e.stopPropagation();
3115
                this.popover(config._panes.getNode(), {
3116
                    align: 'dt-container'
3117
                });
3118
                config._panes.rebuild(undefined, true);
3119
            },
3120
            config: {},
3121
            init: function (dt, node, config) {
3122
                var panes = new $.fn.dataTable.SearchPanes(dt, $.extend({
3123
                    filterChanged: function (count) {
3124
                        // console.log(dt.context[0])
3125
                        dt.button(node).text(dt.i18n('searchPanes.collapse', dt.context[0].oLanguage.searchPanes !== undefined ?
3126
                            dt.context[0].oLanguage.searchPanes.collapse :
3127
                            dt.context[0]._searchPanes.c.i18n.collapse, count));
3128
                    }
3129
                }, config.config));
3130
                var message = dt.i18n('searchPanes.collapse', panes.c.i18n.collapse, 0);
3131
                dt.button(node).text(message);
3132
                config._panes = panes;
3133
            },
3134
            text: 'Search Panes'
3135
        };
3136
        function _init(settings, options, fromPre) {
3137
            if (options === void 0) { options = null; }
3138
            if (fromPre === void 0) { fromPre = false; }
3139
            var api = new dataTable.Api(settings);
3140
            var opts = options
3141
                ? options
3142
                : api.init().searchPanes || dataTable.defaults.searchPanes;
3143
            var searchPanes = new SearchPanes(api, opts, fromPre);
3144
            var node = searchPanes.getNode();
3145
            return node;
3146
        }
3147
        // Attach a listener to the document which listens for DataTables initialisation
3148
        // events so we can automatically initialise
3149
        $(document).on('preInit.dt.dtsp', function (e, settings, json) {
3150
            if (e.namespace !== 'dt') {
3151
                return;
3152
            }
3153
            if (settings.oInit.searchPanes ||
3154
                dataTable.defaults.searchPanes) {
3155
                if (!settings._searchPanes) {
3156
                    _init(settings, null, true);
3157
                }
3158
            }
3159
        });
3160
        // DataTables `dom` feature option
3161
        dataTable.ext.feature.push({
3162
            cFeature: 'P',
3163
            fnInit: _init
3164
        });
3165
        // DataTables 2 layout feature
3166
        if (dataTable.ext.features) {
3167
            dataTable.ext.features.register('searchPanes', _init);
3168
        }
3169
    }));
3170

3171
}());
3172

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.