datatables.net-searchbuilder 1.3.4 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/dataTables.searchBuilder.js +270 -296
- package/js/dataTables.searchBuilder.min.js +4 -149
- package/js/dataTables.searchBuilder.min.mjs +7 -0
- package/js/dataTables.searchBuilder.mjs +3781 -0
- package/package.json +4 -2
- package/types/criteria.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/searchBuilder.bootstrap.d.ts +4 -0
- package/types/searchBuilder.bootstrap4.d.ts +4 -0
- package/types/searchBuilder.bootstrap5.d.ts +4 -0
- package/types/searchBuilder.bulma.d.ts +4 -0
- package/types/searchBuilder.dataTables.d.ts +4 -0
- package/types/searchBuilder.foundation.d.ts +4 -0
- package/types/searchBuilder.jqueryui.d.ts +4 -0
- package/types/searchBuilder.semanticui.d.ts +4 -0
- package/types/types.d.ts +97 -22
|
@@ -0,0 +1,3781 @@
|
|
|
1
|
+
/*! SearchBuilder 1.4.2
|
|
2
|
+
* ©SpryMedia Ltd - datatables.net/license/mit
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import $ from 'jquery';
|
|
6
|
+
import DataTable from 'datatables.net';
|
|
7
|
+
|
|
8
|
+
(function () {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
var $$3;
|
|
12
|
+
var dataTable$3;
|
|
13
|
+
function moment() {
|
|
14
|
+
return window.moment;
|
|
15
|
+
}
|
|
16
|
+
function luxon() {
|
|
17
|
+
return window.luxon;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Sets the value of jQuery for use in the file
|
|
21
|
+
*
|
|
22
|
+
* @param jq the instance of jQuery to be set
|
|
23
|
+
*/
|
|
24
|
+
function setJQuery$2(jq) {
|
|
25
|
+
$$3 = jq;
|
|
26
|
+
dataTable$3 = jq.fn.dataTable;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The Criteria class is used within SearchBuilder to represent a search criteria
|
|
30
|
+
*/
|
|
31
|
+
var Criteria = /** @class */ (function () {
|
|
32
|
+
function Criteria(table, opts, topGroup, index, depth, serverData) {
|
|
33
|
+
var _this = this;
|
|
34
|
+
if (index === void 0) { index = 0; }
|
|
35
|
+
if (depth === void 0) { depth = 1; }
|
|
36
|
+
if (serverData === void 0) { serverData = undefined; }
|
|
37
|
+
// Check that the required version of DataTables is included
|
|
38
|
+
if (!dataTable$3 || !dataTable$3.versionCheck || !dataTable$3.versionCheck('1.10.0')) {
|
|
39
|
+
throw new Error('SearchPane requires DataTables 1.10 or newer');
|
|
40
|
+
}
|
|
41
|
+
this.classes = $$3.extend(true, {}, Criteria.classes);
|
|
42
|
+
// Get options from user and any extra conditions/column types defined by plug-ins
|
|
43
|
+
this.c = $$3.extend(true, {}, Criteria.defaults, $$3.fn.dataTable.ext.searchBuilder, opts);
|
|
44
|
+
var i18n = this.c.i18n;
|
|
45
|
+
this.s = {
|
|
46
|
+
condition: undefined,
|
|
47
|
+
conditions: {},
|
|
48
|
+
data: undefined,
|
|
49
|
+
dataIdx: -1,
|
|
50
|
+
dataPoints: [],
|
|
51
|
+
dateFormat: false,
|
|
52
|
+
depth: depth,
|
|
53
|
+
dt: table,
|
|
54
|
+
filled: false,
|
|
55
|
+
index: index,
|
|
56
|
+
origData: undefined,
|
|
57
|
+
preventRedraw: false,
|
|
58
|
+
serverData: serverData,
|
|
59
|
+
topGroup: topGroup,
|
|
60
|
+
type: '',
|
|
61
|
+
value: []
|
|
62
|
+
};
|
|
63
|
+
this.dom = {
|
|
64
|
+
buttons: $$3('<div/>')
|
|
65
|
+
.addClass(this.classes.buttonContainer),
|
|
66
|
+
condition: $$3('<select disabled/>')
|
|
67
|
+
.addClass(this.classes.condition)
|
|
68
|
+
.addClass(this.classes.dropDown)
|
|
69
|
+
.addClass(this.classes.italic)
|
|
70
|
+
.attr('autocomplete', 'hacking'),
|
|
71
|
+
conditionTitle: $$3('<option value="" disabled selected hidden/>')
|
|
72
|
+
.html(this.s.dt.i18n('searchBuilder.condition', i18n.condition)),
|
|
73
|
+
container: $$3('<div/>')
|
|
74
|
+
.addClass(this.classes.container),
|
|
75
|
+
data: $$3('<select/>')
|
|
76
|
+
.addClass(this.classes.data)
|
|
77
|
+
.addClass(this.classes.dropDown)
|
|
78
|
+
.addClass(this.classes.italic),
|
|
79
|
+
dataTitle: $$3('<option value="" disabled selected hidden/>')
|
|
80
|
+
.html(this.s.dt.i18n('searchBuilder.data', i18n.data)),
|
|
81
|
+
defaultValue: $$3('<select disabled/>')
|
|
82
|
+
.addClass(this.classes.value)
|
|
83
|
+
.addClass(this.classes.dropDown)
|
|
84
|
+
.addClass(this.classes.select)
|
|
85
|
+
.addClass(this.classes.italic),
|
|
86
|
+
"delete": $$3('<button/>')
|
|
87
|
+
.html(this.s.dt.i18n('searchBuilder.delete', i18n["delete"]))
|
|
88
|
+
.addClass(this.classes["delete"])
|
|
89
|
+
.addClass(this.classes.button)
|
|
90
|
+
.attr('title', this.s.dt.i18n('searchBuilder.deleteTitle', i18n.deleteTitle))
|
|
91
|
+
.attr('type', 'button'),
|
|
92
|
+
inputCont: $$3('<div/>')
|
|
93
|
+
.addClass(this.classes.inputCont),
|
|
94
|
+
// eslint-disable-next-line no-useless-escape
|
|
95
|
+
left: $$3('<button/>')
|
|
96
|
+
.html(this.s.dt.i18n('searchBuilder.left', i18n.left))
|
|
97
|
+
.addClass(this.classes.left)
|
|
98
|
+
.addClass(this.classes.button)
|
|
99
|
+
.attr('title', this.s.dt.i18n('searchBuilder.leftTitle', i18n.leftTitle))
|
|
100
|
+
.attr('type', 'button'),
|
|
101
|
+
// eslint-disable-next-line no-useless-escape
|
|
102
|
+
right: $$3('<button/>')
|
|
103
|
+
.html(this.s.dt.i18n('searchBuilder.right', i18n.right))
|
|
104
|
+
.addClass(this.classes.right)
|
|
105
|
+
.addClass(this.classes.button)
|
|
106
|
+
.attr('title', this.s.dt.i18n('searchBuilder.rightTitle', i18n.rightTitle))
|
|
107
|
+
.attr('type', 'button'),
|
|
108
|
+
value: [
|
|
109
|
+
$$3('<select disabled/>')
|
|
110
|
+
.addClass(this.classes.value)
|
|
111
|
+
.addClass(this.classes.dropDown)
|
|
112
|
+
.addClass(this.classes.italic)
|
|
113
|
+
.addClass(this.classes.select)
|
|
114
|
+
],
|
|
115
|
+
valueTitle: $$3('<option value="--valueTitle--" disabled selected hidden/>')
|
|
116
|
+
.html(this.s.dt.i18n('searchBuilder.value', i18n.value))
|
|
117
|
+
};
|
|
118
|
+
// If the greyscale option is selected then add the class to add the grey colour to SearchBuilder
|
|
119
|
+
if (this.c.greyscale) {
|
|
120
|
+
this.dom.data.addClass(this.classes.greyscale);
|
|
121
|
+
this.dom.condition.addClass(this.classes.greyscale);
|
|
122
|
+
this.dom.defaultValue.addClass(this.classes.greyscale);
|
|
123
|
+
for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
|
|
124
|
+
var val = _a[_i];
|
|
125
|
+
val.addClass(this.classes.greyscale);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
$$3(window).on('resize.dtsb', dataTable$3.util.throttle(function () {
|
|
129
|
+
_this.s.topGroup.trigger('dtsb-redrawLogic');
|
|
130
|
+
}));
|
|
131
|
+
this._buildCriteria();
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Escape html characters within a string
|
|
136
|
+
*
|
|
137
|
+
* @param txt the string to be escaped
|
|
138
|
+
* @returns the escaped string
|
|
139
|
+
*/
|
|
140
|
+
Criteria._escapeHTML = function (txt) {
|
|
141
|
+
return txt
|
|
142
|
+
.toString()
|
|
143
|
+
.replace(/&/g, '&')
|
|
144
|
+
.replace(/</g, '<')
|
|
145
|
+
.replace(/>/g, '>')
|
|
146
|
+
.replace(/"/g, '"');
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Parses formatted numbers down to a form where they can be compared
|
|
150
|
+
*
|
|
151
|
+
* @param val the value to convert
|
|
152
|
+
* @returns the converted value
|
|
153
|
+
*/
|
|
154
|
+
Criteria.parseNumFmt = function (val) {
|
|
155
|
+
return +val.replace(/(?!^-)[^0-9.]/g, '');
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Adds the left button to the criteria
|
|
159
|
+
*/
|
|
160
|
+
Criteria.prototype.updateArrows = function (hasSiblings) {
|
|
161
|
+
if (hasSiblings === void 0) { hasSiblings = false; }
|
|
162
|
+
// Empty the container and append all of the elements in the correct order
|
|
163
|
+
this.dom.container.children().detach();
|
|
164
|
+
this.dom.container
|
|
165
|
+
.append(this.dom.data)
|
|
166
|
+
.append(this.dom.condition)
|
|
167
|
+
.append(this.dom.inputCont);
|
|
168
|
+
this.setListeners();
|
|
169
|
+
// Trigger the inserted events for the value elements as they are inserted
|
|
170
|
+
if (this.dom.value[0] !== undefined) {
|
|
171
|
+
this.dom.value[0].trigger('dtsb-inserted');
|
|
172
|
+
}
|
|
173
|
+
for (var i = 1; i < this.dom.value.length; i++) {
|
|
174
|
+
this.dom.inputCont.append(this.dom.value[i]);
|
|
175
|
+
this.dom.value[i].trigger('dtsb-inserted');
|
|
176
|
+
}
|
|
177
|
+
// If this is a top level criteria then don't let it move left
|
|
178
|
+
if (this.s.depth > 1) {
|
|
179
|
+
this.dom.buttons.append(this.dom.left);
|
|
180
|
+
}
|
|
181
|
+
// If the depthLimit of the query has been hit then don't add the right button
|
|
182
|
+
if ((this.c.depthLimit === false || this.s.depth < this.c.depthLimit) && hasSiblings) {
|
|
183
|
+
this.dom.buttons.append(this.dom.right);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this.dom.right.remove();
|
|
187
|
+
}
|
|
188
|
+
this.dom.buttons.append(this.dom["delete"]);
|
|
189
|
+
this.dom.container.append(this.dom.buttons);
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Destroys the criteria, removing listeners and container from the dom
|
|
193
|
+
*/
|
|
194
|
+
Criteria.prototype.destroy = function () {
|
|
195
|
+
// Turn off listeners
|
|
196
|
+
this.dom.data.off('.dtsb');
|
|
197
|
+
this.dom.condition.off('.dtsb');
|
|
198
|
+
this.dom["delete"].off('.dtsb');
|
|
199
|
+
for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
|
|
200
|
+
var val = _a[_i];
|
|
201
|
+
val.off('.dtsb');
|
|
202
|
+
}
|
|
203
|
+
// Remove container from the dom
|
|
204
|
+
this.dom.container.remove();
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* Passes in the data for the row and compares it against this single criteria
|
|
208
|
+
*
|
|
209
|
+
* @param rowData The data for the row to be compared
|
|
210
|
+
* @returns boolean Whether the criteria has passed
|
|
211
|
+
*/
|
|
212
|
+
Criteria.prototype.search = function (rowData, rowIdx) {
|
|
213
|
+
var condition = this.s.conditions[this.s.condition];
|
|
214
|
+
if (this.s.condition !== undefined && condition !== undefined) {
|
|
215
|
+
var filter = rowData[this.s.dataIdx];
|
|
216
|
+
// This check is in place for if a custom decimal character is in place
|
|
217
|
+
if (this.s.type.includes('num') &&
|
|
218
|
+
(this.s.dt.settings()[0].oLanguage.sDecimal !== '' ||
|
|
219
|
+
this.s.dt.settings()[0].oLanguage.sThousands !== '')) {
|
|
220
|
+
var splitRD = [rowData[this.s.dataIdx]];
|
|
221
|
+
if (this.s.dt.settings()[0].oLanguage.sDecimal !== '') {
|
|
222
|
+
splitRD = rowData[this.s.dataIdx].split(this.s.dt.settings()[0].oLanguage.sDecimal);
|
|
223
|
+
}
|
|
224
|
+
if (this.s.dt.settings()[0].oLanguage.sThousands !== '') {
|
|
225
|
+
for (var i = 0; i < splitRD.length; i++) {
|
|
226
|
+
splitRD[i] = splitRD[i].replace(this.s.dt.settings()[0].oLanguage.sThousands, ',');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
filter = splitRD.join('.');
|
|
230
|
+
}
|
|
231
|
+
// If orthogonal data is in place we need to get it's values for searching
|
|
232
|
+
if (this.c.orthogonal.search !== 'filter') {
|
|
233
|
+
var settings = this.s.dt.settings()[0];
|
|
234
|
+
filter = settings.oApi._fnGetCellData(settings, rowIdx, this.s.dataIdx, typeof this.c.orthogonal === 'string' ?
|
|
235
|
+
this.c.orthogonal :
|
|
236
|
+
this.c.orthogonal.search);
|
|
237
|
+
}
|
|
238
|
+
if (this.s.type === 'array') {
|
|
239
|
+
// Make sure we are working with an array
|
|
240
|
+
if (!Array.isArray(filter)) {
|
|
241
|
+
filter = [filter];
|
|
242
|
+
}
|
|
243
|
+
filter.sort();
|
|
244
|
+
for (var _i = 0, filter_1 = filter; _i < filter_1.length; _i++) {
|
|
245
|
+
var filt = filter_1[_i];
|
|
246
|
+
if (filt && typeof filt === 'string') {
|
|
247
|
+
filt = filt.replace(/[\r\n\u2028]/g, ' ');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else if (filter !== null && typeof filter === 'string') {
|
|
252
|
+
filter = filter.replace(/[\r\n\u2028]/g, ' ');
|
|
253
|
+
}
|
|
254
|
+
if (this.s.type.includes('html') && typeof filter === 'string') {
|
|
255
|
+
filter = filter.replace(/(<([^>]+)>)/ig, '');
|
|
256
|
+
}
|
|
257
|
+
// Not ideal, but jqueries .val() returns an empty string even
|
|
258
|
+
// when the value set is null, so we shall assume the two are equal
|
|
259
|
+
if (filter === null) {
|
|
260
|
+
filter = '';
|
|
261
|
+
}
|
|
262
|
+
return condition.search(filter, this.s.value, this);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Gets the details required to rebuild the criteria
|
|
267
|
+
*/
|
|
268
|
+
Criteria.prototype.getDetails = function (deFormatDates) {
|
|
269
|
+
if (deFormatDates === void 0) { deFormatDates = false; }
|
|
270
|
+
// This check is in place for if a custom decimal character is in place
|
|
271
|
+
if (this.s.type !== null &&
|
|
272
|
+
this.s.type.includes('num') &&
|
|
273
|
+
(this.s.dt.settings()[0].oLanguage.sDecimal !== '' || this.s.dt.settings()[0].oLanguage.sThousands !== '')) {
|
|
274
|
+
for (var i = 0; i < this.s.value.length; i++) {
|
|
275
|
+
var splitRD = [this.s.value[i].toString()];
|
|
276
|
+
if (this.s.dt.settings()[0].oLanguage.sDecimal !== '') {
|
|
277
|
+
splitRD = this.s.value[i].split(this.s.dt.settings()[0].oLanguage.sDecimal);
|
|
278
|
+
}
|
|
279
|
+
if (this.s.dt.settings()[0].oLanguage.sThousands !== '') {
|
|
280
|
+
for (var j = 0; j < splitRD.length; j++) {
|
|
281
|
+
splitRD[j] = splitRD[j].replace(this.s.dt.settings()[0].oLanguage.sThousands, ',');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
this.s.value[i] = splitRD.join('.');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
else if (this.s.type !== null && deFormatDates) {
|
|
288
|
+
if (this.s.type.includes('date') ||
|
|
289
|
+
this.s.type.includes('time')) {
|
|
290
|
+
for (var i = 0; i < this.s.value.length; i++) {
|
|
291
|
+
if (this.s.value[i].match(/^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])$/g) === null) {
|
|
292
|
+
this.s.value[i] = '';
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (this.s.type.includes('moment')) {
|
|
297
|
+
for (var i = 0; i < this.s.value.length; i++) {
|
|
298
|
+
if (this.s.value[i] &&
|
|
299
|
+
this.s.value[i].length > 0 &&
|
|
300
|
+
moment()(this.s.value[i], this.s.dateFormat, true).isValid()) {
|
|
301
|
+
this.s.value[i] = moment()(this.s.value[i], this.s.dateFormat).format('YYYY-MM-DD HH:mm:ss');
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else if (this.s.type.includes('luxon')) {
|
|
306
|
+
for (var i = 0; i < this.s.value.length; i++) {
|
|
307
|
+
if (this.s.value[i] &&
|
|
308
|
+
this.s.value[i].length > 0 &&
|
|
309
|
+
luxon().DateTime.fromFormat(this.s.value[i], this.s.dateFormat).invalid === null) {
|
|
310
|
+
this.s.value[i] = luxon().DateTime.fromFormat(this.s.value[i], this.s.dateFormat).toFormat('yyyy-MM-dd HH:mm:ss');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (this.s.type.includes('num') && this.s.dt.page.info().serverSide) {
|
|
316
|
+
for (var i = 0; i < this.s.value.length; i++) {
|
|
317
|
+
this.s.value[i] = this.s.value[i].replace(/[^0-9.\-]/g, '');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
condition: this.s.condition,
|
|
322
|
+
data: this.s.data,
|
|
323
|
+
origData: this.s.origData,
|
|
324
|
+
type: this.s.type,
|
|
325
|
+
value: this.s.value.map(function (a) { return a !== null && a !== undefined ? a.toString() : a; })
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Getter for the node for the container of the criteria
|
|
330
|
+
*
|
|
331
|
+
* @returns JQuery<HTMLElement> the node for the container
|
|
332
|
+
*/
|
|
333
|
+
Criteria.prototype.getNode = function () {
|
|
334
|
+
return this.dom.container;
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* Populates the criteria data, condition and value(s) as far as has been selected
|
|
338
|
+
*/
|
|
339
|
+
Criteria.prototype.populate = function () {
|
|
340
|
+
this._populateData();
|
|
341
|
+
// If the column index has been found attempt to select a condition
|
|
342
|
+
if (this.s.dataIdx !== -1) {
|
|
343
|
+
this._populateCondition();
|
|
344
|
+
// If the condittion has been found attempt to select the values
|
|
345
|
+
if (this.s.condition !== undefined) {
|
|
346
|
+
this._populateValue();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Rebuilds the criteria based upon the details passed in
|
|
352
|
+
*
|
|
353
|
+
* @param loadedCriteria the details required to rebuild the criteria
|
|
354
|
+
*/
|
|
355
|
+
Criteria.prototype.rebuild = function (loadedCriteria) {
|
|
356
|
+
// Check to see if the previously selected data exists, if so select it
|
|
357
|
+
var foundData = false;
|
|
358
|
+
var dataIdx;
|
|
359
|
+
this._populateData();
|
|
360
|
+
// If a data selection has previously been made attempt to find and select it
|
|
361
|
+
if (loadedCriteria.data !== undefined) {
|
|
362
|
+
var italic_1 = this.classes.italic;
|
|
363
|
+
var data_1 = this.dom.data;
|
|
364
|
+
this.dom.data.children('option').each(function () {
|
|
365
|
+
if (!foundData &&
|
|
366
|
+
($$3(this).text() === loadedCriteria.data ||
|
|
367
|
+
loadedCriteria.origData && $$3(this).prop('origData') === loadedCriteria.origData)) {
|
|
368
|
+
$$3(this).prop('selected', true);
|
|
369
|
+
data_1.removeClass(italic_1);
|
|
370
|
+
foundData = true;
|
|
371
|
+
dataIdx = $$3(this).val();
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
$$3(this).removeProp('selected');
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
// If the data has been found and selected then the condition can be populated and searched
|
|
379
|
+
if (foundData) {
|
|
380
|
+
this.s.data = loadedCriteria.data;
|
|
381
|
+
this.s.origData = loadedCriteria.origData;
|
|
382
|
+
this.s.dataIdx = dataIdx;
|
|
383
|
+
this.c.orthogonal = this._getOptions().orthogonal;
|
|
384
|
+
this.dom.dataTitle.remove();
|
|
385
|
+
this._populateCondition();
|
|
386
|
+
this.dom.conditionTitle.remove();
|
|
387
|
+
var condition = void 0;
|
|
388
|
+
// Check to see if the previously selected condition exists, if so select it
|
|
389
|
+
var options = this.dom.condition.children('option');
|
|
390
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
391
|
+
for (var i = 0; i < options.length; i++) {
|
|
392
|
+
var option = $$3(options[i]);
|
|
393
|
+
if (loadedCriteria.condition !== undefined &&
|
|
394
|
+
option.val() === loadedCriteria.condition &&
|
|
395
|
+
typeof loadedCriteria.condition === 'string') {
|
|
396
|
+
option.prop('selected', true);
|
|
397
|
+
condition = option.val();
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
option.removeProp('selected');
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
this.s.condition = condition;
|
|
404
|
+
// If the condition has been found and selected then the value can be populated and searched
|
|
405
|
+
if (this.s.condition !== undefined) {
|
|
406
|
+
this.dom.conditionTitle.removeProp('selected');
|
|
407
|
+
this.dom.conditionTitle.remove();
|
|
408
|
+
this.dom.condition.removeClass(this.classes.italic);
|
|
409
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
410
|
+
for (var i = 0; i < options.length; i++) {
|
|
411
|
+
var option = $$3(options[i]);
|
|
412
|
+
if (option.val() !== this.s.condition) {
|
|
413
|
+
option.removeProp('selected');
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
this._populateValue(loadedCriteria);
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
this.dom.conditionTitle.prependTo(this.dom.condition).prop('selected', true);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
/**
|
|
424
|
+
* Sets the listeners for the criteria
|
|
425
|
+
*/
|
|
426
|
+
Criteria.prototype.setListeners = function () {
|
|
427
|
+
var _this = this;
|
|
428
|
+
this.dom.data
|
|
429
|
+
.unbind('change')
|
|
430
|
+
.on('change.dtsb', function () {
|
|
431
|
+
_this.dom.dataTitle.removeProp('selected');
|
|
432
|
+
// Need to go over every option to identify the correct selection
|
|
433
|
+
var options = _this.dom.data.children('option.' + _this.classes.option);
|
|
434
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
435
|
+
for (var i = 0; i < options.length; i++) {
|
|
436
|
+
var option = $$3(options[i]);
|
|
437
|
+
if (option.val() === _this.dom.data.val()) {
|
|
438
|
+
_this.dom.data.removeClass(_this.classes.italic);
|
|
439
|
+
option.prop('selected', true);
|
|
440
|
+
_this.s.dataIdx = +option.val();
|
|
441
|
+
_this.s.data = option.text();
|
|
442
|
+
_this.s.origData = option.prop('origData');
|
|
443
|
+
_this.c.orthogonal = _this._getOptions().orthogonal;
|
|
444
|
+
// When the data is changed, the values in condition and
|
|
445
|
+
// value may also change so need to renew them
|
|
446
|
+
_this._clearCondition();
|
|
447
|
+
_this._clearValue();
|
|
448
|
+
_this._populateCondition();
|
|
449
|
+
// If this criteria was previously active in the search then
|
|
450
|
+
// remove it from the search and trigger a new search
|
|
451
|
+
if (_this.s.filled) {
|
|
452
|
+
_this.s.filled = false;
|
|
453
|
+
_this.s.dt.draw();
|
|
454
|
+
_this.setListeners();
|
|
455
|
+
}
|
|
456
|
+
_this.s.dt.state.save();
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
option.removeProp('selected');
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
this.dom.condition
|
|
464
|
+
.unbind('change')
|
|
465
|
+
.on('change.dtsb', function () {
|
|
466
|
+
_this.dom.conditionTitle.removeProp('selected');
|
|
467
|
+
// Need to go over every option to identify the correct selection
|
|
468
|
+
var options = _this.dom.condition.children('option.' + _this.classes.option);
|
|
469
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
470
|
+
for (var i = 0; i < options.length; i++) {
|
|
471
|
+
var option = $$3(options[i]);
|
|
472
|
+
if (option.val() === _this.dom.condition.val()) {
|
|
473
|
+
_this.dom.condition.removeClass(_this.classes.italic);
|
|
474
|
+
option.prop('selected', true);
|
|
475
|
+
var condDisp = option.val();
|
|
476
|
+
// Find the condition that has been selected and store it internally
|
|
477
|
+
for (var _i = 0, _a = Object.keys(_this.s.conditions); _i < _a.length; _i++) {
|
|
478
|
+
var cond = _a[_i];
|
|
479
|
+
if (cond === condDisp) {
|
|
480
|
+
_this.s.condition = condDisp;
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// When the condition is changed, the value selector may switch between
|
|
485
|
+
// a select element and an input element
|
|
486
|
+
_this._clearValue();
|
|
487
|
+
_this._populateValue();
|
|
488
|
+
for (var _b = 0, _c = _this.dom.value; _b < _c.length; _b++) {
|
|
489
|
+
var val = _c[_b];
|
|
490
|
+
// If this criteria was previously active in the search then remove
|
|
491
|
+
// it from the search and trigger a new search
|
|
492
|
+
if (_this.s.filled && val !== undefined && _this.dom.inputCont.has(val[0]).length !== 0) {
|
|
493
|
+
_this.s.filled = false;
|
|
494
|
+
_this.s.dt.draw();
|
|
495
|
+
_this.setListeners();
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
if (_this.dom.value.length === 0 ||
|
|
499
|
+
_this.dom.value.length === 1 && _this.dom.value[0] === undefined) {
|
|
500
|
+
_this.s.dt.draw();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
option.removeProp('selected');
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
};
|
|
509
|
+
Criteria.prototype.setupButtons = function () {
|
|
510
|
+
if (window.innerWidth > 550) {
|
|
511
|
+
this.dom.container.removeClass(this.classes.vertical);
|
|
512
|
+
this.dom.buttons.css('left', null);
|
|
513
|
+
this.dom.buttons.css('top', null);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
this.dom.container.addClass(this.classes.vertical);
|
|
517
|
+
this.dom.buttons.css('left', this.dom.data.innerWidth());
|
|
518
|
+
this.dom.buttons.css('top', this.dom.data.position().top);
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Builds the elements of the dom together
|
|
522
|
+
*/
|
|
523
|
+
Criteria.prototype._buildCriteria = function () {
|
|
524
|
+
// Append Titles for select elements
|
|
525
|
+
this.dom.data.append(this.dom.dataTitle);
|
|
526
|
+
this.dom.condition.append(this.dom.conditionTitle);
|
|
527
|
+
// Add elements to container
|
|
528
|
+
this.dom.container
|
|
529
|
+
.append(this.dom.data)
|
|
530
|
+
.append(this.dom.condition);
|
|
531
|
+
this.dom.inputCont.empty();
|
|
532
|
+
for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
|
|
533
|
+
var val = _a[_i];
|
|
534
|
+
val.append(this.dom.valueTitle);
|
|
535
|
+
this.dom.inputCont.append(val);
|
|
536
|
+
}
|
|
537
|
+
// Add buttons to container
|
|
538
|
+
this.dom.buttons
|
|
539
|
+
.append(this.dom["delete"])
|
|
540
|
+
.append(this.dom.right);
|
|
541
|
+
this.dom.container.append(this.dom.inputCont).append(this.dom.buttons);
|
|
542
|
+
this.setListeners();
|
|
543
|
+
};
|
|
544
|
+
/**
|
|
545
|
+
* Clears the condition select element
|
|
546
|
+
*/
|
|
547
|
+
Criteria.prototype._clearCondition = function () {
|
|
548
|
+
this.dom.condition.empty();
|
|
549
|
+
this.dom.conditionTitle.prop('selected', true).attr('disabled', 'true');
|
|
550
|
+
this.dom.condition.prepend(this.dom.conditionTitle).prop('selectedIndex', 0);
|
|
551
|
+
this.s.conditions = {};
|
|
552
|
+
this.s.condition = undefined;
|
|
553
|
+
};
|
|
554
|
+
/**
|
|
555
|
+
* Clears the value elements
|
|
556
|
+
*/
|
|
557
|
+
Criteria.prototype._clearValue = function () {
|
|
558
|
+
if (this.s.condition !== undefined) {
|
|
559
|
+
if (this.dom.value.length > 0 && this.dom.value[0] !== undefined) {
|
|
560
|
+
var _loop_1 = function (val) {
|
|
561
|
+
if (val !== undefined) {
|
|
562
|
+
// Timeout is annoying but because of IOS
|
|
563
|
+
setTimeout(function () {
|
|
564
|
+
val.remove();
|
|
565
|
+
}, 50);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
// Remove all of the value elements
|
|
569
|
+
for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
|
|
570
|
+
var val = _a[_i];
|
|
571
|
+
_loop_1(val);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
// Call the init function to get the value elements for this condition
|
|
575
|
+
this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener));
|
|
576
|
+
if (this.dom.value.length > 0 && this.dom.value[0] !== undefined) {
|
|
577
|
+
this.dom.inputCont
|
|
578
|
+
.empty()
|
|
579
|
+
.append(this.dom.value[0])
|
|
580
|
+
.insertAfter(this.dom.condition);
|
|
581
|
+
this.dom.value[0].trigger('dtsb-inserted');
|
|
582
|
+
// Insert all of the value elements
|
|
583
|
+
for (var i = 1; i < this.dom.value.length; i++) {
|
|
584
|
+
this.dom.inputCont.append(this.dom.value[i]);
|
|
585
|
+
this.dom.value[i].trigger('dtsb-inserted');
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
var _loop_2 = function (val) {
|
|
591
|
+
if (val !== undefined) {
|
|
592
|
+
// Timeout is annoying but because of IOS
|
|
593
|
+
setTimeout(function () {
|
|
594
|
+
val.remove();
|
|
595
|
+
}, 50);
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
// Remove all of the value elements
|
|
599
|
+
for (var _b = 0, _c = this.dom.value; _b < _c.length; _b++) {
|
|
600
|
+
var val = _c[_b];
|
|
601
|
+
_loop_2(val);
|
|
602
|
+
}
|
|
603
|
+
// Append the default valueTitle to the default select element
|
|
604
|
+
this.dom.valueTitle
|
|
605
|
+
.prop('selected', true);
|
|
606
|
+
this.dom.defaultValue
|
|
607
|
+
.append(this.dom.valueTitle)
|
|
608
|
+
.insertAfter(this.dom.condition);
|
|
609
|
+
}
|
|
610
|
+
this.s.value = [];
|
|
611
|
+
this.dom.value = [
|
|
612
|
+
$$3('<select disabled/>')
|
|
613
|
+
.addClass(this.classes.value)
|
|
614
|
+
.addClass(this.classes.dropDown)
|
|
615
|
+
.addClass(this.classes.italic)
|
|
616
|
+
.addClass(this.classes.select)
|
|
617
|
+
.append(this.dom.valueTitle.clone())
|
|
618
|
+
];
|
|
619
|
+
};
|
|
620
|
+
/**
|
|
621
|
+
* Gets the options for the column
|
|
622
|
+
*
|
|
623
|
+
* @returns {object} The options for the column
|
|
624
|
+
*/
|
|
625
|
+
Criteria.prototype._getOptions = function () {
|
|
626
|
+
var table = this.s.dt;
|
|
627
|
+
return $$3.extend(true, {}, Criteria.defaults, table.settings()[0].aoColumns[this.s.dataIdx].searchBuilder);
|
|
628
|
+
};
|
|
629
|
+
/**
|
|
630
|
+
* Populates the condition dropdown
|
|
631
|
+
*/
|
|
632
|
+
Criteria.prototype._populateCondition = function () {
|
|
633
|
+
var conditionOpts = [];
|
|
634
|
+
var conditionsLength = Object.keys(this.s.conditions).length;
|
|
635
|
+
var colInits = this.s.dt.settings()[0].aoColumns;
|
|
636
|
+
var column = +this.dom.data.children('option:selected').val();
|
|
637
|
+
// If there are no conditions stored then we need to get them from the appropriate type
|
|
638
|
+
if (conditionsLength === 0) {
|
|
639
|
+
this.s.type = this.s.dt.columns().type().toArray()[column];
|
|
640
|
+
if (colInits !== undefined) {
|
|
641
|
+
var colInit = colInits[column];
|
|
642
|
+
if (colInit.searchBuilderType !== undefined && colInit.searchBuilderType !== null) {
|
|
643
|
+
this.s.type = colInit.searchBuilderType;
|
|
644
|
+
}
|
|
645
|
+
else if (this.s.type === undefined || this.s.type === null) {
|
|
646
|
+
this.s.type = colInit.sType;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
// If the column type is still unknown, call a draw to try reading it again
|
|
650
|
+
if (this.s.type === null || this.s.type === undefined) {
|
|
651
|
+
$$3.fn.dataTable.ext.oApi._fnColumnTypes(this.s.dt.settings()[0]);
|
|
652
|
+
this.s.type = this.s.dt.columns().type().toArray()[column];
|
|
653
|
+
}
|
|
654
|
+
// Enable the condition element
|
|
655
|
+
this.dom.condition
|
|
656
|
+
.removeAttr('disabled')
|
|
657
|
+
.empty()
|
|
658
|
+
.append(this.dom.conditionTitle)
|
|
659
|
+
.addClass(this.classes.italic);
|
|
660
|
+
this.dom.conditionTitle
|
|
661
|
+
.prop('selected', true);
|
|
662
|
+
var decimal = this.s.dt.settings()[0].oLanguage.sDecimal;
|
|
663
|
+
// This check is in place for if a custom decimal character is in place
|
|
664
|
+
if (decimal !== '' && this.s.type.indexOf(decimal) === this.s.type.length - decimal.length) {
|
|
665
|
+
if (this.s.type.includes('num-fmt')) {
|
|
666
|
+
this.s.type = this.s.type.replace(decimal, '');
|
|
667
|
+
}
|
|
668
|
+
else if (this.s.type.includes('num')) {
|
|
669
|
+
this.s.type = this.s.type.replace(decimal, '');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
// Select which conditions are going to be used based on the column type
|
|
673
|
+
var conditionObj = this.c.conditions[this.s.type] !== undefined ?
|
|
674
|
+
this.c.conditions[this.s.type] :
|
|
675
|
+
this.s.type.includes('moment') ?
|
|
676
|
+
this.c.conditions.moment :
|
|
677
|
+
this.s.type.includes('luxon') ?
|
|
678
|
+
this.c.conditions.luxon :
|
|
679
|
+
this.c.conditions.string;
|
|
680
|
+
// If it is a moment format then extract the date format
|
|
681
|
+
if (this.s.type.includes('moment')) {
|
|
682
|
+
this.s.dateFormat = this.s.type.replace(/moment-/g, '');
|
|
683
|
+
}
|
|
684
|
+
else if (this.s.type.includes('luxon')) {
|
|
685
|
+
this.s.dateFormat = this.s.type.replace(/luxon-/g, '');
|
|
686
|
+
}
|
|
687
|
+
// Add all of the conditions to the select element
|
|
688
|
+
for (var _i = 0, _a = Object.keys(conditionObj); _i < _a.length; _i++) {
|
|
689
|
+
var condition = _a[_i];
|
|
690
|
+
if (conditionObj[condition] !== null) {
|
|
691
|
+
// Serverside processing does not supply the options for the select elements
|
|
692
|
+
// Instead input elements need to be used for these instead
|
|
693
|
+
if (this.s.dt.page.info().serverSide && conditionObj[condition].init === Criteria.initSelect) {
|
|
694
|
+
var col = colInits[column];
|
|
695
|
+
if (this.s.serverData && this.s.serverData[col.data]) {
|
|
696
|
+
conditionObj[condition].init = Criteria.initSelectSSP;
|
|
697
|
+
conditionObj[condition].inputValue = Criteria.inputValueSelect;
|
|
698
|
+
conditionObj[condition].isInputValid = Criteria.isInputValidSelect;
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
conditionObj[condition].init = Criteria.initInput;
|
|
702
|
+
conditionObj[condition].inputValue = Criteria.inputValueInput;
|
|
703
|
+
conditionObj[condition].isInputValid = Criteria.isInputValidInput;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
this.s.conditions[condition] = conditionObj[condition];
|
|
707
|
+
var condName = conditionObj[condition].conditionName;
|
|
708
|
+
if (typeof condName === 'function') {
|
|
709
|
+
condName = condName(this.s.dt, this.c.i18n);
|
|
710
|
+
}
|
|
711
|
+
conditionOpts.push($$3('<option>', {
|
|
712
|
+
text: condName,
|
|
713
|
+
value: condition
|
|
714
|
+
})
|
|
715
|
+
.addClass(this.classes.option)
|
|
716
|
+
.addClass(this.classes.notItalic));
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
// Otherwise we can just load them in
|
|
721
|
+
else if (conditionsLength > 0) {
|
|
722
|
+
this.dom.condition.empty().removeAttr('disabled').addClass(this.classes.italic);
|
|
723
|
+
for (var _b = 0, _c = Object.keys(this.s.conditions); _b < _c.length; _b++) {
|
|
724
|
+
var condition = _c[_b];
|
|
725
|
+
var condName = this.s.conditions[condition].conditionName;
|
|
726
|
+
if (typeof condName === 'function') {
|
|
727
|
+
condName = condName(this.s.dt, this.c.i18n);
|
|
728
|
+
}
|
|
729
|
+
var newOpt = $$3('<option>', {
|
|
730
|
+
text: condName,
|
|
731
|
+
value: condition
|
|
732
|
+
})
|
|
733
|
+
.addClass(this.classes.option)
|
|
734
|
+
.addClass(this.classes.notItalic);
|
|
735
|
+
if (this.s.condition !== undefined && this.s.condition === condName) {
|
|
736
|
+
newOpt.prop('selected', true);
|
|
737
|
+
this.dom.condition.removeClass(this.classes.italic);
|
|
738
|
+
}
|
|
739
|
+
conditionOpts.push(newOpt);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
else {
|
|
743
|
+
this.dom.condition
|
|
744
|
+
.attr('disabled', 'true')
|
|
745
|
+
.addClass(this.classes.italic);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
for (var _d = 0, conditionOpts_1 = conditionOpts; _d < conditionOpts_1.length; _d++) {
|
|
749
|
+
var opt = conditionOpts_1[_d];
|
|
750
|
+
this.dom.condition.append(opt);
|
|
751
|
+
}
|
|
752
|
+
// Selecting a default condition if one is set
|
|
753
|
+
if (colInits[column].searchBuilder && colInits[column].searchBuilder.defaultCondition) {
|
|
754
|
+
var defaultCondition = colInits[column].searchBuilder.defaultCondition;
|
|
755
|
+
// If it is a number just use it as an index
|
|
756
|
+
if (typeof defaultCondition === 'number') {
|
|
757
|
+
this.dom.condition.prop('selectedIndex', defaultCondition);
|
|
758
|
+
this.dom.condition.trigger('change');
|
|
759
|
+
}
|
|
760
|
+
// If it is a string then things get slightly more tricly
|
|
761
|
+
else if (typeof defaultCondition === 'string') {
|
|
762
|
+
// We need to check each condition option to see if any will match
|
|
763
|
+
for (var i = 0; i < conditionOpts.length; i++) {
|
|
764
|
+
// Need to check against the stored conditions so we can match the token "cond" to the option
|
|
765
|
+
for (var _e = 0, _f = Object.keys(this.s.conditions); _e < _f.length; _e++) {
|
|
766
|
+
var cond = _f[_e];
|
|
767
|
+
var condName = this.s.conditions[cond].conditionName;
|
|
768
|
+
if (
|
|
769
|
+
// If the conditionName matches the text of the option
|
|
770
|
+
(typeof condName === 'string' ? condName : condName(this.s.dt, this.c.i18n)) ===
|
|
771
|
+
conditionOpts[i].text() &&
|
|
772
|
+
// and the tokens match
|
|
773
|
+
cond === defaultCondition) {
|
|
774
|
+
// Select that option
|
|
775
|
+
this.dom.condition
|
|
776
|
+
.prop('selectedIndex', this.dom.condition.children().toArray().indexOf(conditionOpts[i][0]))
|
|
777
|
+
.removeClass(this.classes.italic);
|
|
778
|
+
this.dom.condition.trigger('change');
|
|
779
|
+
i = conditionOpts.length;
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
// If not default set then default to 0, the title
|
|
787
|
+
else {
|
|
788
|
+
this.dom.condition.prop('selectedIndex', 0);
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
/**
|
|
792
|
+
* Populates the data / column select element
|
|
793
|
+
*/
|
|
794
|
+
Criteria.prototype._populateData = function () {
|
|
795
|
+
var columns = this.s.dt.settings()[0].aoColumns;
|
|
796
|
+
var includeColumns = this.s.dt.columns(this.c.columns).indexes().toArray();
|
|
797
|
+
this.dom.data.empty().append(this.dom.dataTitle);
|
|
798
|
+
for (var index = 0; index < columns.length; index++) {
|
|
799
|
+
// Need to check that the column can be filtered on before adding it
|
|
800
|
+
if (this.c.columns === true || includeColumns.includes(index)) {
|
|
801
|
+
var col = columns[index];
|
|
802
|
+
var opt = {
|
|
803
|
+
index: index,
|
|
804
|
+
origData: col.data,
|
|
805
|
+
text: (col.searchBuilderTitle || col.sTitle)
|
|
806
|
+
.replace(/(<([^>]+)>)/ig, '')
|
|
807
|
+
};
|
|
808
|
+
this.dom.data.append($$3('<option>', {
|
|
809
|
+
text: opt.text,
|
|
810
|
+
value: opt.index
|
|
811
|
+
})
|
|
812
|
+
.addClass(this.classes.option)
|
|
813
|
+
.addClass(this.classes.notItalic)
|
|
814
|
+
.prop('origData', col.data)
|
|
815
|
+
.prop('selected', this.s.dataIdx === opt.index ? true : false));
|
|
816
|
+
if (this.s.dataIdx === opt.index) {
|
|
817
|
+
this.dom.dataTitle.removeProp('selected');
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
/**
|
|
823
|
+
* Populates the Value select element
|
|
824
|
+
*
|
|
825
|
+
* @param loadedCriteria optional, used to reload criteria from predefined filters
|
|
826
|
+
*/
|
|
827
|
+
Criteria.prototype._populateValue = function (loadedCriteria) {
|
|
828
|
+
var _this = this;
|
|
829
|
+
var prevFilled = this.s.filled;
|
|
830
|
+
this.s.filled = false;
|
|
831
|
+
// Remove any previous value elements
|
|
832
|
+
// Timeout is annoying but because of IOS
|
|
833
|
+
setTimeout(function () {
|
|
834
|
+
_this.dom.defaultValue.remove();
|
|
835
|
+
}, 50);
|
|
836
|
+
var _loop_3 = function (val) {
|
|
837
|
+
// Timeout is annoying but because of IOS
|
|
838
|
+
setTimeout(function () {
|
|
839
|
+
if (val !== undefined) {
|
|
840
|
+
val.remove();
|
|
841
|
+
}
|
|
842
|
+
}, 50);
|
|
843
|
+
};
|
|
844
|
+
for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
|
|
845
|
+
var val = _a[_i];
|
|
846
|
+
_loop_3(val);
|
|
847
|
+
}
|
|
848
|
+
var children = this.dom.inputCont.children();
|
|
849
|
+
if (children.length > 1) {
|
|
850
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
851
|
+
for (var i = 0; i < children.length; i++) {
|
|
852
|
+
$$3(children[i]).remove();
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
// Find the column with the title matching the data for the criteria and take note of the index
|
|
856
|
+
if (loadedCriteria !== undefined) {
|
|
857
|
+
this.s.dt.columns().every(function (index) {
|
|
858
|
+
if (_this.s.dt.settings()[0].aoColumns[index].sTitle === loadedCriteria.data) {
|
|
859
|
+
_this.s.dataIdx = index;
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
// Initialise the value elements based on the condition
|
|
864
|
+
this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener, loadedCriteria !== undefined ? loadedCriteria.value : undefined));
|
|
865
|
+
if (loadedCriteria !== undefined && loadedCriteria.value !== undefined) {
|
|
866
|
+
this.s.value = loadedCriteria.value;
|
|
867
|
+
}
|
|
868
|
+
this.dom.inputCont.empty();
|
|
869
|
+
// Insert value elements and trigger the inserted event
|
|
870
|
+
if (this.dom.value[0] !== undefined) {
|
|
871
|
+
this.dom.value[0]
|
|
872
|
+
.appendTo(this.dom.inputCont)
|
|
873
|
+
.trigger('dtsb-inserted');
|
|
874
|
+
}
|
|
875
|
+
for (var i = 1; i < this.dom.value.length; i++) {
|
|
876
|
+
this.dom.value[i]
|
|
877
|
+
.insertAfter(this.dom.value[i - 1])
|
|
878
|
+
.trigger('dtsb-inserted');
|
|
879
|
+
}
|
|
880
|
+
// Check if the criteria can be used in a search
|
|
881
|
+
this.s.filled = this.s.conditions[this.s.condition].isInputValid(this.dom.value, this);
|
|
882
|
+
this.setListeners();
|
|
883
|
+
// If it can and this is different to before then trigger a draw
|
|
884
|
+
if (!this.s.preventRedraw && prevFilled !== this.s.filled) {
|
|
885
|
+
// If using SSP we want to restrict the amount of server calls that take place
|
|
886
|
+
// and this will already have taken place
|
|
887
|
+
if (!this.s.dt.page.info().serverSide) {
|
|
888
|
+
this.s.dt.draw();
|
|
889
|
+
}
|
|
890
|
+
this.setListeners();
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
/**
|
|
894
|
+
* Provides throttling capabilities to SearchBuilder without having to use dt's _fnThrottle function
|
|
895
|
+
* This is because that function is not quite suitable for our needs as it runs initially rather than waiting
|
|
896
|
+
*
|
|
897
|
+
* @param args arguments supplied to the throttle function
|
|
898
|
+
* @returns Function that is to be run that implements the throttling
|
|
899
|
+
*/
|
|
900
|
+
Criteria.prototype._throttle = function (fn, frequency) {
|
|
901
|
+
if (frequency === void 0) { frequency = 200; }
|
|
902
|
+
var last = null;
|
|
903
|
+
var timer = null;
|
|
904
|
+
var that = this;
|
|
905
|
+
if (frequency === null) {
|
|
906
|
+
frequency = 200;
|
|
907
|
+
}
|
|
908
|
+
return function () {
|
|
909
|
+
var args = [];
|
|
910
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
911
|
+
args[_i] = arguments[_i];
|
|
912
|
+
}
|
|
913
|
+
var now = +new Date();
|
|
914
|
+
if (last !== null && now < last + frequency) {
|
|
915
|
+
clearTimeout(timer);
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
last = now;
|
|
919
|
+
}
|
|
920
|
+
timer = setTimeout(function () {
|
|
921
|
+
last = null;
|
|
922
|
+
fn.apply(that, args);
|
|
923
|
+
}, frequency);
|
|
924
|
+
};
|
|
925
|
+
};
|
|
926
|
+
Criteria.version = '1.1.0';
|
|
927
|
+
Criteria.classes = {
|
|
928
|
+
button: 'dtsb-button',
|
|
929
|
+
buttonContainer: 'dtsb-buttonContainer',
|
|
930
|
+
condition: 'dtsb-condition',
|
|
931
|
+
container: 'dtsb-criteria',
|
|
932
|
+
data: 'dtsb-data',
|
|
933
|
+
"delete": 'dtsb-delete',
|
|
934
|
+
dropDown: 'dtsb-dropDown',
|
|
935
|
+
greyscale: 'dtsb-greyscale',
|
|
936
|
+
input: 'dtsb-input',
|
|
937
|
+
inputCont: 'dtsb-inputCont',
|
|
938
|
+
italic: 'dtsb-italic',
|
|
939
|
+
joiner: 'dtsp-joiner',
|
|
940
|
+
left: 'dtsb-left',
|
|
941
|
+
notItalic: 'dtsb-notItalic',
|
|
942
|
+
option: 'dtsb-option',
|
|
943
|
+
right: 'dtsb-right',
|
|
944
|
+
select: 'dtsb-select',
|
|
945
|
+
value: 'dtsb-value',
|
|
946
|
+
vertical: 'dtsb-vertical'
|
|
947
|
+
};
|
|
948
|
+
/**
|
|
949
|
+
* Default initialisation function for select conditions
|
|
950
|
+
*/
|
|
951
|
+
Criteria.initSelect = function (that, fn, preDefined, array) {
|
|
952
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
953
|
+
if (array === void 0) { array = false; }
|
|
954
|
+
var column = that.dom.data.children('option:selected').val();
|
|
955
|
+
var indexArray = that.s.dt.rows().indexes().toArray();
|
|
956
|
+
var settings = that.s.dt.settings()[0];
|
|
957
|
+
that.dom.valueTitle.prop('selected', true);
|
|
958
|
+
// Declare select element to be used with all of the default classes and listeners.
|
|
959
|
+
var el = $$3('<select/>')
|
|
960
|
+
.addClass(Criteria.classes.value)
|
|
961
|
+
.addClass(Criteria.classes.dropDown)
|
|
962
|
+
.addClass(Criteria.classes.italic)
|
|
963
|
+
.addClass(Criteria.classes.select)
|
|
964
|
+
.append(that.dom.valueTitle)
|
|
965
|
+
.on('change.dtsb', function () {
|
|
966
|
+
$$3(this).removeClass(Criteria.classes.italic);
|
|
967
|
+
fn(that, this);
|
|
968
|
+
});
|
|
969
|
+
if (that.c.greyscale) {
|
|
970
|
+
el.addClass(Criteria.classes.greyscale);
|
|
971
|
+
}
|
|
972
|
+
var added = [];
|
|
973
|
+
var options = [];
|
|
974
|
+
// Add all of the options from the table to the select element.
|
|
975
|
+
// Only add one option for each possible value
|
|
976
|
+
for (var _i = 0, indexArray_1 = indexArray; _i < indexArray_1.length; _i++) {
|
|
977
|
+
var index = indexArray_1[_i];
|
|
978
|
+
var filter = settings.oApi._fnGetCellData(settings, index, column, typeof that.c.orthogonal === 'string' ?
|
|
979
|
+
that.c.orthogonal :
|
|
980
|
+
that.c.orthogonal.search);
|
|
981
|
+
var value = {
|
|
982
|
+
filter: typeof filter === 'string' ?
|
|
983
|
+
filter.replace(/[\r\n\u2028]/g, ' ') : // Need to replace certain characters to match search values
|
|
984
|
+
filter,
|
|
985
|
+
index: index,
|
|
986
|
+
text: settings.oApi._fnGetCellData(settings, index, column, typeof that.c.orthogonal === 'string' ?
|
|
987
|
+
that.c.orthogonal :
|
|
988
|
+
that.c.orthogonal.display)
|
|
989
|
+
};
|
|
990
|
+
// If we are dealing with an array type, either make sure we are working with arrays, or sort them
|
|
991
|
+
if (that.s.type === 'array') {
|
|
992
|
+
value.filter = !Array.isArray(value.filter) ? [value.filter] : value.filter;
|
|
993
|
+
value.text = !Array.isArray(value.text) ? [value.text] : value.text;
|
|
994
|
+
}
|
|
995
|
+
// Function to add an option to the select element
|
|
996
|
+
var addOption = function (filt, text) {
|
|
997
|
+
if (that.s.type.includes('html') && filt !== null && typeof filt === 'string') {
|
|
998
|
+
filt.replace(/(<([^>]+)>)/ig, '');
|
|
999
|
+
}
|
|
1000
|
+
// Add text and value, stripping out any html if that is the column type
|
|
1001
|
+
var opt = $$3('<option>', {
|
|
1002
|
+
type: Array.isArray(filt) ? 'Array' : 'String',
|
|
1003
|
+
value: filt
|
|
1004
|
+
})
|
|
1005
|
+
.data('sbv', filt)
|
|
1006
|
+
.addClass(that.classes.option)
|
|
1007
|
+
.addClass(that.classes.notItalic)
|
|
1008
|
+
// Have to add the text this way so that special html characters are not escaped - & etc.
|
|
1009
|
+
.html(typeof text === 'string' ?
|
|
1010
|
+
text.replace(/(<([^>]+)>)/ig, '') :
|
|
1011
|
+
text);
|
|
1012
|
+
var val = opt.val();
|
|
1013
|
+
// Check that this value has not already been added
|
|
1014
|
+
if (added.indexOf(val) === -1) {
|
|
1015
|
+
added.push(val);
|
|
1016
|
+
options.push(opt);
|
|
1017
|
+
if (preDefined !== null && Array.isArray(preDefined[0])) {
|
|
1018
|
+
preDefined[0] = preDefined[0].sort().join(',');
|
|
1019
|
+
}
|
|
1020
|
+
// If this value was previously selected as indicated by preDefined, then select it again
|
|
1021
|
+
if (preDefined !== null && opt.val() === preDefined[0]) {
|
|
1022
|
+
opt.prop('selected', true);
|
|
1023
|
+
el.removeClass(Criteria.classes.italic);
|
|
1024
|
+
that.dom.valueTitle.removeProp('selected');
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
// If this is to add the individual values within the array we need to loop over the array
|
|
1029
|
+
if (array) {
|
|
1030
|
+
for (var i = 0; i < value.filter.length; i++) {
|
|
1031
|
+
addOption(value.filter[i], value.text[i]);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
// Otherwise the value that is in the cell is to be added
|
|
1035
|
+
else {
|
|
1036
|
+
addOption(value.filter, Array.isArray(value.text) ? value.text.join(', ') : value.text);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
options.sort(function (a, b) {
|
|
1040
|
+
if (that.s.type === 'array' ||
|
|
1041
|
+
that.s.type === 'string' ||
|
|
1042
|
+
that.s.type === 'html') {
|
|
1043
|
+
if (a.val() < b.val()) {
|
|
1044
|
+
return -1;
|
|
1045
|
+
}
|
|
1046
|
+
else if (a.val() > b.val()) {
|
|
1047
|
+
return 1;
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
return 0;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
else if (that.s.type === 'num' ||
|
|
1054
|
+
that.s.type === 'html-num') {
|
|
1055
|
+
if (+a.val().replace(/(<([^>]+)>)/ig, '') < +b.val().replace(/(<([^>]+)>)/ig, '')) {
|
|
1056
|
+
return -1;
|
|
1057
|
+
}
|
|
1058
|
+
else if (+a.val().replace(/(<([^>]+)>)/ig, '') > +b.val().replace(/(<([^>]+)>)/ig, '')) {
|
|
1059
|
+
return 1;
|
|
1060
|
+
}
|
|
1061
|
+
else {
|
|
1062
|
+
return 0;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
else if (that.s.type === 'num-fmt' || that.s.type === 'html-num-fmt') {
|
|
1066
|
+
if (+a.val().replace(/[^0-9.]/g, '') < +b.val().replace(/[^0-9.]/g, '')) {
|
|
1067
|
+
return -1;
|
|
1068
|
+
}
|
|
1069
|
+
else if (+a.val().replace(/[^0-9.]/g, '') > +b.val().replace(/[^0-9.]/g, '')) {
|
|
1070
|
+
return 1;
|
|
1071
|
+
}
|
|
1072
|
+
else {
|
|
1073
|
+
return 0;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
for (var _a = 0, options_1 = options; _a < options_1.length; _a++) {
|
|
1078
|
+
var opt = options_1[_a];
|
|
1079
|
+
el.append(opt);
|
|
1080
|
+
}
|
|
1081
|
+
return el;
|
|
1082
|
+
};
|
|
1083
|
+
/**
|
|
1084
|
+
* Default initialisation function for select conditions
|
|
1085
|
+
*/
|
|
1086
|
+
Criteria.initSelectSSP = function (that, fn, preDefined) {
|
|
1087
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
1088
|
+
that.dom.valueTitle.prop('selected', true);
|
|
1089
|
+
// Declare select element to be used with all of the default classes and listeners.
|
|
1090
|
+
var el = $$3('<select/>')
|
|
1091
|
+
.addClass(Criteria.classes.value)
|
|
1092
|
+
.addClass(Criteria.classes.dropDown)
|
|
1093
|
+
.addClass(Criteria.classes.italic)
|
|
1094
|
+
.addClass(Criteria.classes.select)
|
|
1095
|
+
.append(that.dom.valueTitle)
|
|
1096
|
+
.on('change.dtsb', function () {
|
|
1097
|
+
$$3(this).removeClass(Criteria.classes.italic);
|
|
1098
|
+
fn(that, this);
|
|
1099
|
+
});
|
|
1100
|
+
if (that.c.greyscale) {
|
|
1101
|
+
el.addClass(Criteria.classes.greyscale);
|
|
1102
|
+
}
|
|
1103
|
+
var options = [];
|
|
1104
|
+
for (var _i = 0, _a = that.s.serverData[that.s.origData]; _i < _a.length; _i++) {
|
|
1105
|
+
var option = _a[_i];
|
|
1106
|
+
var value = option.value;
|
|
1107
|
+
var label = option.label;
|
|
1108
|
+
// Function to add an option to the select element
|
|
1109
|
+
var addOption = function (filt, text) {
|
|
1110
|
+
if (that.s.type.includes('html') && filt !== null && typeof filt === 'string') {
|
|
1111
|
+
filt.replace(/(<([^>]+)>)/ig, '');
|
|
1112
|
+
}
|
|
1113
|
+
// Add text and value, stripping out any html if that is the column type
|
|
1114
|
+
var opt = $$3('<option>', {
|
|
1115
|
+
type: Array.isArray(filt) ? 'Array' : 'String',
|
|
1116
|
+
value: filt
|
|
1117
|
+
})
|
|
1118
|
+
.data('sbv', filt)
|
|
1119
|
+
.addClass(that.classes.option)
|
|
1120
|
+
.addClass(that.classes.notItalic)
|
|
1121
|
+
// Have to add the text this way so that special html characters are not escaped - & etc.
|
|
1122
|
+
.html(typeof text === 'string' ?
|
|
1123
|
+
text.replace(/(<([^>]+)>)/ig, '') :
|
|
1124
|
+
text);
|
|
1125
|
+
options.push(opt);
|
|
1126
|
+
// If this value was previously selected as indicated by preDefined, then select it again
|
|
1127
|
+
if (preDefined !== null && opt.val() === preDefined[0]) {
|
|
1128
|
+
opt.prop('selected', true);
|
|
1129
|
+
el.removeClass(Criteria.classes.italic);
|
|
1130
|
+
that.dom.valueTitle.removeProp('selected');
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
addOption(value, label);
|
|
1134
|
+
}
|
|
1135
|
+
for (var _b = 0, options_2 = options; _b < options_2.length; _b++) {
|
|
1136
|
+
var opt = options_2[_b];
|
|
1137
|
+
el.append(opt);
|
|
1138
|
+
}
|
|
1139
|
+
return el;
|
|
1140
|
+
};
|
|
1141
|
+
/**
|
|
1142
|
+
* Default initialisation function for select array conditions
|
|
1143
|
+
*
|
|
1144
|
+
* This exists because there needs to be different select functionality for contains/without and equals/not
|
|
1145
|
+
*/
|
|
1146
|
+
Criteria.initSelectArray = function (that, fn, preDefined) {
|
|
1147
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
1148
|
+
return Criteria.initSelect(that, fn, preDefined, true);
|
|
1149
|
+
};
|
|
1150
|
+
/**
|
|
1151
|
+
* Default initialisation function for input conditions
|
|
1152
|
+
*/
|
|
1153
|
+
Criteria.initInput = function (that, fn, preDefined) {
|
|
1154
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
1155
|
+
// Declare the input element
|
|
1156
|
+
var searchDelay = that.s.dt.settings()[0].searchDelay;
|
|
1157
|
+
var el = $$3('<input/>')
|
|
1158
|
+
.addClass(Criteria.classes.value)
|
|
1159
|
+
.addClass(Criteria.classes.input)
|
|
1160
|
+
.on('input.dtsb keypress.dtsb', that._throttle(function (e) {
|
|
1161
|
+
var code = e.keyCode || e.which;
|
|
1162
|
+
return fn(that, this, code);
|
|
1163
|
+
}, searchDelay === null ? 100 : searchDelay));
|
|
1164
|
+
if (that.c.greyscale) {
|
|
1165
|
+
el.addClass(Criteria.classes.greyscale);
|
|
1166
|
+
}
|
|
1167
|
+
// If there is a preDefined value then add it
|
|
1168
|
+
if (preDefined !== null) {
|
|
1169
|
+
el.val(preDefined[0]);
|
|
1170
|
+
}
|
|
1171
|
+
// This is add responsive functionality to the logic button without redrawing everything else
|
|
1172
|
+
that.s.dt.one('draw.dtsb', function () {
|
|
1173
|
+
that.s.topGroup.trigger('dtsb-redrawLogic');
|
|
1174
|
+
});
|
|
1175
|
+
return el;
|
|
1176
|
+
};
|
|
1177
|
+
/**
|
|
1178
|
+
* Default initialisation function for conditions requiring 2 inputs
|
|
1179
|
+
*/
|
|
1180
|
+
Criteria.init2Input = function (that, fn, preDefined) {
|
|
1181
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
1182
|
+
// Declare all of the necessary jQuery elements
|
|
1183
|
+
var searchDelay = that.s.dt.settings()[0].searchDelay;
|
|
1184
|
+
var els = [
|
|
1185
|
+
$$3('<input/>')
|
|
1186
|
+
.addClass(Criteria.classes.value)
|
|
1187
|
+
.addClass(Criteria.classes.input)
|
|
1188
|
+
.on('input.dtsb keypress.dtsb', that._throttle(function (e) {
|
|
1189
|
+
var code = e.keyCode || e.which;
|
|
1190
|
+
return fn(that, this, code);
|
|
1191
|
+
}, searchDelay === null ? 100 : searchDelay)),
|
|
1192
|
+
$$3('<span>')
|
|
1193
|
+
.addClass(that.classes.joiner)
|
|
1194
|
+
.html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
|
|
1195
|
+
$$3('<input/>')
|
|
1196
|
+
.addClass(Criteria.classes.value)
|
|
1197
|
+
.addClass(Criteria.classes.input)
|
|
1198
|
+
.on('input.dtsb keypress.dtsb', that._throttle(function (e) {
|
|
1199
|
+
var code = e.keyCode || e.which;
|
|
1200
|
+
return fn(that, this, code);
|
|
1201
|
+
}, searchDelay === null ? 100 : searchDelay))
|
|
1202
|
+
];
|
|
1203
|
+
if (that.c.greyscale) {
|
|
1204
|
+
els[0].addClass(Criteria.classes.greyscale);
|
|
1205
|
+
els[2].addClass(Criteria.classes.greyscale);
|
|
1206
|
+
}
|
|
1207
|
+
// If there is a preDefined value then add it
|
|
1208
|
+
if (preDefined !== null) {
|
|
1209
|
+
els[0].val(preDefined[0]);
|
|
1210
|
+
els[2].val(preDefined[1]);
|
|
1211
|
+
}
|
|
1212
|
+
// This is add responsive functionality to the logic button without redrawing everything else
|
|
1213
|
+
that.s.dt.one('draw.dtsb', function () {
|
|
1214
|
+
that.s.topGroup.trigger('dtsb-redrawLogic');
|
|
1215
|
+
});
|
|
1216
|
+
return els;
|
|
1217
|
+
};
|
|
1218
|
+
/**
|
|
1219
|
+
* Default initialisation function for date conditions
|
|
1220
|
+
*/
|
|
1221
|
+
Criteria.initDate = function (that, fn, preDefined) {
|
|
1222
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
1223
|
+
var searchDelay = that.s.dt.settings()[0].searchDelay;
|
|
1224
|
+
// Declare date element using DataTables dateTime plugin
|
|
1225
|
+
var el = $$3('<input/>')
|
|
1226
|
+
.addClass(Criteria.classes.value)
|
|
1227
|
+
.addClass(Criteria.classes.input)
|
|
1228
|
+
.dtDateTime({
|
|
1229
|
+
attachTo: 'input',
|
|
1230
|
+
format: that.s.dateFormat ? that.s.dateFormat : undefined
|
|
1231
|
+
})
|
|
1232
|
+
.on('change.dtsb', that._throttle(function () {
|
|
1233
|
+
return fn(that, this);
|
|
1234
|
+
}, searchDelay === null ? 100 : searchDelay))
|
|
1235
|
+
.on('input.dtsb keypress.dtsb', function (e) {
|
|
1236
|
+
that._throttle(function () {
|
|
1237
|
+
var code = e.keyCode || e.which;
|
|
1238
|
+
return fn(that, this, code);
|
|
1239
|
+
}, searchDelay === null ? 100 : searchDelay);
|
|
1240
|
+
});
|
|
1241
|
+
if (that.c.greyscale) {
|
|
1242
|
+
el.addClass(Criteria.classes.greyscale);
|
|
1243
|
+
}
|
|
1244
|
+
// If there is a preDefined value then add it
|
|
1245
|
+
if (preDefined !== null) {
|
|
1246
|
+
el.val(preDefined[0]);
|
|
1247
|
+
}
|
|
1248
|
+
// This is add responsive functionality to the logic button without redrawing everything else
|
|
1249
|
+
that.s.dt.one('draw.dtsb', function () {
|
|
1250
|
+
that.s.topGroup.trigger('dtsb-redrawLogic');
|
|
1251
|
+
});
|
|
1252
|
+
return el;
|
|
1253
|
+
};
|
|
1254
|
+
Criteria.initNoValue = function (that) {
|
|
1255
|
+
// This is add responsive functionality to the logic button without redrawing everything else
|
|
1256
|
+
that.s.dt.one('draw.dtsb', function () {
|
|
1257
|
+
that.s.topGroup.trigger('dtsb-redrawLogic');
|
|
1258
|
+
});
|
|
1259
|
+
return [];
|
|
1260
|
+
};
|
|
1261
|
+
Criteria.init2Date = function (that, fn, preDefined) {
|
|
1262
|
+
var _this = this;
|
|
1263
|
+
if (preDefined === void 0) { preDefined = null; }
|
|
1264
|
+
var searchDelay = that.s.dt.settings()[0].searchDelay;
|
|
1265
|
+
// Declare all of the date elements that are required using DataTables dateTime plugin
|
|
1266
|
+
var els = [
|
|
1267
|
+
$$3('<input/>')
|
|
1268
|
+
.addClass(Criteria.classes.value)
|
|
1269
|
+
.addClass(Criteria.classes.input)
|
|
1270
|
+
.dtDateTime({
|
|
1271
|
+
attachTo: 'input',
|
|
1272
|
+
format: that.s.dateFormat ? that.s.dateFormat : undefined
|
|
1273
|
+
})
|
|
1274
|
+
.on('change.dtsb', searchDelay !== null ?
|
|
1275
|
+
that.s.dt.settings()[0].oApi._fnThrottle(function () {
|
|
1276
|
+
return fn(that, this);
|
|
1277
|
+
}, searchDelay) :
|
|
1278
|
+
function () {
|
|
1279
|
+
fn(that, _this);
|
|
1280
|
+
})
|
|
1281
|
+
.on('input.dtsb keypress.dtsb', function (e) {
|
|
1282
|
+
that.s.dt.settings()[0].oApi._fnThrottle(function () {
|
|
1283
|
+
var code = e.keyCode || e.which;
|
|
1284
|
+
return fn(that, this, code);
|
|
1285
|
+
}, searchDelay === null ? 0 : searchDelay);
|
|
1286
|
+
}),
|
|
1287
|
+
$$3('<span>')
|
|
1288
|
+
.addClass(that.classes.joiner)
|
|
1289
|
+
.html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
|
|
1290
|
+
$$3('<input/>')
|
|
1291
|
+
.addClass(Criteria.classes.value)
|
|
1292
|
+
.addClass(Criteria.classes.input)
|
|
1293
|
+
.dtDateTime({
|
|
1294
|
+
attachTo: 'input',
|
|
1295
|
+
format: that.s.dateFormat ? that.s.dateFormat : undefined
|
|
1296
|
+
})
|
|
1297
|
+
.on('change.dtsb', searchDelay !== null ?
|
|
1298
|
+
that.s.dt.settings()[0].oApi._fnThrottle(function () {
|
|
1299
|
+
return fn(that, this);
|
|
1300
|
+
}, searchDelay) :
|
|
1301
|
+
function () {
|
|
1302
|
+
fn(that, _this);
|
|
1303
|
+
})
|
|
1304
|
+
.on('input.dtsb keypress.dtsb', !that.c.enterSearch &&
|
|
1305
|
+
!(that.s.dt.settings()[0].oInit.search !== undefined &&
|
|
1306
|
+
that.s.dt.settings()[0].oInit.search["return"]) &&
|
|
1307
|
+
searchDelay !== null ?
|
|
1308
|
+
that.s.dt.settings()[0].oApi._fnThrottle(function () {
|
|
1309
|
+
return fn(that, this);
|
|
1310
|
+
}, searchDelay) :
|
|
1311
|
+
function (e) {
|
|
1312
|
+
var code = e.keyCode || e.which;
|
|
1313
|
+
fn(that, _this, code);
|
|
1314
|
+
})
|
|
1315
|
+
];
|
|
1316
|
+
if (that.c.greyscale) {
|
|
1317
|
+
els[0].addClass(Criteria.classes.greyscale);
|
|
1318
|
+
els[2].addClass(Criteria.classes.greyscale);
|
|
1319
|
+
}
|
|
1320
|
+
// If there are and preDefined values then add them
|
|
1321
|
+
if (preDefined !== null && preDefined.length > 0) {
|
|
1322
|
+
els[0].val(preDefined[0]);
|
|
1323
|
+
els[2].val(preDefined[1]);
|
|
1324
|
+
}
|
|
1325
|
+
// This is add responsive functionality to the logic button without redrawing everything else
|
|
1326
|
+
that.s.dt.one('draw.dtsb', function () {
|
|
1327
|
+
that.s.topGroup.trigger('dtsb-redrawLogic');
|
|
1328
|
+
});
|
|
1329
|
+
return els;
|
|
1330
|
+
};
|
|
1331
|
+
/**
|
|
1332
|
+
* Default function for select elements to validate condition
|
|
1333
|
+
*/
|
|
1334
|
+
Criteria.isInputValidSelect = function (el) {
|
|
1335
|
+
var allFilled = true;
|
|
1336
|
+
// Check each element to make sure that the selections are valid
|
|
1337
|
+
for (var _i = 0, el_1 = el; _i < el_1.length; _i++) {
|
|
1338
|
+
var element = el_1[_i];
|
|
1339
|
+
if (element.children('option:selected').length ===
|
|
1340
|
+
element.children('option').length -
|
|
1341
|
+
element.children('option.' + Criteria.classes.notItalic).length &&
|
|
1342
|
+
element.children('option:selected').length === 1 &&
|
|
1343
|
+
element.children('option:selected')[0] === element.children('option')[0]) {
|
|
1344
|
+
allFilled = false;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
return allFilled;
|
|
1348
|
+
};
|
|
1349
|
+
/**
|
|
1350
|
+
* Default function for input and date elements to validate condition
|
|
1351
|
+
*/
|
|
1352
|
+
Criteria.isInputValidInput = function (el) {
|
|
1353
|
+
var allFilled = true;
|
|
1354
|
+
// Check each element to make sure that the inputs are valid
|
|
1355
|
+
for (var _i = 0, el_2 = el; _i < el_2.length; _i++) {
|
|
1356
|
+
var element = el_2[_i];
|
|
1357
|
+
if (element.is('input') && element.val().length === 0) {
|
|
1358
|
+
allFilled = false;
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return allFilled;
|
|
1362
|
+
};
|
|
1363
|
+
/**
|
|
1364
|
+
* Default function for getting select conditions
|
|
1365
|
+
*/
|
|
1366
|
+
Criteria.inputValueSelect = function (el) {
|
|
1367
|
+
var values = [];
|
|
1368
|
+
// Go through the select elements and push each selected option to the return array
|
|
1369
|
+
for (var _i = 0, el_3 = el; _i < el_3.length; _i++) {
|
|
1370
|
+
var element = el_3[_i];
|
|
1371
|
+
if (element.is('select')) {
|
|
1372
|
+
values.push(Criteria._escapeHTML(element.children('option:selected').data('sbv')));
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
return values;
|
|
1376
|
+
};
|
|
1377
|
+
/**
|
|
1378
|
+
* Default function for getting input conditions
|
|
1379
|
+
*/
|
|
1380
|
+
Criteria.inputValueInput = function (el) {
|
|
1381
|
+
var values = [];
|
|
1382
|
+
// Go through the input elements and push each value to the return array
|
|
1383
|
+
for (var _i = 0, el_4 = el; _i < el_4.length; _i++) {
|
|
1384
|
+
var element = el_4[_i];
|
|
1385
|
+
if (element.is('input')) {
|
|
1386
|
+
values.push(Criteria._escapeHTML(element.val()));
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
return values;
|
|
1390
|
+
};
|
|
1391
|
+
/**
|
|
1392
|
+
* Function that is run on each element as a call back when a search should be triggered
|
|
1393
|
+
*/
|
|
1394
|
+
Criteria.updateListener = function (that, el, code) {
|
|
1395
|
+
// When the value is changed the criteria is now complete so can be included in searches
|
|
1396
|
+
// Get the condition from the map based on the key that has been selected for the condition
|
|
1397
|
+
var condition = that.s.conditions[that.s.condition];
|
|
1398
|
+
that.s.filled = condition.isInputValid(that.dom.value, that);
|
|
1399
|
+
that.s.value = condition.inputValue(that.dom.value, that);
|
|
1400
|
+
if (!that.s.filled) {
|
|
1401
|
+
if (!that.c.enterSearch &&
|
|
1402
|
+
!(that.s.dt.settings()[0].oInit.search !== undefined &&
|
|
1403
|
+
that.s.dt.settings()[0].oInit.search["return"]) ||
|
|
1404
|
+
code === 13) {
|
|
1405
|
+
that.s.dt.draw();
|
|
1406
|
+
}
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
if (!Array.isArray(that.s.value)) {
|
|
1410
|
+
that.s.value = [that.s.value];
|
|
1411
|
+
}
|
|
1412
|
+
for (var i = 0; i < that.s.value.length; i++) {
|
|
1413
|
+
// If the value is an array we need to sort it
|
|
1414
|
+
if (Array.isArray(that.s.value[i])) {
|
|
1415
|
+
that.s.value[i].sort();
|
|
1416
|
+
}
|
|
1417
|
+
// Otherwise replace the decimal place character for i18n
|
|
1418
|
+
else if (that.s.type.includes('num') &&
|
|
1419
|
+
(that.s.dt.settings()[0].oLanguage.sDecimal !== '' ||
|
|
1420
|
+
that.s.dt.settings()[0].oLanguage.sThousands !== '')) {
|
|
1421
|
+
var splitRD = [that.s.value[i].toString()];
|
|
1422
|
+
if (that.s.dt.settings()[0].oLanguage.sDecimal !== '') {
|
|
1423
|
+
splitRD = that.s.value[i].split(that.s.dt.settings()[0].oLanguage.sDecimal);
|
|
1424
|
+
}
|
|
1425
|
+
if (that.s.dt.settings()[0].oLanguage.sThousands !== '') {
|
|
1426
|
+
for (var j = 0; j < splitRD.length; j++) {
|
|
1427
|
+
splitRD[j] = splitRD[j].replace(that.s.dt.settings()[0].oLanguage.sThousands, ',');
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
that.s.value[i] = splitRD.join('.');
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
// Take note of the cursor position so that we can refocus there later
|
|
1434
|
+
var idx = null;
|
|
1435
|
+
var cursorPos = null;
|
|
1436
|
+
for (var i = 0; i < that.dom.value.length; i++) {
|
|
1437
|
+
if (el === that.dom.value[i][0]) {
|
|
1438
|
+
idx = i;
|
|
1439
|
+
if (el.selectionStart !== undefined) {
|
|
1440
|
+
cursorPos = el.selectionStart;
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
if (!that.c.enterSearch &&
|
|
1445
|
+
!(that.s.dt.settings()[0].oInit.search !== undefined &&
|
|
1446
|
+
that.s.dt.settings()[0].oInit.search["return"]) ||
|
|
1447
|
+
code === 13) {
|
|
1448
|
+
// Trigger a search
|
|
1449
|
+
that.s.dt.draw();
|
|
1450
|
+
}
|
|
1451
|
+
// Refocus the element and set the correct cursor position
|
|
1452
|
+
if (idx !== null) {
|
|
1453
|
+
that.dom.value[idx].removeClass(that.classes.italic);
|
|
1454
|
+
that.dom.value[idx].focus();
|
|
1455
|
+
if (cursorPos !== null) {
|
|
1456
|
+
that.dom.value[idx][0].setSelectionRange(cursorPos, cursorPos);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
// The order of the conditions will make eslint sad :(
|
|
1461
|
+
// Has to be in this order so that they are displayed correctly in select elements
|
|
1462
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
1463
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1464
|
+
Criteria.dateConditions = {
|
|
1465
|
+
'=': {
|
|
1466
|
+
conditionName: function (dt, i18n) {
|
|
1467
|
+
return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);
|
|
1468
|
+
},
|
|
1469
|
+
init: Criteria.initDate,
|
|
1470
|
+
inputValue: Criteria.inputValueInput,
|
|
1471
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1472
|
+
search: function (value, comparison) {
|
|
1473
|
+
value = value.replace(/(\/|-|,)/g, '-');
|
|
1474
|
+
return value === comparison[0];
|
|
1475
|
+
}
|
|
1476
|
+
},
|
|
1477
|
+
// eslint-disable-next-line sort-keys
|
|
1478
|
+
'!=': {
|
|
1479
|
+
conditionName: function (dt, i18n) {
|
|
1480
|
+
return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);
|
|
1481
|
+
},
|
|
1482
|
+
init: Criteria.initDate,
|
|
1483
|
+
inputValue: Criteria.inputValueInput,
|
|
1484
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1485
|
+
search: function (value, comparison) {
|
|
1486
|
+
value = value.replace(/(\/|-|,)/g, '-');
|
|
1487
|
+
return value !== comparison[0];
|
|
1488
|
+
}
|
|
1489
|
+
},
|
|
1490
|
+
'<': {
|
|
1491
|
+
conditionName: function (dt, i18n) {
|
|
1492
|
+
return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);
|
|
1493
|
+
},
|
|
1494
|
+
init: Criteria.initDate,
|
|
1495
|
+
inputValue: Criteria.inputValueInput,
|
|
1496
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1497
|
+
search: function (value, comparison) {
|
|
1498
|
+
value = value.replace(/(\/|-|,)/g, '-');
|
|
1499
|
+
return value < comparison[0];
|
|
1500
|
+
}
|
|
1501
|
+
},
|
|
1502
|
+
'>': {
|
|
1503
|
+
conditionName: function (dt, i18n) {
|
|
1504
|
+
return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);
|
|
1505
|
+
},
|
|
1506
|
+
init: Criteria.initDate,
|
|
1507
|
+
inputValue: Criteria.inputValueInput,
|
|
1508
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1509
|
+
search: function (value, comparison) {
|
|
1510
|
+
value = value.replace(/(\/|-|,)/g, '-');
|
|
1511
|
+
return value > comparison[0];
|
|
1512
|
+
}
|
|
1513
|
+
},
|
|
1514
|
+
'between': {
|
|
1515
|
+
conditionName: function (dt, i18n) {
|
|
1516
|
+
return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);
|
|
1517
|
+
},
|
|
1518
|
+
init: Criteria.init2Date,
|
|
1519
|
+
inputValue: Criteria.inputValueInput,
|
|
1520
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1521
|
+
search: function (value, comparison) {
|
|
1522
|
+
value = value.replace(/(\/|-|,)/g, '-');
|
|
1523
|
+
if (comparison[0] < comparison[1]) {
|
|
1524
|
+
return comparison[0] <= value && value <= comparison[1];
|
|
1525
|
+
}
|
|
1526
|
+
else {
|
|
1527
|
+
return comparison[1] <= value && value <= comparison[0];
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
// eslint-disable-next-line sort-keys
|
|
1532
|
+
'!between': {
|
|
1533
|
+
conditionName: function (dt, i18n) {
|
|
1534
|
+
return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);
|
|
1535
|
+
},
|
|
1536
|
+
init: Criteria.init2Date,
|
|
1537
|
+
inputValue: Criteria.inputValueInput,
|
|
1538
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1539
|
+
search: function (value, comparison) {
|
|
1540
|
+
value = value.replace(/(\/|-|,)/g, '-');
|
|
1541
|
+
if (comparison[0] < comparison[1]) {
|
|
1542
|
+
return !(comparison[0] <= value && value <= comparison[1]);
|
|
1543
|
+
}
|
|
1544
|
+
else {
|
|
1545
|
+
return !(comparison[1] <= value && value <= comparison[0]);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
},
|
|
1549
|
+
'null': {
|
|
1550
|
+
conditionName: function (dt, i18n) {
|
|
1551
|
+
return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);
|
|
1552
|
+
},
|
|
1553
|
+
init: Criteria.initNoValue,
|
|
1554
|
+
inputValue: function () {
|
|
1555
|
+
return;
|
|
1556
|
+
},
|
|
1557
|
+
isInputValid: function () {
|
|
1558
|
+
return true;
|
|
1559
|
+
},
|
|
1560
|
+
search: function (value) {
|
|
1561
|
+
return value === null || value === undefined || value.length === 0;
|
|
1562
|
+
}
|
|
1563
|
+
},
|
|
1564
|
+
// eslint-disable-next-line sort-keys
|
|
1565
|
+
'!null': {
|
|
1566
|
+
conditionName: function (dt, i18n) {
|
|
1567
|
+
return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);
|
|
1568
|
+
},
|
|
1569
|
+
init: Criteria.initNoValue,
|
|
1570
|
+
inputValue: function () {
|
|
1571
|
+
return;
|
|
1572
|
+
},
|
|
1573
|
+
isInputValid: function () {
|
|
1574
|
+
return true;
|
|
1575
|
+
},
|
|
1576
|
+
search: function (value) {
|
|
1577
|
+
return !(value === null || value === undefined || value.length === 0);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
// The order of the conditions will make eslint sad :(
|
|
1582
|
+
// Has to be in this order so that they are displayed correctly in select elements
|
|
1583
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
1584
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1585
|
+
Criteria.momentDateConditions = {
|
|
1586
|
+
'=': {
|
|
1587
|
+
conditionName: function (dt, i18n) {
|
|
1588
|
+
return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);
|
|
1589
|
+
},
|
|
1590
|
+
init: Criteria.initDate,
|
|
1591
|
+
inputValue: Criteria.inputValueInput,
|
|
1592
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1593
|
+
search: function (value, comparison, that) {
|
|
1594
|
+
return moment()(value, that.s.dateFormat).valueOf() ===
|
|
1595
|
+
moment()(comparison[0], that.s.dateFormat).valueOf();
|
|
1596
|
+
}
|
|
1597
|
+
},
|
|
1598
|
+
// eslint-disable-next-line sort-keys
|
|
1599
|
+
'!=': {
|
|
1600
|
+
conditionName: function (dt, i18n) {
|
|
1601
|
+
return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);
|
|
1602
|
+
},
|
|
1603
|
+
init: Criteria.initDate,
|
|
1604
|
+
inputValue: Criteria.inputValueInput,
|
|
1605
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1606
|
+
search: function (value, comparison, that) {
|
|
1607
|
+
return moment()(value, that.s.dateFormat).valueOf() !==
|
|
1608
|
+
moment()(comparison[0], that.s.dateFormat).valueOf();
|
|
1609
|
+
}
|
|
1610
|
+
},
|
|
1611
|
+
'<': {
|
|
1612
|
+
conditionName: function (dt, i18n) {
|
|
1613
|
+
return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);
|
|
1614
|
+
},
|
|
1615
|
+
init: Criteria.initDate,
|
|
1616
|
+
inputValue: Criteria.inputValueInput,
|
|
1617
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1618
|
+
search: function (value, comparison, that) {
|
|
1619
|
+
return moment()(value, that.s.dateFormat).valueOf() < moment()(comparison[0], that.s.dateFormat).valueOf();
|
|
1620
|
+
}
|
|
1621
|
+
},
|
|
1622
|
+
'>': {
|
|
1623
|
+
conditionName: function (dt, i18n) {
|
|
1624
|
+
return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);
|
|
1625
|
+
},
|
|
1626
|
+
init: Criteria.initDate,
|
|
1627
|
+
inputValue: Criteria.inputValueInput,
|
|
1628
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1629
|
+
search: function (value, comparison, that) {
|
|
1630
|
+
return moment()(value, that.s.dateFormat).valueOf() > moment()(comparison[0], that.s.dateFormat).valueOf();
|
|
1631
|
+
}
|
|
1632
|
+
},
|
|
1633
|
+
'between': {
|
|
1634
|
+
conditionName: function (dt, i18n) {
|
|
1635
|
+
return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);
|
|
1636
|
+
},
|
|
1637
|
+
init: Criteria.init2Date,
|
|
1638
|
+
inputValue: Criteria.inputValueInput,
|
|
1639
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1640
|
+
search: function (value, comparison, that) {
|
|
1641
|
+
var val = moment()(value, that.s.dateFormat).valueOf();
|
|
1642
|
+
var comp0 = moment()(comparison[0], that.s.dateFormat).valueOf();
|
|
1643
|
+
var comp1 = moment()(comparison[1], that.s.dateFormat).valueOf();
|
|
1644
|
+
if (comp0 < comp1) {
|
|
1645
|
+
return comp0 <= val && val <= comp1;
|
|
1646
|
+
}
|
|
1647
|
+
else {
|
|
1648
|
+
return comp1 <= val && val <= comp0;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
},
|
|
1652
|
+
// eslint-disable-next-line sort-keys
|
|
1653
|
+
'!between': {
|
|
1654
|
+
conditionName: function (dt, i18n) {
|
|
1655
|
+
return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);
|
|
1656
|
+
},
|
|
1657
|
+
init: Criteria.init2Date,
|
|
1658
|
+
inputValue: Criteria.inputValueInput,
|
|
1659
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1660
|
+
search: function (value, comparison, that) {
|
|
1661
|
+
var val = moment()(value, that.s.dateFormat).valueOf();
|
|
1662
|
+
var comp0 = moment()(comparison[0], that.s.dateFormat).valueOf();
|
|
1663
|
+
var comp1 = moment()(comparison[1], that.s.dateFormat).valueOf();
|
|
1664
|
+
if (comp0 < comp1) {
|
|
1665
|
+
return !(+comp0 <= +val && +val <= +comp1);
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
return !(+comp1 <= +val && +val <= +comp0);
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
},
|
|
1672
|
+
'null': {
|
|
1673
|
+
conditionName: function (dt, i18n) {
|
|
1674
|
+
return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);
|
|
1675
|
+
},
|
|
1676
|
+
init: Criteria.initNoValue,
|
|
1677
|
+
inputValue: function () {
|
|
1678
|
+
return;
|
|
1679
|
+
},
|
|
1680
|
+
isInputValid: function () {
|
|
1681
|
+
return true;
|
|
1682
|
+
},
|
|
1683
|
+
search: function (value) {
|
|
1684
|
+
return value === null || value === undefined || value.length === 0;
|
|
1685
|
+
}
|
|
1686
|
+
},
|
|
1687
|
+
// eslint-disable-next-line sort-keys
|
|
1688
|
+
'!null': {
|
|
1689
|
+
conditionName: function (dt, i18n) {
|
|
1690
|
+
return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);
|
|
1691
|
+
},
|
|
1692
|
+
init: Criteria.initNoValue,
|
|
1693
|
+
inputValue: function () {
|
|
1694
|
+
return;
|
|
1695
|
+
},
|
|
1696
|
+
isInputValid: function () {
|
|
1697
|
+
return true;
|
|
1698
|
+
},
|
|
1699
|
+
search: function (value) {
|
|
1700
|
+
return !(value === null || value === undefined || value.length === 0);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
// The order of the conditions will make eslint sad :(
|
|
1705
|
+
// Has to be in this order so that they are displayed correctly in select elements
|
|
1706
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
1707
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1708
|
+
Criteria.luxonDateConditions = {
|
|
1709
|
+
'=': {
|
|
1710
|
+
conditionName: function (dt, i18n) {
|
|
1711
|
+
return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);
|
|
1712
|
+
},
|
|
1713
|
+
init: Criteria.initDate,
|
|
1714
|
+
inputValue: Criteria.inputValueInput,
|
|
1715
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1716
|
+
search: function (value, comparison, that) {
|
|
1717
|
+
return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
|
|
1718
|
+
=== luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
|
|
1719
|
+
}
|
|
1720
|
+
},
|
|
1721
|
+
// eslint-disable-next-line sort-keys
|
|
1722
|
+
'!=': {
|
|
1723
|
+
conditionName: function (dt, i18n) {
|
|
1724
|
+
return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);
|
|
1725
|
+
},
|
|
1726
|
+
init: Criteria.initDate,
|
|
1727
|
+
inputValue: Criteria.inputValueInput,
|
|
1728
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1729
|
+
search: function (value, comparison, that) {
|
|
1730
|
+
return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
|
|
1731
|
+
!== luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
|
|
1732
|
+
}
|
|
1733
|
+
},
|
|
1734
|
+
'<': {
|
|
1735
|
+
conditionName: function (dt, i18n) {
|
|
1736
|
+
return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);
|
|
1737
|
+
},
|
|
1738
|
+
init: Criteria.initDate,
|
|
1739
|
+
inputValue: Criteria.inputValueInput,
|
|
1740
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1741
|
+
search: function (value, comparison, that) {
|
|
1742
|
+
return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
|
|
1743
|
+
< luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
|
|
1744
|
+
}
|
|
1745
|
+
},
|
|
1746
|
+
'>': {
|
|
1747
|
+
conditionName: function (dt, i18n) {
|
|
1748
|
+
return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);
|
|
1749
|
+
},
|
|
1750
|
+
init: Criteria.initDate,
|
|
1751
|
+
inputValue: Criteria.inputValueInput,
|
|
1752
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1753
|
+
search: function (value, comparison, that) {
|
|
1754
|
+
return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
|
|
1755
|
+
> luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
|
|
1756
|
+
}
|
|
1757
|
+
},
|
|
1758
|
+
'between': {
|
|
1759
|
+
conditionName: function (dt, i18n) {
|
|
1760
|
+
return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);
|
|
1761
|
+
},
|
|
1762
|
+
init: Criteria.init2Date,
|
|
1763
|
+
inputValue: Criteria.inputValueInput,
|
|
1764
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1765
|
+
search: function (value, comparison, that) {
|
|
1766
|
+
var val = luxon().DateTime.fromFormat(value, that.s.dateFormat).ts;
|
|
1767
|
+
var comp0 = luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
|
|
1768
|
+
var comp1 = luxon().DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
|
|
1769
|
+
if (comp0 < comp1) {
|
|
1770
|
+
return comp0 <= val && val <= comp1;
|
|
1771
|
+
}
|
|
1772
|
+
else {
|
|
1773
|
+
return comp1 <= val && val <= comp0;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
},
|
|
1777
|
+
// eslint-disable-next-line sort-keys
|
|
1778
|
+
'!between': {
|
|
1779
|
+
conditionName: function (dt, i18n) {
|
|
1780
|
+
return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);
|
|
1781
|
+
},
|
|
1782
|
+
init: Criteria.init2Date,
|
|
1783
|
+
inputValue: Criteria.inputValueInput,
|
|
1784
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1785
|
+
search: function (value, comparison, that) {
|
|
1786
|
+
var val = luxon().DateTime.fromFormat(value, that.s.dateFormat).ts;
|
|
1787
|
+
var comp0 = luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
|
|
1788
|
+
var comp1 = luxon().DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
|
|
1789
|
+
if (comp0 < comp1) {
|
|
1790
|
+
return !(+comp0 <= +val && +val <= +comp1);
|
|
1791
|
+
}
|
|
1792
|
+
else {
|
|
1793
|
+
return !(+comp1 <= +val && +val <= +comp0);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
},
|
|
1797
|
+
'null': {
|
|
1798
|
+
conditionName: function (dt, i18n) {
|
|
1799
|
+
return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);
|
|
1800
|
+
},
|
|
1801
|
+
init: Criteria.initNoValue,
|
|
1802
|
+
inputValue: function () {
|
|
1803
|
+
return;
|
|
1804
|
+
},
|
|
1805
|
+
isInputValid: function () {
|
|
1806
|
+
return true;
|
|
1807
|
+
},
|
|
1808
|
+
search: function (value) {
|
|
1809
|
+
return value === null || value === undefined || value.length === 0;
|
|
1810
|
+
}
|
|
1811
|
+
},
|
|
1812
|
+
// eslint-disable-next-line sort-keys
|
|
1813
|
+
'!null': {
|
|
1814
|
+
conditionName: function (dt, i18n) {
|
|
1815
|
+
return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);
|
|
1816
|
+
},
|
|
1817
|
+
init: Criteria.initNoValue,
|
|
1818
|
+
inputValue: function () {
|
|
1819
|
+
return;
|
|
1820
|
+
},
|
|
1821
|
+
isInputValid: function () {
|
|
1822
|
+
return true;
|
|
1823
|
+
},
|
|
1824
|
+
search: function (value) {
|
|
1825
|
+
return !(value === null || value === undefined || value.length === 0);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
};
|
|
1829
|
+
// The order of the conditions will make eslint sad :(
|
|
1830
|
+
// Has to be in this order so that they are displayed correctly in select elements
|
|
1831
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
1832
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1833
|
+
Criteria.numConditions = {
|
|
1834
|
+
'=': {
|
|
1835
|
+
conditionName: function (dt, i18n) {
|
|
1836
|
+
return dt.i18n('searchBuilder.conditions.number.equals', i18n.conditions.number.equals);
|
|
1837
|
+
},
|
|
1838
|
+
init: Criteria.initSelect,
|
|
1839
|
+
inputValue: Criteria.inputValueSelect,
|
|
1840
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
1841
|
+
search: function (value, comparison) {
|
|
1842
|
+
return +value === +comparison[0];
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1845
|
+
// eslint-disable-next-line sort-keys
|
|
1846
|
+
'!=': {
|
|
1847
|
+
conditionName: function (dt, i18n) {
|
|
1848
|
+
return dt.i18n('searchBuilder.conditions.number.not', i18n.conditions.number.not);
|
|
1849
|
+
},
|
|
1850
|
+
init: Criteria.initSelect,
|
|
1851
|
+
inputValue: Criteria.inputValueSelect,
|
|
1852
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
1853
|
+
search: function (value, comparison) {
|
|
1854
|
+
return +value !== +comparison[0];
|
|
1855
|
+
}
|
|
1856
|
+
},
|
|
1857
|
+
'<': {
|
|
1858
|
+
conditionName: function (dt, i18n) {
|
|
1859
|
+
return dt.i18n('searchBuilder.conditions.number.lt', i18n.conditions.number.lt);
|
|
1860
|
+
},
|
|
1861
|
+
init: Criteria.initInput,
|
|
1862
|
+
inputValue: Criteria.inputValueInput,
|
|
1863
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1864
|
+
search: function (value, comparison) {
|
|
1865
|
+
return +value < +comparison[0];
|
|
1866
|
+
}
|
|
1867
|
+
},
|
|
1868
|
+
'<=': {
|
|
1869
|
+
conditionName: function (dt, i18n) {
|
|
1870
|
+
return dt.i18n('searchBuilder.conditions.number.lte', i18n.conditions.number.lte);
|
|
1871
|
+
},
|
|
1872
|
+
init: Criteria.initInput,
|
|
1873
|
+
inputValue: Criteria.inputValueInput,
|
|
1874
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1875
|
+
search: function (value, comparison) {
|
|
1876
|
+
return +value <= +comparison[0];
|
|
1877
|
+
}
|
|
1878
|
+
},
|
|
1879
|
+
'>=': {
|
|
1880
|
+
conditionName: function (dt, i18n) {
|
|
1881
|
+
return dt.i18n('searchBuilder.conditions.number.gte', i18n.conditions.number.gte);
|
|
1882
|
+
},
|
|
1883
|
+
init: Criteria.initInput,
|
|
1884
|
+
inputValue: Criteria.inputValueInput,
|
|
1885
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1886
|
+
search: function (value, comparison) {
|
|
1887
|
+
return +value >= +comparison[0];
|
|
1888
|
+
}
|
|
1889
|
+
},
|
|
1890
|
+
// eslint-disable-next-line sort-keys
|
|
1891
|
+
'>': {
|
|
1892
|
+
conditionName: function (dt, i18n) {
|
|
1893
|
+
return dt.i18n('searchBuilder.conditions.number.gt', i18n.conditions.number.gt);
|
|
1894
|
+
},
|
|
1895
|
+
init: Criteria.initInput,
|
|
1896
|
+
inputValue: Criteria.inputValueInput,
|
|
1897
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1898
|
+
search: function (value, comparison) {
|
|
1899
|
+
return +value > +comparison[0];
|
|
1900
|
+
}
|
|
1901
|
+
},
|
|
1902
|
+
'between': {
|
|
1903
|
+
conditionName: function (dt, i18n) {
|
|
1904
|
+
return dt.i18n('searchBuilder.conditions.number.between', i18n.conditions.number.between);
|
|
1905
|
+
},
|
|
1906
|
+
init: Criteria.init2Input,
|
|
1907
|
+
inputValue: Criteria.inputValueInput,
|
|
1908
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1909
|
+
search: function (value, comparison) {
|
|
1910
|
+
if (+comparison[0] < +comparison[1]) {
|
|
1911
|
+
return +comparison[0] <= +value && +value <= +comparison[1];
|
|
1912
|
+
}
|
|
1913
|
+
else {
|
|
1914
|
+
return +comparison[1] <= +value && +value <= +comparison[0];
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
},
|
|
1918
|
+
// eslint-disable-next-line sort-keys
|
|
1919
|
+
'!between': {
|
|
1920
|
+
conditionName: function (dt, i18n) {
|
|
1921
|
+
return dt.i18n('searchBuilder.conditions.number.notBetween', i18n.conditions.number.notBetween);
|
|
1922
|
+
},
|
|
1923
|
+
init: Criteria.init2Input,
|
|
1924
|
+
inputValue: Criteria.inputValueInput,
|
|
1925
|
+
isInputValid: Criteria.isInputValidInput,
|
|
1926
|
+
search: function (value, comparison) {
|
|
1927
|
+
if (+comparison[0] < +comparison[1]) {
|
|
1928
|
+
return !(+comparison[0] <= +value && +value <= +comparison[1]);
|
|
1929
|
+
}
|
|
1930
|
+
else {
|
|
1931
|
+
return !(+comparison[1] <= +value && +value <= +comparison[0]);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
},
|
|
1935
|
+
'null': {
|
|
1936
|
+
conditionName: function (dt, i18n) {
|
|
1937
|
+
return dt.i18n('searchBuilder.conditions.number.empty', i18n.conditions.number.empty);
|
|
1938
|
+
},
|
|
1939
|
+
init: Criteria.initNoValue,
|
|
1940
|
+
inputValue: function () {
|
|
1941
|
+
return;
|
|
1942
|
+
},
|
|
1943
|
+
isInputValid: function () {
|
|
1944
|
+
return true;
|
|
1945
|
+
},
|
|
1946
|
+
search: function (value) {
|
|
1947
|
+
return value === null || value === undefined || value.length === 0;
|
|
1948
|
+
}
|
|
1949
|
+
},
|
|
1950
|
+
// eslint-disable-next-line sort-keys
|
|
1951
|
+
'!null': {
|
|
1952
|
+
conditionName: function (dt, i18n) {
|
|
1953
|
+
return dt.i18n('searchBuilder.conditions.number.notEmpty', i18n.conditions.number.notEmpty);
|
|
1954
|
+
},
|
|
1955
|
+
init: Criteria.initNoValue,
|
|
1956
|
+
inputValue: function () {
|
|
1957
|
+
return;
|
|
1958
|
+
},
|
|
1959
|
+
isInputValid: function () {
|
|
1960
|
+
return true;
|
|
1961
|
+
},
|
|
1962
|
+
search: function (value) {
|
|
1963
|
+
return !(value === null || value === undefined || value.length === 0);
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
// The order of the conditions will make eslint sad :(
|
|
1968
|
+
// Has to be in this order so that they are displayed correctly in select elements
|
|
1969
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
1970
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1971
|
+
Criteria.numFmtConditions = {
|
|
1972
|
+
'=': {
|
|
1973
|
+
conditionName: function (dt, i18n) {
|
|
1974
|
+
return dt.i18n('searchBuilder.conditions.number.equals', i18n.conditions.number.equals);
|
|
1975
|
+
},
|
|
1976
|
+
init: Criteria.initSelect,
|
|
1977
|
+
inputValue: Criteria.inputValueSelect,
|
|
1978
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
1979
|
+
search: function (value, comparison) {
|
|
1980
|
+
return Criteria.parseNumFmt(value) === Criteria.parseNumFmt(comparison[0]);
|
|
1981
|
+
}
|
|
1982
|
+
},
|
|
1983
|
+
// eslint-disable-next-line sort-keys
|
|
1984
|
+
'!=': {
|
|
1985
|
+
conditionName: function (dt, i18n) {
|
|
1986
|
+
return dt.i18n('searchBuilder.conditions.number.not', i18n.conditions.number.not);
|
|
1987
|
+
},
|
|
1988
|
+
init: Criteria.initSelect,
|
|
1989
|
+
inputValue: Criteria.inputValueSelect,
|
|
1990
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
1991
|
+
search: function (value, comparison) {
|
|
1992
|
+
return Criteria.parseNumFmt(value) !== Criteria.parseNumFmt(comparison[0]);
|
|
1993
|
+
}
|
|
1994
|
+
},
|
|
1995
|
+
'<': {
|
|
1996
|
+
conditionName: function (dt, i18n) {
|
|
1997
|
+
return dt.i18n('searchBuilder.conditions.number.lt', i18n.conditions.number.lt);
|
|
1998
|
+
},
|
|
1999
|
+
init: Criteria.initInput,
|
|
2000
|
+
inputValue: Criteria.inputValueInput,
|
|
2001
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2002
|
+
search: function (value, comparison) {
|
|
2003
|
+
return Criteria.parseNumFmt(value) < Criteria.parseNumFmt(comparison[0]);
|
|
2004
|
+
}
|
|
2005
|
+
},
|
|
2006
|
+
'<=': {
|
|
2007
|
+
conditionName: function (dt, i18n) {
|
|
2008
|
+
return dt.i18n('searchBuilder.conditions.number.lte', i18n.conditions.number.lte);
|
|
2009
|
+
},
|
|
2010
|
+
init: Criteria.initInput,
|
|
2011
|
+
inputValue: Criteria.inputValueInput,
|
|
2012
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2013
|
+
search: function (value, comparison) {
|
|
2014
|
+
return Criteria.parseNumFmt(value) <= Criteria.parseNumFmt(comparison[0]);
|
|
2015
|
+
}
|
|
2016
|
+
},
|
|
2017
|
+
'>=': {
|
|
2018
|
+
conditionName: function (dt, i18n) {
|
|
2019
|
+
return dt.i18n('searchBuilder.conditions.number.gte', i18n.conditions.number.gte);
|
|
2020
|
+
},
|
|
2021
|
+
init: Criteria.initInput,
|
|
2022
|
+
inputValue: Criteria.inputValueInput,
|
|
2023
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2024
|
+
search: function (value, comparison) {
|
|
2025
|
+
return Criteria.parseNumFmt(value) >= Criteria.parseNumFmt(comparison[0]);
|
|
2026
|
+
}
|
|
2027
|
+
},
|
|
2028
|
+
// eslint-disable-next-line sort-keys
|
|
2029
|
+
'>': {
|
|
2030
|
+
conditionName: function (dt, i18n) {
|
|
2031
|
+
return dt.i18n('searchBuilder.conditions.number.gt', i18n.conditions.number.gt);
|
|
2032
|
+
},
|
|
2033
|
+
init: Criteria.initInput,
|
|
2034
|
+
inputValue: Criteria.inputValueInput,
|
|
2035
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2036
|
+
search: function (value, comparison) {
|
|
2037
|
+
return Criteria.parseNumFmt(value) > Criteria.parseNumFmt(comparison[0]);
|
|
2038
|
+
}
|
|
2039
|
+
},
|
|
2040
|
+
'between': {
|
|
2041
|
+
conditionName: function (dt, i18n) {
|
|
2042
|
+
return dt.i18n('searchBuilder.conditions.number.between', i18n.conditions.number.between);
|
|
2043
|
+
},
|
|
2044
|
+
init: Criteria.init2Input,
|
|
2045
|
+
inputValue: Criteria.inputValueInput,
|
|
2046
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2047
|
+
search: function (value, comparison) {
|
|
2048
|
+
var val = Criteria.parseNumFmt(value);
|
|
2049
|
+
var comp0 = Criteria.parseNumFmt(comparison[0]);
|
|
2050
|
+
var comp1 = Criteria.parseNumFmt(comparison[1]);
|
|
2051
|
+
if (+comp0 < +comp1) {
|
|
2052
|
+
return +comp0 <= +val && +val <= +comp1;
|
|
2053
|
+
}
|
|
2054
|
+
else {
|
|
2055
|
+
return +comp1 <= +val && +val <= +comp0;
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
},
|
|
2059
|
+
// eslint-disable-next-line sort-keys
|
|
2060
|
+
'!between': {
|
|
2061
|
+
conditionName: function (dt, i18n) {
|
|
2062
|
+
return dt.i18n('searchBuilder.conditions.number.notBetween', i18n.conditions.number.notBetween);
|
|
2063
|
+
},
|
|
2064
|
+
init: Criteria.init2Input,
|
|
2065
|
+
inputValue: Criteria.inputValueInput,
|
|
2066
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2067
|
+
search: function (value, comparison) {
|
|
2068
|
+
var val = Criteria.parseNumFmt(value);
|
|
2069
|
+
var comp0 = Criteria.parseNumFmt(comparison[0]);
|
|
2070
|
+
var comp1 = Criteria.parseNumFmt(comparison[1]);
|
|
2071
|
+
if (+comp0 < +comp1) {
|
|
2072
|
+
return !(+comp0 <= +val && +val <= +comp1);
|
|
2073
|
+
}
|
|
2074
|
+
else {
|
|
2075
|
+
return !(+comp1 <= +val && +val <= +comp0);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
},
|
|
2079
|
+
'null': {
|
|
2080
|
+
conditionName: function (dt, i18n) {
|
|
2081
|
+
return dt.i18n('searchBuilder.conditions.number.empty', i18n.conditions.number.empty);
|
|
2082
|
+
},
|
|
2083
|
+
init: Criteria.initNoValue,
|
|
2084
|
+
inputValue: function () {
|
|
2085
|
+
return;
|
|
2086
|
+
},
|
|
2087
|
+
isInputValid: function () {
|
|
2088
|
+
return true;
|
|
2089
|
+
},
|
|
2090
|
+
search: function (value) {
|
|
2091
|
+
return value === null || value === undefined || value.length === 0;
|
|
2092
|
+
}
|
|
2093
|
+
},
|
|
2094
|
+
// eslint-disable-next-line sort-keys
|
|
2095
|
+
'!null': {
|
|
2096
|
+
conditionName: function (dt, i18n) {
|
|
2097
|
+
return dt.i18n('searchBuilder.conditions.number.notEmpty', i18n.conditions.number.notEmpty);
|
|
2098
|
+
},
|
|
2099
|
+
init: Criteria.initNoValue,
|
|
2100
|
+
inputValue: function () {
|
|
2101
|
+
return;
|
|
2102
|
+
},
|
|
2103
|
+
isInputValid: function () {
|
|
2104
|
+
return true;
|
|
2105
|
+
},
|
|
2106
|
+
search: function (value) {
|
|
2107
|
+
return !(value === null || value === undefined || value.length === 0);
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
};
|
|
2111
|
+
// The order of the conditions will make eslint sad :(
|
|
2112
|
+
// Has to be in this order so that they are displayed correctly in select elements
|
|
2113
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
2114
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
2115
|
+
Criteria.stringConditions = {
|
|
2116
|
+
'=': {
|
|
2117
|
+
conditionName: function (dt, i18n) {
|
|
2118
|
+
return dt.i18n('searchBuilder.conditions.string.equals', i18n.conditions.string.equals);
|
|
2119
|
+
},
|
|
2120
|
+
init: Criteria.initSelect,
|
|
2121
|
+
inputValue: Criteria.inputValueSelect,
|
|
2122
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
2123
|
+
search: function (value, comparison) {
|
|
2124
|
+
return value === comparison[0];
|
|
2125
|
+
}
|
|
2126
|
+
},
|
|
2127
|
+
// eslint-disable-next-line sort-keys
|
|
2128
|
+
'!=': {
|
|
2129
|
+
conditionName: function (dt, i18n) {
|
|
2130
|
+
return dt.i18n('searchBuilder.conditions.string.not', i18n.conditions.string.not);
|
|
2131
|
+
},
|
|
2132
|
+
init: Criteria.initSelect,
|
|
2133
|
+
inputValue: Criteria.inputValueSelect,
|
|
2134
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2135
|
+
search: function (value, comparison) {
|
|
2136
|
+
return value !== comparison[0];
|
|
2137
|
+
}
|
|
2138
|
+
},
|
|
2139
|
+
'starts': {
|
|
2140
|
+
conditionName: function (dt, i18n) {
|
|
2141
|
+
return dt.i18n('searchBuilder.conditions.string.startsWith', i18n.conditions.string.startsWith);
|
|
2142
|
+
},
|
|
2143
|
+
init: Criteria.initInput,
|
|
2144
|
+
inputValue: Criteria.inputValueInput,
|
|
2145
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2146
|
+
search: function (value, comparison) {
|
|
2147
|
+
return value.toLowerCase().indexOf(comparison[0].toLowerCase()) === 0;
|
|
2148
|
+
}
|
|
2149
|
+
},
|
|
2150
|
+
// eslint-disable-next-line sort-keys
|
|
2151
|
+
'!starts': {
|
|
2152
|
+
conditionName: function (dt, i18n) {
|
|
2153
|
+
return dt.i18n('searchBuilder.conditions.string.notStartsWith', i18n.conditions.string.notStartsWith);
|
|
2154
|
+
},
|
|
2155
|
+
init: Criteria.initInput,
|
|
2156
|
+
inputValue: Criteria.inputValueInput,
|
|
2157
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2158
|
+
search: function (value, comparison) {
|
|
2159
|
+
return value.toLowerCase().indexOf(comparison[0].toLowerCase()) !== 0;
|
|
2160
|
+
}
|
|
2161
|
+
},
|
|
2162
|
+
// eslint-disable-next-line sort-keys
|
|
2163
|
+
'contains': {
|
|
2164
|
+
conditionName: function (dt, i18n) {
|
|
2165
|
+
return dt.i18n('searchBuilder.conditions.string.contains', i18n.conditions.string.contains);
|
|
2166
|
+
},
|
|
2167
|
+
init: Criteria.initInput,
|
|
2168
|
+
inputValue: Criteria.inputValueInput,
|
|
2169
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2170
|
+
search: function (value, comparison) {
|
|
2171
|
+
return value.toLowerCase().includes(comparison[0].toLowerCase());
|
|
2172
|
+
}
|
|
2173
|
+
},
|
|
2174
|
+
// eslint-disable-next-line sort-keys
|
|
2175
|
+
'!contains': {
|
|
2176
|
+
conditionName: function (dt, i18n) {
|
|
2177
|
+
return dt.i18n('searchBuilder.conditions.string.notContains', i18n.conditions.string.notContains);
|
|
2178
|
+
},
|
|
2179
|
+
init: Criteria.initInput,
|
|
2180
|
+
inputValue: Criteria.inputValueInput,
|
|
2181
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2182
|
+
search: function (value, comparison) {
|
|
2183
|
+
return !value.toLowerCase().includes(comparison[0].toLowerCase());
|
|
2184
|
+
}
|
|
2185
|
+
},
|
|
2186
|
+
'ends': {
|
|
2187
|
+
conditionName: function (dt, i18n) {
|
|
2188
|
+
return dt.i18n('searchBuilder.conditions.string.endsWith', i18n.conditions.string.endsWith);
|
|
2189
|
+
},
|
|
2190
|
+
init: Criteria.initInput,
|
|
2191
|
+
inputValue: Criteria.inputValueInput,
|
|
2192
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2193
|
+
search: function (value, comparison) {
|
|
2194
|
+
return value.toLowerCase().endsWith(comparison[0].toLowerCase());
|
|
2195
|
+
}
|
|
2196
|
+
},
|
|
2197
|
+
// eslint-disable-next-line sort-keys
|
|
2198
|
+
'!ends': {
|
|
2199
|
+
conditionName: function (dt, i18n) {
|
|
2200
|
+
return dt.i18n('searchBuilder.conditions.string.notEndsWith', i18n.conditions.string.notEndsWith);
|
|
2201
|
+
},
|
|
2202
|
+
init: Criteria.initInput,
|
|
2203
|
+
inputValue: Criteria.inputValueInput,
|
|
2204
|
+
isInputValid: Criteria.isInputValidInput,
|
|
2205
|
+
search: function (value, comparison) {
|
|
2206
|
+
return !value.toLowerCase().endsWith(comparison[0].toLowerCase());
|
|
2207
|
+
}
|
|
2208
|
+
},
|
|
2209
|
+
'null': {
|
|
2210
|
+
conditionName: function (dt, i18n) {
|
|
2211
|
+
return dt.i18n('searchBuilder.conditions.string.empty', i18n.conditions.string.empty);
|
|
2212
|
+
},
|
|
2213
|
+
init: Criteria.initNoValue,
|
|
2214
|
+
inputValue: function () {
|
|
2215
|
+
return;
|
|
2216
|
+
},
|
|
2217
|
+
isInputValid: function () {
|
|
2218
|
+
return true;
|
|
2219
|
+
},
|
|
2220
|
+
search: function (value) {
|
|
2221
|
+
return value === null || value === undefined || value.length === 0;
|
|
2222
|
+
}
|
|
2223
|
+
},
|
|
2224
|
+
// eslint-disable-next-line sort-keys
|
|
2225
|
+
'!null': {
|
|
2226
|
+
conditionName: function (dt, i18n) {
|
|
2227
|
+
return dt.i18n('searchBuilder.conditions.string.notEmpty', i18n.conditions.string.notEmpty);
|
|
2228
|
+
},
|
|
2229
|
+
init: Criteria.initNoValue,
|
|
2230
|
+
inputValue: function () {
|
|
2231
|
+
return;
|
|
2232
|
+
},
|
|
2233
|
+
isInputValid: function () {
|
|
2234
|
+
return true;
|
|
2235
|
+
},
|
|
2236
|
+
search: function (value) {
|
|
2237
|
+
return !(value === null || value === undefined || value.length === 0);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
// The order of the conditions will make eslint sad :(
|
|
2242
|
+
// Also have to disable member ordering for this as the private methods used are not yet declared otherwise
|
|
2243
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
2244
|
+
Criteria.arrayConditions = {
|
|
2245
|
+
'contains': {
|
|
2246
|
+
conditionName: function (dt, i18n) {
|
|
2247
|
+
return dt.i18n('searchBuilder.conditions.array.contains', i18n.conditions.array.contains);
|
|
2248
|
+
},
|
|
2249
|
+
init: Criteria.initSelectArray,
|
|
2250
|
+
inputValue: Criteria.inputValueSelect,
|
|
2251
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
2252
|
+
search: function (value, comparison) {
|
|
2253
|
+
return value.includes(comparison[0]);
|
|
2254
|
+
}
|
|
2255
|
+
},
|
|
2256
|
+
'without': {
|
|
2257
|
+
conditionName: function (dt, i18n) {
|
|
2258
|
+
return dt.i18n('searchBuilder.conditions.array.without', i18n.conditions.array.without);
|
|
2259
|
+
},
|
|
2260
|
+
init: Criteria.initSelectArray,
|
|
2261
|
+
inputValue: Criteria.inputValueSelect,
|
|
2262
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
2263
|
+
search: function (value, comparison) {
|
|
2264
|
+
return value.indexOf(comparison[0]) === -1;
|
|
2265
|
+
}
|
|
2266
|
+
},
|
|
2267
|
+
// eslint-disable-next-line sort-keys
|
|
2268
|
+
'=': {
|
|
2269
|
+
conditionName: function (dt, i18n) {
|
|
2270
|
+
return dt.i18n('searchBuilder.conditions.array.equals', i18n.conditions.array.equals);
|
|
2271
|
+
},
|
|
2272
|
+
init: Criteria.initSelect,
|
|
2273
|
+
inputValue: Criteria.inputValueSelect,
|
|
2274
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
2275
|
+
search: function (value, comparison) {
|
|
2276
|
+
if (value.length === comparison[0].length) {
|
|
2277
|
+
for (var i = 0; i < value.length; i++) {
|
|
2278
|
+
if (value[i] !== comparison[0][i]) {
|
|
2279
|
+
return false;
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
return true;
|
|
2283
|
+
}
|
|
2284
|
+
return false;
|
|
2285
|
+
}
|
|
2286
|
+
},
|
|
2287
|
+
// eslint-disable-next-line sort-keys
|
|
2288
|
+
'!=': {
|
|
2289
|
+
conditionName: function (dt, i18n) {
|
|
2290
|
+
return dt.i18n('searchBuilder.conditions.array.not', i18n.conditions.array.not);
|
|
2291
|
+
},
|
|
2292
|
+
init: Criteria.initSelect,
|
|
2293
|
+
inputValue: Criteria.inputValueSelect,
|
|
2294
|
+
isInputValid: Criteria.isInputValidSelect,
|
|
2295
|
+
search: function (value, comparison) {
|
|
2296
|
+
if (value.length === comparison[0].length) {
|
|
2297
|
+
for (var i = 0; i < value.length; i++) {
|
|
2298
|
+
if (value[i] !== comparison[0][i]) {
|
|
2299
|
+
return true;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
return false;
|
|
2303
|
+
}
|
|
2304
|
+
return true;
|
|
2305
|
+
}
|
|
2306
|
+
},
|
|
2307
|
+
'null': {
|
|
2308
|
+
conditionName: function (dt, i18n) {
|
|
2309
|
+
return dt.i18n('searchBuilder.conditions.array.empty', i18n.conditions.array.empty);
|
|
2310
|
+
},
|
|
2311
|
+
init: Criteria.initNoValue,
|
|
2312
|
+
inputValue: function () {
|
|
2313
|
+
return;
|
|
2314
|
+
},
|
|
2315
|
+
isInputValid: function () {
|
|
2316
|
+
return true;
|
|
2317
|
+
},
|
|
2318
|
+
search: function (value) {
|
|
2319
|
+
return value === null || value === undefined || value.length === 0;
|
|
2320
|
+
}
|
|
2321
|
+
},
|
|
2322
|
+
// eslint-disable-next-line sort-keys
|
|
2323
|
+
'!null': {
|
|
2324
|
+
conditionName: function (dt, i18n) {
|
|
2325
|
+
return dt.i18n('searchBuilder.conditions.array.notEmpty', i18n.conditions.array.notEmpty);
|
|
2326
|
+
},
|
|
2327
|
+
init: Criteria.initNoValue,
|
|
2328
|
+
inputValue: function () {
|
|
2329
|
+
return;
|
|
2330
|
+
},
|
|
2331
|
+
isInputValid: function () {
|
|
2332
|
+
return true;
|
|
2333
|
+
},
|
|
2334
|
+
search: function (value) {
|
|
2335
|
+
return value !== null && value !== undefined && value.length !== 0;
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
};
|
|
2339
|
+
// eslint will be sad because we have to disable member ordering for this as the
|
|
2340
|
+
// private static properties used are not yet declared otherwise
|
|
2341
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
2342
|
+
Criteria.defaults = {
|
|
2343
|
+
columns: true,
|
|
2344
|
+
conditions: {
|
|
2345
|
+
'array': Criteria.arrayConditions,
|
|
2346
|
+
'date': Criteria.dateConditions,
|
|
2347
|
+
'html': Criteria.stringConditions,
|
|
2348
|
+
'html-num': Criteria.numConditions,
|
|
2349
|
+
'html-num-fmt': Criteria.numFmtConditions,
|
|
2350
|
+
'luxon': Criteria.luxonDateConditions,
|
|
2351
|
+
'moment': Criteria.momentDateConditions,
|
|
2352
|
+
'num': Criteria.numConditions,
|
|
2353
|
+
'num-fmt': Criteria.numFmtConditions,
|
|
2354
|
+
'string': Criteria.stringConditions
|
|
2355
|
+
},
|
|
2356
|
+
depthLimit: false,
|
|
2357
|
+
enterSearch: false,
|
|
2358
|
+
filterChanged: undefined,
|
|
2359
|
+
greyscale: false,
|
|
2360
|
+
i18n: {
|
|
2361
|
+
add: 'Add Condition',
|
|
2362
|
+
button: {
|
|
2363
|
+
0: 'Search Builder',
|
|
2364
|
+
_: 'Search Builder (%d)'
|
|
2365
|
+
},
|
|
2366
|
+
clearAll: 'Clear All',
|
|
2367
|
+
condition: 'Condition',
|
|
2368
|
+
data: 'Data',
|
|
2369
|
+
"delete": '×',
|
|
2370
|
+
deleteTitle: 'Delete filtering rule',
|
|
2371
|
+
left: '<',
|
|
2372
|
+
leftTitle: 'Outdent criteria',
|
|
2373
|
+
logicAnd: 'And',
|
|
2374
|
+
logicOr: 'Or',
|
|
2375
|
+
right: '>',
|
|
2376
|
+
rightTitle: 'Indent criteria',
|
|
2377
|
+
title: {
|
|
2378
|
+
0: 'Custom Search Builder',
|
|
2379
|
+
_: 'Custom Search Builder (%d)'
|
|
2380
|
+
},
|
|
2381
|
+
value: 'Value',
|
|
2382
|
+
valueJoiner: 'and'
|
|
2383
|
+
},
|
|
2384
|
+
logic: 'AND',
|
|
2385
|
+
orthogonal: {
|
|
2386
|
+
display: 'display',
|
|
2387
|
+
search: 'filter'
|
|
2388
|
+
},
|
|
2389
|
+
preDefined: false
|
|
2390
|
+
};
|
|
2391
|
+
return Criteria;
|
|
2392
|
+
}());
|
|
2393
|
+
|
|
2394
|
+
var $$2;
|
|
2395
|
+
var dataTable$2;
|
|
2396
|
+
/**
|
|
2397
|
+
* Sets the value of jQuery for use in the file
|
|
2398
|
+
*
|
|
2399
|
+
* @param jq the instance of jQuery to be set
|
|
2400
|
+
*/
|
|
2401
|
+
function setJQuery$1(jq) {
|
|
2402
|
+
$$2 = jq;
|
|
2403
|
+
dataTable$2 = jq.fn.dataTable;
|
|
2404
|
+
}
|
|
2405
|
+
/**
|
|
2406
|
+
* The Group class is used within SearchBuilder to represent a group of criteria
|
|
2407
|
+
*/
|
|
2408
|
+
var Group = /** @class */ (function () {
|
|
2409
|
+
function Group(table, opts, topGroup, index, isChild, depth, serverData) {
|
|
2410
|
+
if (index === void 0) { index = 0; }
|
|
2411
|
+
if (isChild === void 0) { isChild = false; }
|
|
2412
|
+
if (depth === void 0) { depth = 1; }
|
|
2413
|
+
if (serverData === void 0) { serverData = undefined; }
|
|
2414
|
+
// Check that the required version of DataTables is included
|
|
2415
|
+
if (!dataTable$2 || !dataTable$2.versionCheck || !dataTable$2.versionCheck('1.10.0')) {
|
|
2416
|
+
throw new Error('SearchBuilder requires DataTables 1.10 or newer');
|
|
2417
|
+
}
|
|
2418
|
+
this.classes = $$2.extend(true, {}, Group.classes);
|
|
2419
|
+
// Get options from user
|
|
2420
|
+
this.c = $$2.extend(true, {}, Group.defaults, opts);
|
|
2421
|
+
this.s = {
|
|
2422
|
+
criteria: [],
|
|
2423
|
+
depth: depth,
|
|
2424
|
+
dt: table,
|
|
2425
|
+
index: index,
|
|
2426
|
+
isChild: isChild,
|
|
2427
|
+
logic: undefined,
|
|
2428
|
+
opts: opts,
|
|
2429
|
+
preventRedraw: false,
|
|
2430
|
+
serverData: serverData,
|
|
2431
|
+
toDrop: undefined,
|
|
2432
|
+
topGroup: topGroup
|
|
2433
|
+
};
|
|
2434
|
+
this.dom = {
|
|
2435
|
+
add: $$2('<button/>')
|
|
2436
|
+
.addClass(this.classes.add)
|
|
2437
|
+
.addClass(this.classes.button)
|
|
2438
|
+
.attr('type', 'button'),
|
|
2439
|
+
clear: $$2('<button>×</button>')
|
|
2440
|
+
.addClass(this.classes.button)
|
|
2441
|
+
.addClass(this.classes.clearGroup)
|
|
2442
|
+
.attr('type', 'button'),
|
|
2443
|
+
container: $$2('<div/>')
|
|
2444
|
+
.addClass(this.classes.group),
|
|
2445
|
+
logic: $$2('<button><div/></button>')
|
|
2446
|
+
.addClass(this.classes.logic)
|
|
2447
|
+
.addClass(this.classes.button)
|
|
2448
|
+
.attr('type', 'button'),
|
|
2449
|
+
logicContainer: $$2('<div/>')
|
|
2450
|
+
.addClass(this.classes.logicContainer)
|
|
2451
|
+
};
|
|
2452
|
+
// A reference to the top level group is maintained throughout any subgroups and criteria that may be created
|
|
2453
|
+
if (this.s.topGroup === undefined) {
|
|
2454
|
+
this.s.topGroup = this.dom.container;
|
|
2455
|
+
}
|
|
2456
|
+
this._setup();
|
|
2457
|
+
return this;
|
|
2458
|
+
}
|
|
2459
|
+
/**
|
|
2460
|
+
* Destroys the groups buttons, clears the internal criteria and removes it from the dom
|
|
2461
|
+
*/
|
|
2462
|
+
Group.prototype.destroy = function () {
|
|
2463
|
+
// Turn off listeners
|
|
2464
|
+
this.dom.add.off('.dtsb');
|
|
2465
|
+
this.dom.logic.off('.dtsb');
|
|
2466
|
+
// Trigger event for groups at a higher level to pick up on
|
|
2467
|
+
this.dom.container
|
|
2468
|
+
.trigger('dtsb-destroy')
|
|
2469
|
+
.remove();
|
|
2470
|
+
this.s.criteria = [];
|
|
2471
|
+
};
|
|
2472
|
+
/**
|
|
2473
|
+
* Gets the details required to rebuild the group
|
|
2474
|
+
*/
|
|
2475
|
+
// Eslint upset at empty object but needs to be done
|
|
2476
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
2477
|
+
Group.prototype.getDetails = function (deFormatDates) {
|
|
2478
|
+
if (deFormatDates === void 0) { deFormatDates = false; }
|
|
2479
|
+
if (this.s.criteria.length === 0) {
|
|
2480
|
+
return {};
|
|
2481
|
+
}
|
|
2482
|
+
var details = {
|
|
2483
|
+
criteria: [],
|
|
2484
|
+
logic: this.s.logic
|
|
2485
|
+
};
|
|
2486
|
+
// NOTE here crit could be either a subgroup or a criteria
|
|
2487
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2488
|
+
var crit = _a[_i];
|
|
2489
|
+
details.criteria.push(crit.criteria.getDetails(deFormatDates));
|
|
2490
|
+
}
|
|
2491
|
+
return details;
|
|
2492
|
+
};
|
|
2493
|
+
/**
|
|
2494
|
+
* Getter for the node for the container of the group
|
|
2495
|
+
*
|
|
2496
|
+
* @returns Node for the container of the group
|
|
2497
|
+
*/
|
|
2498
|
+
Group.prototype.getNode = function () {
|
|
2499
|
+
return this.dom.container;
|
|
2500
|
+
};
|
|
2501
|
+
/**
|
|
2502
|
+
* Rebuilds the group based upon the details passed in
|
|
2503
|
+
*
|
|
2504
|
+
* @param loadedDetails the details required to rebuild the group
|
|
2505
|
+
*/
|
|
2506
|
+
Group.prototype.rebuild = function (loadedDetails) {
|
|
2507
|
+
// If no criteria are stored then just return
|
|
2508
|
+
if (loadedDetails.criteria === undefined ||
|
|
2509
|
+
loadedDetails.criteria === null ||
|
|
2510
|
+
Array.isArray(loadedDetails.criteria) && loadedDetails.criteria.length === 0) {
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
this.s.logic = loadedDetails.logic;
|
|
2514
|
+
this.dom.logic.children().first().html(this.s.logic === 'OR'
|
|
2515
|
+
? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)
|
|
2516
|
+
: this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
|
|
2517
|
+
// Add all of the criteria, be it a sub group or a criteria
|
|
2518
|
+
if (Array.isArray(loadedDetails.criteria)) {
|
|
2519
|
+
for (var _i = 0, _a = loadedDetails.criteria; _i < _a.length; _i++) {
|
|
2520
|
+
var crit = _a[_i];
|
|
2521
|
+
if (crit.logic !== undefined) {
|
|
2522
|
+
this._addPrevGroup(crit);
|
|
2523
|
+
}
|
|
2524
|
+
else if (crit.logic === undefined) {
|
|
2525
|
+
this._addPrevCriteria(crit);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
// For all of the criteria children, update the arrows incase they require changing and set the listeners
|
|
2530
|
+
for (var _b = 0, _c = this.s.criteria; _b < _c.length; _b++) {
|
|
2531
|
+
var crit = _c[_b];
|
|
2532
|
+
if (crit.criteria instanceof Criteria) {
|
|
2533
|
+
crit.criteria.updateArrows(this.s.criteria.length > 1);
|
|
2534
|
+
this._setCriteriaListeners(crit.criteria);
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
};
|
|
2538
|
+
/**
|
|
2539
|
+
* Redraws the Contents of the searchBuilder Groups and Criteria
|
|
2540
|
+
*/
|
|
2541
|
+
Group.prototype.redrawContents = function () {
|
|
2542
|
+
if (this.s.preventRedraw) {
|
|
2543
|
+
return;
|
|
2544
|
+
}
|
|
2545
|
+
// Clear the container out and add the basic elements
|
|
2546
|
+
this.dom.container.children().detach();
|
|
2547
|
+
this.dom.container
|
|
2548
|
+
.append(this.dom.logicContainer)
|
|
2549
|
+
.append(this.dom.add);
|
|
2550
|
+
// Sort the criteria by index so that they appear in the correct order
|
|
2551
|
+
this.s.criteria.sort(function (a, b) {
|
|
2552
|
+
if (a.criteria.s.index < b.criteria.s.index) {
|
|
2553
|
+
return -1;
|
|
2554
|
+
}
|
|
2555
|
+
else if (a.criteria.s.index > b.criteria.s.index) {
|
|
2556
|
+
return 1;
|
|
2557
|
+
}
|
|
2558
|
+
return 0;
|
|
2559
|
+
});
|
|
2560
|
+
this.setListeners();
|
|
2561
|
+
for (var i = 0; i < this.s.criteria.length; i++) {
|
|
2562
|
+
var crit = this.s.criteria[i].criteria;
|
|
2563
|
+
if (crit instanceof Criteria) {
|
|
2564
|
+
// Reset the index to the new value
|
|
2565
|
+
this.s.criteria[i].index = i;
|
|
2566
|
+
this.s.criteria[i].criteria.s.index = i;
|
|
2567
|
+
// Add to the group
|
|
2568
|
+
this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);
|
|
2569
|
+
// Set listeners for various points
|
|
2570
|
+
this._setCriteriaListeners(crit);
|
|
2571
|
+
this.s.criteria[i].criteria.s.preventRedraw = this.s.preventRedraw;
|
|
2572
|
+
this.s.criteria[i].criteria.rebuild(this.s.criteria[i].criteria.getDetails());
|
|
2573
|
+
this.s.criteria[i].criteria.s.preventRedraw = false;
|
|
2574
|
+
}
|
|
2575
|
+
else if (crit instanceof Group && crit.s.criteria.length > 0) {
|
|
2576
|
+
// Reset the index to the new value
|
|
2577
|
+
this.s.criteria[i].index = i;
|
|
2578
|
+
this.s.criteria[i].criteria.s.index = i;
|
|
2579
|
+
// Add the sub group to the group
|
|
2580
|
+
this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);
|
|
2581
|
+
// Redraw the contents of the group
|
|
2582
|
+
crit.s.preventRedraw = this.s.preventRedraw;
|
|
2583
|
+
crit.redrawContents();
|
|
2584
|
+
crit.s.preventRedraw = false;
|
|
2585
|
+
this._setGroupListeners(crit);
|
|
2586
|
+
}
|
|
2587
|
+
else {
|
|
2588
|
+
// The group is empty so remove it
|
|
2589
|
+
this.s.criteria.splice(i, 1);
|
|
2590
|
+
i--;
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
this.setupLogic();
|
|
2594
|
+
};
|
|
2595
|
+
/**
|
|
2596
|
+
* Resizes the logic button only rather than the entire dom.
|
|
2597
|
+
*/
|
|
2598
|
+
Group.prototype.redrawLogic = function () {
|
|
2599
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2600
|
+
var crit = _a[_i];
|
|
2601
|
+
if (crit.criteria instanceof Group) {
|
|
2602
|
+
crit.criteria.redrawLogic();
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
this.setupLogic();
|
|
2606
|
+
};
|
|
2607
|
+
/**
|
|
2608
|
+
* Search method, checking the row data against the criteria in the group
|
|
2609
|
+
*
|
|
2610
|
+
* @param rowData The row data to be compared
|
|
2611
|
+
* @returns boolean The result of the search
|
|
2612
|
+
*/
|
|
2613
|
+
Group.prototype.search = function (rowData, rowIdx) {
|
|
2614
|
+
if (this.s.logic === 'AND') {
|
|
2615
|
+
return this._andSearch(rowData, rowIdx);
|
|
2616
|
+
}
|
|
2617
|
+
else if (this.s.logic === 'OR') {
|
|
2618
|
+
return this._orSearch(rowData, rowIdx);
|
|
2619
|
+
}
|
|
2620
|
+
return true;
|
|
2621
|
+
};
|
|
2622
|
+
/**
|
|
2623
|
+
* Locates the groups logic button to the correct location on the page
|
|
2624
|
+
*/
|
|
2625
|
+
Group.prototype.setupLogic = function () {
|
|
2626
|
+
// Remove logic button
|
|
2627
|
+
this.dom.logicContainer.remove();
|
|
2628
|
+
this.dom.clear.remove();
|
|
2629
|
+
// If there are no criteria in the group then keep the logic removed and return
|
|
2630
|
+
if (this.s.criteria.length < 1) {
|
|
2631
|
+
if (!this.s.isChild) {
|
|
2632
|
+
this.dom.container.trigger('dtsb-destroy');
|
|
2633
|
+
// Set criteria left margin
|
|
2634
|
+
this.dom.container.css('margin-left', 0);
|
|
2635
|
+
}
|
|
2636
|
+
return;
|
|
2637
|
+
}
|
|
2638
|
+
this.dom.clear.height('0px');
|
|
2639
|
+
this.dom.logicContainer.append(this.dom.clear);
|
|
2640
|
+
// Prepend logic button
|
|
2641
|
+
this.dom.container.prepend(this.dom.logicContainer);
|
|
2642
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2643
|
+
var crit = _a[_i];
|
|
2644
|
+
if (crit.criteria instanceof Criteria) {
|
|
2645
|
+
crit.criteria.setupButtons();
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
// Set width, take 2 for the border
|
|
2649
|
+
var height = this.dom.container.outerHeight() - 1;
|
|
2650
|
+
this.dom.logicContainer.width(height);
|
|
2651
|
+
this._setLogicListener();
|
|
2652
|
+
// Set criteria left margin
|
|
2653
|
+
this.dom.container.css('margin-left', this.dom.logicContainer.outerHeight(true));
|
|
2654
|
+
var logicOffset = this.dom.logicContainer.offset();
|
|
2655
|
+
// Set horizontal alignment
|
|
2656
|
+
var currentLeft = logicOffset.left;
|
|
2657
|
+
var groupLeft = this.dom.container.offset().left;
|
|
2658
|
+
var shuffleLeft = currentLeft - groupLeft;
|
|
2659
|
+
var newPos = currentLeft - shuffleLeft - this.dom.logicContainer.outerHeight(true);
|
|
2660
|
+
this.dom.logicContainer.offset({ left: newPos });
|
|
2661
|
+
// Set vertical alignment
|
|
2662
|
+
var firstCrit = this.dom.logicContainer.next();
|
|
2663
|
+
var currentTop = logicOffset.top;
|
|
2664
|
+
var firstTop = $$2(firstCrit).offset().top;
|
|
2665
|
+
var shuffleTop = currentTop - firstTop;
|
|
2666
|
+
var newTop = currentTop - shuffleTop;
|
|
2667
|
+
this.dom.logicContainer.offset({ top: newTop });
|
|
2668
|
+
this.dom.clear.outerHeight(this.dom.logicContainer.height());
|
|
2669
|
+
this._setClearListener();
|
|
2670
|
+
};
|
|
2671
|
+
/**
|
|
2672
|
+
* Sets listeners on the groups elements
|
|
2673
|
+
*/
|
|
2674
|
+
Group.prototype.setListeners = function () {
|
|
2675
|
+
var _this = this;
|
|
2676
|
+
this.dom.add.unbind('click');
|
|
2677
|
+
this.dom.add.on('click.dtsb', function () {
|
|
2678
|
+
// If this is the parent group then the logic button has not been added yet
|
|
2679
|
+
if (!_this.s.isChild) {
|
|
2680
|
+
_this.dom.container.prepend(_this.dom.logicContainer);
|
|
2681
|
+
}
|
|
2682
|
+
_this.addCriteria();
|
|
2683
|
+
_this.dom.container.trigger('dtsb-add');
|
|
2684
|
+
_this.s.dt.state.save();
|
|
2685
|
+
return false;
|
|
2686
|
+
});
|
|
2687
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2688
|
+
var crit = _a[_i];
|
|
2689
|
+
crit.criteria.setListeners();
|
|
2690
|
+
}
|
|
2691
|
+
this._setClearListener();
|
|
2692
|
+
this._setLogicListener();
|
|
2693
|
+
};
|
|
2694
|
+
/**
|
|
2695
|
+
* Adds a criteria to the group
|
|
2696
|
+
*
|
|
2697
|
+
* @param crit Instance of Criteria to be added to the group
|
|
2698
|
+
*/
|
|
2699
|
+
Group.prototype.addCriteria = function (crit) {
|
|
2700
|
+
if (crit === void 0) { crit = null; }
|
|
2701
|
+
var index = crit === null ? this.s.criteria.length : crit.s.index;
|
|
2702
|
+
var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth, this.s.serverData);
|
|
2703
|
+
// If a Criteria has been passed in then set the values to continue that
|
|
2704
|
+
if (crit !== null) {
|
|
2705
|
+
criteria.c = crit.c;
|
|
2706
|
+
criteria.s = crit.s;
|
|
2707
|
+
criteria.s.depth = this.s.depth;
|
|
2708
|
+
criteria.classes = crit.classes;
|
|
2709
|
+
}
|
|
2710
|
+
criteria.populate();
|
|
2711
|
+
var inserted = false;
|
|
2712
|
+
for (var i = 0; i < this.s.criteria.length; i++) {
|
|
2713
|
+
if (i === 0 && this.s.criteria[i].criteria.s.index > criteria.s.index) {
|
|
2714
|
+
// Add the node for the criteria at the start of the group
|
|
2715
|
+
criteria.getNode().insertBefore(this.s.criteria[i].criteria.dom.container);
|
|
2716
|
+
inserted = true;
|
|
2717
|
+
}
|
|
2718
|
+
else if (i < this.s.criteria.length - 1 &&
|
|
2719
|
+
this.s.criteria[i].criteria.s.index < criteria.s.index &&
|
|
2720
|
+
this.s.criteria[i + 1].criteria.s.index > criteria.s.index) {
|
|
2721
|
+
// Add the node for the criteria in the correct location
|
|
2722
|
+
criteria.getNode().insertAfter(this.s.criteria[i].criteria.dom.container);
|
|
2723
|
+
inserted = true;
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
if (!inserted) {
|
|
2727
|
+
criteria.getNode().insertBefore(this.dom.add);
|
|
2728
|
+
}
|
|
2729
|
+
// Add the details for this criteria to the array
|
|
2730
|
+
this.s.criteria.push({
|
|
2731
|
+
criteria: criteria,
|
|
2732
|
+
index: index
|
|
2733
|
+
});
|
|
2734
|
+
this.s.criteria = this.s.criteria.sort(function (a, b) { return a.criteria.s.index - b.criteria.s.index; });
|
|
2735
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2736
|
+
var opt = _a[_i];
|
|
2737
|
+
if (opt.criteria instanceof Criteria) {
|
|
2738
|
+
opt.criteria.updateArrows(this.s.criteria.length > 1);
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
this._setCriteriaListeners(criteria);
|
|
2742
|
+
criteria.setListeners();
|
|
2743
|
+
this.setupLogic();
|
|
2744
|
+
};
|
|
2745
|
+
/**
|
|
2746
|
+
* Checks the group to see if it has any filled criteria
|
|
2747
|
+
*/
|
|
2748
|
+
Group.prototype.checkFilled = function () {
|
|
2749
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2750
|
+
var crit = _a[_i];
|
|
2751
|
+
if (crit.criteria instanceof Criteria && crit.criteria.s.filled ||
|
|
2752
|
+
crit.criteria instanceof Group && crit.criteria.checkFilled()) {
|
|
2753
|
+
return true;
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
return false;
|
|
2757
|
+
};
|
|
2758
|
+
/**
|
|
2759
|
+
* Gets the count for the number of criteria in this group and any sub groups
|
|
2760
|
+
*/
|
|
2761
|
+
Group.prototype.count = function () {
|
|
2762
|
+
var count = 0;
|
|
2763
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2764
|
+
var crit = _a[_i];
|
|
2765
|
+
if (crit.criteria instanceof Group) {
|
|
2766
|
+
count += crit.criteria.count();
|
|
2767
|
+
}
|
|
2768
|
+
else {
|
|
2769
|
+
count++;
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
return count;
|
|
2773
|
+
};
|
|
2774
|
+
/**
|
|
2775
|
+
* Rebuilds a sub group that previously existed
|
|
2776
|
+
*
|
|
2777
|
+
* @param loadedGroup The details of a group within this group
|
|
2778
|
+
*/
|
|
2779
|
+
Group.prototype._addPrevGroup = function (loadedGroup) {
|
|
2780
|
+
var idx = this.s.criteria.length;
|
|
2781
|
+
var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1, this.s.serverData);
|
|
2782
|
+
// Add the new group to the criteria array
|
|
2783
|
+
this.s.criteria.push({
|
|
2784
|
+
criteria: group,
|
|
2785
|
+
index: idx,
|
|
2786
|
+
logic: group.s.logic
|
|
2787
|
+
});
|
|
2788
|
+
// Rebuild it with the previous conditions for that group
|
|
2789
|
+
group.rebuild(loadedGroup);
|
|
2790
|
+
this.s.criteria[idx].criteria = group;
|
|
2791
|
+
this.s.topGroup.trigger('dtsb-redrawContents');
|
|
2792
|
+
this._setGroupListeners(group);
|
|
2793
|
+
};
|
|
2794
|
+
/**
|
|
2795
|
+
* Rebuilds a criteria of this group that previously existed
|
|
2796
|
+
*
|
|
2797
|
+
* @param loadedCriteria The details of a criteria within the group
|
|
2798
|
+
*/
|
|
2799
|
+
Group.prototype._addPrevCriteria = function (loadedCriteria) {
|
|
2800
|
+
var idx = this.s.criteria.length;
|
|
2801
|
+
var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth, this.s.serverData);
|
|
2802
|
+
criteria.populate();
|
|
2803
|
+
// Add the new criteria to the criteria array
|
|
2804
|
+
this.s.criteria.push({
|
|
2805
|
+
criteria: criteria,
|
|
2806
|
+
index: idx
|
|
2807
|
+
});
|
|
2808
|
+
// Rebuild it with the previous conditions for that criteria
|
|
2809
|
+
criteria.s.preventRedraw = this.s.preventRedraw;
|
|
2810
|
+
criteria.rebuild(loadedCriteria);
|
|
2811
|
+
criteria.s.preventRedraw = false;
|
|
2812
|
+
this.s.criteria[idx].criteria = criteria;
|
|
2813
|
+
if (!this.s.preventRedraw) {
|
|
2814
|
+
this.s.topGroup.trigger('dtsb-redrawContents');
|
|
2815
|
+
}
|
|
2816
|
+
};
|
|
2817
|
+
/**
|
|
2818
|
+
* Checks And the criteria using AND logic
|
|
2819
|
+
*
|
|
2820
|
+
* @param rowData The row data to be checked against the search criteria
|
|
2821
|
+
* @returns boolean The result of the AND search
|
|
2822
|
+
*/
|
|
2823
|
+
Group.prototype._andSearch = function (rowData, rowIdx) {
|
|
2824
|
+
// If there are no criteria then return true for this group
|
|
2825
|
+
if (this.s.criteria.length === 0) {
|
|
2826
|
+
return true;
|
|
2827
|
+
}
|
|
2828
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2829
|
+
var crit = _a[_i];
|
|
2830
|
+
// If the criteria is not complete then skip it
|
|
2831
|
+
if (crit.criteria instanceof Criteria && !crit.criteria.s.filled) {
|
|
2832
|
+
continue;
|
|
2833
|
+
}
|
|
2834
|
+
// Otherwise if a single one fails return false
|
|
2835
|
+
else if (!crit.criteria.search(rowData, rowIdx)) {
|
|
2836
|
+
return false;
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
// If we get to here then everything has passed, so return true for the group
|
|
2840
|
+
return true;
|
|
2841
|
+
};
|
|
2842
|
+
/**
|
|
2843
|
+
* Checks And the criteria using OR logic
|
|
2844
|
+
*
|
|
2845
|
+
* @param rowData The row data to be checked against the search criteria
|
|
2846
|
+
* @returns boolean The result of the OR search
|
|
2847
|
+
*/
|
|
2848
|
+
Group.prototype._orSearch = function (rowData, rowIdx) {
|
|
2849
|
+
// If there are no criteria in the group then return true
|
|
2850
|
+
if (this.s.criteria.length === 0) {
|
|
2851
|
+
return true;
|
|
2852
|
+
}
|
|
2853
|
+
// This will check to make sure that at least one criteria in the group is complete
|
|
2854
|
+
var filledfound = false;
|
|
2855
|
+
for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
|
|
2856
|
+
var crit = _a[_i];
|
|
2857
|
+
if (crit.criteria instanceof Criteria && crit.criteria.s.filled) {
|
|
2858
|
+
// A completed criteria has been found so set the flag
|
|
2859
|
+
filledfound = true;
|
|
2860
|
+
// If the search passes then return true
|
|
2861
|
+
if (crit.criteria.search(rowData, rowIdx)) {
|
|
2862
|
+
return true;
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
else if (crit.criteria instanceof Group && crit.criteria.checkFilled()) {
|
|
2866
|
+
filledfound = true;
|
|
2867
|
+
if (crit.criteria.search(rowData, rowIdx)) {
|
|
2868
|
+
return true;
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
// If we get here we need to return the inverse of filledfound,
|
|
2873
|
+
// as if any have been found and we are here then none have passed
|
|
2874
|
+
return !filledfound;
|
|
2875
|
+
};
|
|
2876
|
+
/**
|
|
2877
|
+
* Removes a criteria from the group
|
|
2878
|
+
*
|
|
2879
|
+
* @param criteria The criteria instance to be removed
|
|
2880
|
+
*/
|
|
2881
|
+
Group.prototype._removeCriteria = function (criteria, group) {
|
|
2882
|
+
if (group === void 0) { group = false; }
|
|
2883
|
+
// If removing a criteria and there is only then then just destroy the group
|
|
2884
|
+
if (this.s.criteria.length <= 1 && this.s.isChild) {
|
|
2885
|
+
this.destroy();
|
|
2886
|
+
}
|
|
2887
|
+
else {
|
|
2888
|
+
// Otherwise splice the given criteria out and redo the indexes
|
|
2889
|
+
var last = void 0;
|
|
2890
|
+
for (var i = 0; i < this.s.criteria.length; i++) {
|
|
2891
|
+
if (this.s.criteria[i].index === criteria.s.index &&
|
|
2892
|
+
(!group || this.s.criteria[i].criteria instanceof Group)) {
|
|
2893
|
+
last = i;
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
// We want to remove the last element with the desired index, as its replacement will be inserted before it
|
|
2897
|
+
if (last !== undefined) {
|
|
2898
|
+
this.s.criteria.splice(last, 1);
|
|
2899
|
+
}
|
|
2900
|
+
for (var i = 0; i < this.s.criteria.length; i++) {
|
|
2901
|
+
this.s.criteria[i].index = i;
|
|
2902
|
+
this.s.criteria[i].criteria.s.index = i;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
};
|
|
2906
|
+
/**
|
|
2907
|
+
* Sets the listeners in group for a criteria
|
|
2908
|
+
*
|
|
2909
|
+
* @param criteria The criteria for the listeners to be set on
|
|
2910
|
+
*/
|
|
2911
|
+
Group.prototype._setCriteriaListeners = function (criteria) {
|
|
2912
|
+
var _this = this;
|
|
2913
|
+
criteria.dom["delete"]
|
|
2914
|
+
.unbind('click')
|
|
2915
|
+
.on('click.dtsb', function () {
|
|
2916
|
+
_this._removeCriteria(criteria);
|
|
2917
|
+
criteria.dom.container.remove();
|
|
2918
|
+
for (var _i = 0, _a = _this.s.criteria; _i < _a.length; _i++) {
|
|
2919
|
+
var crit = _a[_i];
|
|
2920
|
+
if (crit.criteria instanceof Criteria) {
|
|
2921
|
+
crit.criteria.updateArrows(_this.s.criteria.length > 1);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
criteria.destroy();
|
|
2925
|
+
_this.s.dt.draw();
|
|
2926
|
+
_this.s.topGroup.trigger('dtsb-redrawContents');
|
|
2927
|
+
return false;
|
|
2928
|
+
});
|
|
2929
|
+
criteria.dom.right
|
|
2930
|
+
.unbind('click')
|
|
2931
|
+
.on('click.dtsb', function () {
|
|
2932
|
+
var idx = criteria.s.index;
|
|
2933
|
+
var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1, _this.s.serverData);
|
|
2934
|
+
// Add the criteria that is to be moved to the new group
|
|
2935
|
+
group.addCriteria(criteria);
|
|
2936
|
+
// Update the details in the current groups criteria array
|
|
2937
|
+
_this.s.criteria[idx].criteria = group;
|
|
2938
|
+
_this.s.criteria[idx].logic = 'AND';
|
|
2939
|
+
_this.s.topGroup.trigger('dtsb-redrawContents');
|
|
2940
|
+
_this._setGroupListeners(group);
|
|
2941
|
+
return false;
|
|
2942
|
+
});
|
|
2943
|
+
criteria.dom.left
|
|
2944
|
+
.unbind('click')
|
|
2945
|
+
.on('click.dtsb', function () {
|
|
2946
|
+
_this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, undefined, _this.s.serverData);
|
|
2947
|
+
_this.s.toDrop.s = criteria.s;
|
|
2948
|
+
_this.s.toDrop.c = criteria.c;
|
|
2949
|
+
_this.s.toDrop.classes = criteria.classes;
|
|
2950
|
+
_this.s.toDrop.populate();
|
|
2951
|
+
// The dropCriteria event mutates the reference to the index so need to store it
|
|
2952
|
+
var index = _this.s.toDrop.s.index;
|
|
2953
|
+
_this.dom.container.trigger('dtsb-dropCriteria');
|
|
2954
|
+
criteria.s.index = index;
|
|
2955
|
+
_this._removeCriteria(criteria);
|
|
2956
|
+
// By tracking the top level group we can directly trigger a redraw on it,
|
|
2957
|
+
// bubbling is also possible, but that is slow with deep levelled groups
|
|
2958
|
+
_this.s.topGroup.trigger('dtsb-redrawContents');
|
|
2959
|
+
_this.s.dt.draw();
|
|
2960
|
+
return false;
|
|
2961
|
+
});
|
|
2962
|
+
};
|
|
2963
|
+
/**
|
|
2964
|
+
* Set's the listeners for the group clear button
|
|
2965
|
+
*/
|
|
2966
|
+
Group.prototype._setClearListener = function () {
|
|
2967
|
+
var _this = this;
|
|
2968
|
+
this.dom.clear
|
|
2969
|
+
.unbind('click')
|
|
2970
|
+
.on('click.dtsb', function () {
|
|
2971
|
+
if (!_this.s.isChild) {
|
|
2972
|
+
_this.dom.container.trigger('dtsb-clearContents');
|
|
2973
|
+
return false;
|
|
2974
|
+
}
|
|
2975
|
+
_this.destroy();
|
|
2976
|
+
_this.s.topGroup.trigger('dtsb-redrawContents');
|
|
2977
|
+
return false;
|
|
2978
|
+
});
|
|
2979
|
+
};
|
|
2980
|
+
/**
|
|
2981
|
+
* Sets listeners for sub groups of this group
|
|
2982
|
+
*
|
|
2983
|
+
* @param group The sub group that the listeners are to be set on
|
|
2984
|
+
*/
|
|
2985
|
+
Group.prototype._setGroupListeners = function (group) {
|
|
2986
|
+
var _this = this;
|
|
2987
|
+
// Set listeners for the new group
|
|
2988
|
+
group.dom.add
|
|
2989
|
+
.unbind('click')
|
|
2990
|
+
.on('click.dtsb', function () {
|
|
2991
|
+
_this.setupLogic();
|
|
2992
|
+
_this.dom.container.trigger('dtsb-add');
|
|
2993
|
+
return false;
|
|
2994
|
+
});
|
|
2995
|
+
group.dom.container
|
|
2996
|
+
.unbind('dtsb-add')
|
|
2997
|
+
.on('dtsb-add.dtsb', function () {
|
|
2998
|
+
_this.setupLogic();
|
|
2999
|
+
_this.dom.container.trigger('dtsb-add');
|
|
3000
|
+
return false;
|
|
3001
|
+
});
|
|
3002
|
+
group.dom.container
|
|
3003
|
+
.unbind('dtsb-destroy')
|
|
3004
|
+
.on('dtsb-destroy.dtsb', function () {
|
|
3005
|
+
_this._removeCriteria(group, true);
|
|
3006
|
+
group.dom.container.remove();
|
|
3007
|
+
_this.setupLogic();
|
|
3008
|
+
return false;
|
|
3009
|
+
});
|
|
3010
|
+
group.dom.container
|
|
3011
|
+
.unbind('dtsb-dropCriteria')
|
|
3012
|
+
.on('dtsb-dropCriteria.dtsb', function () {
|
|
3013
|
+
var toDrop = group.s.toDrop;
|
|
3014
|
+
toDrop.s.index = group.s.index;
|
|
3015
|
+
toDrop.updateArrows(_this.s.criteria.length > 1);
|
|
3016
|
+
_this.addCriteria(toDrop);
|
|
3017
|
+
return false;
|
|
3018
|
+
});
|
|
3019
|
+
group.setListeners();
|
|
3020
|
+
};
|
|
3021
|
+
/**
|
|
3022
|
+
* Sets up the Group instance, setting listeners and appending elements
|
|
3023
|
+
*/
|
|
3024
|
+
Group.prototype._setup = function () {
|
|
3025
|
+
this.setListeners();
|
|
3026
|
+
this.dom.add.html(this.s.dt.i18n('searchBuilder.add', this.c.i18n.add));
|
|
3027
|
+
this.dom.logic.children().first().html(this.c.logic === 'OR'
|
|
3028
|
+
? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)
|
|
3029
|
+
: this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
|
|
3030
|
+
this.s.logic = this.c.logic === 'OR' ? 'OR' : 'AND';
|
|
3031
|
+
if (this.c.greyscale) {
|
|
3032
|
+
this.dom.logic.addClass(this.classes.greyscale);
|
|
3033
|
+
}
|
|
3034
|
+
this.dom.logicContainer.append(this.dom.logic).append(this.dom.clear);
|
|
3035
|
+
// Only append the logic button immediately if this is a sub group,
|
|
3036
|
+
// otherwise it will be prepended later when adding a criteria
|
|
3037
|
+
if (this.s.isChild) {
|
|
3038
|
+
this.dom.container.append(this.dom.logicContainer);
|
|
3039
|
+
}
|
|
3040
|
+
this.dom.container.append(this.dom.add);
|
|
3041
|
+
};
|
|
3042
|
+
/**
|
|
3043
|
+
* Sets the listener for the logic button
|
|
3044
|
+
*/
|
|
3045
|
+
Group.prototype._setLogicListener = function () {
|
|
3046
|
+
var _this = this;
|
|
3047
|
+
this.dom.logic
|
|
3048
|
+
.unbind('click')
|
|
3049
|
+
.on('click.dtsb', function () {
|
|
3050
|
+
_this._toggleLogic();
|
|
3051
|
+
_this.s.dt.draw();
|
|
3052
|
+
for (var _i = 0, _a = _this.s.criteria; _i < _a.length; _i++) {
|
|
3053
|
+
var crit = _a[_i];
|
|
3054
|
+
crit.criteria.setListeners();
|
|
3055
|
+
}
|
|
3056
|
+
});
|
|
3057
|
+
};
|
|
3058
|
+
/**
|
|
3059
|
+
* Toggles the logic for the group
|
|
3060
|
+
*/
|
|
3061
|
+
Group.prototype._toggleLogic = function () {
|
|
3062
|
+
if (this.s.logic === 'OR') {
|
|
3063
|
+
this.s.logic = 'AND';
|
|
3064
|
+
this.dom.logic.children().first().html(this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
|
|
3065
|
+
}
|
|
3066
|
+
else if (this.s.logic === 'AND') {
|
|
3067
|
+
this.s.logic = 'OR';
|
|
3068
|
+
this.dom.logic.children().first().html(this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr));
|
|
3069
|
+
}
|
|
3070
|
+
};
|
|
3071
|
+
Group.version = '1.1.0';
|
|
3072
|
+
Group.classes = {
|
|
3073
|
+
add: 'dtsb-add',
|
|
3074
|
+
button: 'dtsb-button',
|
|
3075
|
+
clearGroup: 'dtsb-clearGroup',
|
|
3076
|
+
greyscale: 'dtsb-greyscale',
|
|
3077
|
+
group: 'dtsb-group',
|
|
3078
|
+
inputButton: 'dtsb-iptbtn',
|
|
3079
|
+
logic: 'dtsb-logic',
|
|
3080
|
+
logicContainer: 'dtsb-logicContainer'
|
|
3081
|
+
};
|
|
3082
|
+
Group.defaults = {
|
|
3083
|
+
columns: true,
|
|
3084
|
+
conditions: {
|
|
3085
|
+
'date': Criteria.dateConditions,
|
|
3086
|
+
'html': Criteria.stringConditions,
|
|
3087
|
+
'html-num': Criteria.numConditions,
|
|
3088
|
+
'html-num-fmt': Criteria.numFmtConditions,
|
|
3089
|
+
'luxon': Criteria.luxonDateConditions,
|
|
3090
|
+
'moment': Criteria.momentDateConditions,
|
|
3091
|
+
'num': Criteria.numConditions,
|
|
3092
|
+
'num-fmt': Criteria.numFmtConditions,
|
|
3093
|
+
'string': Criteria.stringConditions
|
|
3094
|
+
},
|
|
3095
|
+
depthLimit: false,
|
|
3096
|
+
enterSearch: false,
|
|
3097
|
+
filterChanged: undefined,
|
|
3098
|
+
greyscale: false,
|
|
3099
|
+
i18n: {
|
|
3100
|
+
add: 'Add Condition',
|
|
3101
|
+
button: {
|
|
3102
|
+
0: 'Search Builder',
|
|
3103
|
+
_: 'Search Builder (%d)'
|
|
3104
|
+
},
|
|
3105
|
+
clearAll: 'Clear All',
|
|
3106
|
+
condition: 'Condition',
|
|
3107
|
+
data: 'Data',
|
|
3108
|
+
"delete": '×',
|
|
3109
|
+
deleteTitle: 'Delete filtering rule',
|
|
3110
|
+
left: '<',
|
|
3111
|
+
leftTitle: 'Outdent criteria',
|
|
3112
|
+
logicAnd: 'And',
|
|
3113
|
+
logicOr: 'Or',
|
|
3114
|
+
right: '>',
|
|
3115
|
+
rightTitle: 'Indent criteria',
|
|
3116
|
+
title: {
|
|
3117
|
+
0: 'Custom Search Builder',
|
|
3118
|
+
_: 'Custom Search Builder (%d)'
|
|
3119
|
+
},
|
|
3120
|
+
value: 'Value',
|
|
3121
|
+
valueJoiner: 'and'
|
|
3122
|
+
},
|
|
3123
|
+
logic: 'AND',
|
|
3124
|
+
orthogonal: {
|
|
3125
|
+
display: 'display',
|
|
3126
|
+
search: 'filter'
|
|
3127
|
+
},
|
|
3128
|
+
preDefined: false
|
|
3129
|
+
};
|
|
3130
|
+
return Group;
|
|
3131
|
+
}());
|
|
3132
|
+
|
|
3133
|
+
var $$1;
|
|
3134
|
+
var dataTable$1;
|
|
3135
|
+
/**
|
|
3136
|
+
* Sets the value of jQuery for use in the file
|
|
3137
|
+
*
|
|
3138
|
+
* @param jq the instance of jQuery to be set
|
|
3139
|
+
*/
|
|
3140
|
+
function setJQuery(jq) {
|
|
3141
|
+
$$1 = jq;
|
|
3142
|
+
dataTable$1 = jq.fn.DataTable;
|
|
3143
|
+
}
|
|
3144
|
+
/**
|
|
3145
|
+
* SearchBuilder class for DataTables.
|
|
3146
|
+
* Allows for complex search queries to be constructed and implemented on a DataTable
|
|
3147
|
+
*/
|
|
3148
|
+
var SearchBuilder = /** @class */ (function () {
|
|
3149
|
+
function SearchBuilder(builderSettings, opts) {
|
|
3150
|
+
var _this = this;
|
|
3151
|
+
// Check that the required version of DataTables is included
|
|
3152
|
+
if (!dataTable$1 || !dataTable$1.versionCheck || !dataTable$1.versionCheck('1.10.0')) {
|
|
3153
|
+
throw new Error('SearchBuilder requires DataTables 1.10 or newer');
|
|
3154
|
+
}
|
|
3155
|
+
var table = new dataTable$1.Api(builderSettings);
|
|
3156
|
+
this.classes = $$1.extend(true, {}, SearchBuilder.classes);
|
|
3157
|
+
// Get options from user
|
|
3158
|
+
this.c = $$1.extend(true, {}, SearchBuilder.defaults, opts);
|
|
3159
|
+
this.dom = {
|
|
3160
|
+
clearAll: $$1('<button type="button">' + table.i18n('searchBuilder.clearAll', this.c.i18n.clearAll) + '</button>')
|
|
3161
|
+
.addClass(this.classes.clearAll)
|
|
3162
|
+
.addClass(this.classes.button)
|
|
3163
|
+
.attr('type', 'button'),
|
|
3164
|
+
container: $$1('<div/>')
|
|
3165
|
+
.addClass(this.classes.container),
|
|
3166
|
+
title: $$1('<div/>')
|
|
3167
|
+
.addClass(this.classes.title),
|
|
3168
|
+
titleRow: $$1('<div/>')
|
|
3169
|
+
.addClass(this.classes.titleRow),
|
|
3170
|
+
topGroup: undefined
|
|
3171
|
+
};
|
|
3172
|
+
this.s = {
|
|
3173
|
+
dt: table,
|
|
3174
|
+
opts: opts,
|
|
3175
|
+
search: undefined,
|
|
3176
|
+
serverData: undefined,
|
|
3177
|
+
topGroup: undefined
|
|
3178
|
+
};
|
|
3179
|
+
// If searchbuilder is already defined for this table then return
|
|
3180
|
+
if (table.settings()[0]._searchBuilder !== undefined) {
|
|
3181
|
+
return;
|
|
3182
|
+
}
|
|
3183
|
+
table.settings()[0]._searchBuilder = this;
|
|
3184
|
+
// If using SSP we want to include the previous state in the very first server call
|
|
3185
|
+
if (this.s.dt.page.info().serverSide) {
|
|
3186
|
+
this.s.dt.on('preXhr.dtsb', function (e, settings, data) {
|
|
3187
|
+
var loadedState = _this.s.dt.state.loaded();
|
|
3188
|
+
if (loadedState && loadedState.searchBuilder) {
|
|
3189
|
+
data.searchBuilder = _this._collapseArray(loadedState.searchBuilder);
|
|
3190
|
+
}
|
|
3191
|
+
});
|
|
3192
|
+
this.s.dt.on('xhr.dtsb', function (e, settings, json) {
|
|
3193
|
+
if (json && json.searchBuilder && json.searchBuilder.options) {
|
|
3194
|
+
_this.s.serverData = json.searchBuilder.options;
|
|
3195
|
+
}
|
|
3196
|
+
});
|
|
3197
|
+
}
|
|
3198
|
+
// Run the remaining setup when the table is initialised
|
|
3199
|
+
if (this.s.dt.settings()[0]._bInitComplete) {
|
|
3200
|
+
this._setUp();
|
|
3201
|
+
}
|
|
3202
|
+
else {
|
|
3203
|
+
table.one('init.dt', function () {
|
|
3204
|
+
_this._setUp();
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3207
|
+
return this;
|
|
3208
|
+
}
|
|
3209
|
+
/**
|
|
3210
|
+
* Gets the details required to rebuild the SearchBuilder as it currently is
|
|
3211
|
+
*/
|
|
3212
|
+
// eslint upset at empty object but that is what it is
|
|
3213
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
3214
|
+
SearchBuilder.prototype.getDetails = function (deFormatDates) {
|
|
3215
|
+
if (deFormatDates === void 0) { deFormatDates = false; }
|
|
3216
|
+
return this.s.topGroup.getDetails(deFormatDates);
|
|
3217
|
+
};
|
|
3218
|
+
/**
|
|
3219
|
+
* Getter for the node of the container for the searchBuilder
|
|
3220
|
+
*
|
|
3221
|
+
* @returns JQuery<HTMLElement> the node of the container
|
|
3222
|
+
*/
|
|
3223
|
+
SearchBuilder.prototype.getNode = function () {
|
|
3224
|
+
return this.dom.container;
|
|
3225
|
+
};
|
|
3226
|
+
/**
|
|
3227
|
+
* Rebuilds the SearchBuilder to a state that is provided
|
|
3228
|
+
*
|
|
3229
|
+
* @param details The details required to perform a rebuild
|
|
3230
|
+
*/
|
|
3231
|
+
SearchBuilder.prototype.rebuild = function (details) {
|
|
3232
|
+
this.dom.clearAll.click();
|
|
3233
|
+
// If there are no details to rebuild then return
|
|
3234
|
+
if (details === undefined || details === null) {
|
|
3235
|
+
return this;
|
|
3236
|
+
}
|
|
3237
|
+
this.s.topGroup.s.preventRedraw = true;
|
|
3238
|
+
this.s.topGroup.rebuild(details);
|
|
3239
|
+
this.s.topGroup.s.preventRedraw = false;
|
|
3240
|
+
this._checkClear();
|
|
3241
|
+
this._updateTitle(this.s.topGroup.count());
|
|
3242
|
+
this.s.topGroup.redrawContents();
|
|
3243
|
+
this.s.dt.draw(false);
|
|
3244
|
+
this.s.topGroup.setListeners();
|
|
3245
|
+
return this;
|
|
3246
|
+
};
|
|
3247
|
+
/**
|
|
3248
|
+
* Applies the defaults to preDefined criteria
|
|
3249
|
+
*
|
|
3250
|
+
* @param preDef the array of criteria to be processed.
|
|
3251
|
+
*/
|
|
3252
|
+
SearchBuilder.prototype._applyPreDefDefaults = function (preDef) {
|
|
3253
|
+
var _this = this;
|
|
3254
|
+
if (preDef.criteria !== undefined && preDef.logic === undefined) {
|
|
3255
|
+
preDef.logic = 'AND';
|
|
3256
|
+
}
|
|
3257
|
+
var _loop_1 = function (crit) {
|
|
3258
|
+
// Apply the defaults to any further criteria
|
|
3259
|
+
if (crit.criteria !== undefined) {
|
|
3260
|
+
crit = this_1._applyPreDefDefaults(crit);
|
|
3261
|
+
}
|
|
3262
|
+
else {
|
|
3263
|
+
this_1.s.dt.columns().every(function (index) {
|
|
3264
|
+
if (_this.s.dt.settings()[0].aoColumns[index].sTitle === crit.data) {
|
|
3265
|
+
crit.dataIdx = index;
|
|
3266
|
+
}
|
|
3267
|
+
});
|
|
3268
|
+
}
|
|
3269
|
+
};
|
|
3270
|
+
var this_1 = this;
|
|
3271
|
+
for (var _i = 0, _a = preDef.criteria; _i < _a.length; _i++) {
|
|
3272
|
+
var crit = _a[_i];
|
|
3273
|
+
_loop_1(crit);
|
|
3274
|
+
}
|
|
3275
|
+
return preDef;
|
|
3276
|
+
};
|
|
3277
|
+
/**
|
|
3278
|
+
* Set's up the SearchBuilder
|
|
3279
|
+
*/
|
|
3280
|
+
SearchBuilder.prototype._setUp = function (loadState) {
|
|
3281
|
+
var _this = this;
|
|
3282
|
+
if (loadState === void 0) { loadState = true; }
|
|
3283
|
+
// Register an Api method for getting the column type
|
|
3284
|
+
$$1.fn.DataTable.Api.registerPlural('columns().type()', 'column().type()', function () {
|
|
3285
|
+
return this.iterator('column', function (settings, column) {
|
|
3286
|
+
return settings.aoColumns[column].sType;
|
|
3287
|
+
}, 1);
|
|
3288
|
+
});
|
|
3289
|
+
// Check that DateTime is included, If not need to check if it could be used
|
|
3290
|
+
// eslint-disable-next-line no-extra-parens
|
|
3291
|
+
if (!dataTable$1.DateTime) {
|
|
3292
|
+
var types = this.s.dt.columns().type().toArray();
|
|
3293
|
+
if (types === undefined || types.includes(undefined) || types.includes(null)) {
|
|
3294
|
+
types = [];
|
|
3295
|
+
for (var _i = 0, _a = this.s.dt.settings()[0].aoColumns; _i < _a.length; _i++) {
|
|
3296
|
+
var colInit = _a[_i];
|
|
3297
|
+
types.push(colInit.searchBuilderType !== undefined ? colInit.searchBuilderType : colInit.sType);
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
var columnIdxs = this.s.dt.columns().toArray();
|
|
3301
|
+
// If the types are not yet set then draw to see if they can be retrieved then
|
|
3302
|
+
if (types === undefined || types.includes(undefined) || types.includes(null)) {
|
|
3303
|
+
$$1.fn.dataTable.ext.oApi._fnColumnTypes(this.s.dt.settings()[0]);
|
|
3304
|
+
types = this.s.dt.columns().type().toArray();
|
|
3305
|
+
}
|
|
3306
|
+
for (var i = 0; i < columnIdxs[0].length; i++) {
|
|
3307
|
+
var column = columnIdxs[0][i];
|
|
3308
|
+
var type = types[column];
|
|
3309
|
+
if (
|
|
3310
|
+
// Check if this column can be filtered
|
|
3311
|
+
(this.c.columns === true ||
|
|
3312
|
+
Array.isArray(this.c.columns) &&
|
|
3313
|
+
this.c.columns.includes(i)) &&
|
|
3314
|
+
// Check if the type is one of the restricted types
|
|
3315
|
+
(type.includes('date') ||
|
|
3316
|
+
type.includes('moment') ||
|
|
3317
|
+
type.includes('luxon'))) {
|
|
3318
|
+
alert('SearchBuilder Requires DateTime when used with dates.');
|
|
3319
|
+
throw new Error('SearchBuilder requires DateTime');
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
this.s.topGroup = new Group(this.s.dt, this.c, undefined, undefined, undefined, undefined, this.s.serverData);
|
|
3324
|
+
this._setClearListener();
|
|
3325
|
+
this.s.dt.on('stateSaveParams.dtsb', function (e, settings, data) {
|
|
3326
|
+
data.searchBuilder = _this.getDetails();
|
|
3327
|
+
if (!data.scroller) {
|
|
3328
|
+
data.page = _this.s.dt.page();
|
|
3329
|
+
}
|
|
3330
|
+
else {
|
|
3331
|
+
data.start = _this.s.dt.state().start;
|
|
3332
|
+
}
|
|
3333
|
+
});
|
|
3334
|
+
this.s.dt.on('stateLoadParams.dtsb', function (e, settings, data) {
|
|
3335
|
+
_this.rebuild(data.searchBuilder);
|
|
3336
|
+
});
|
|
3337
|
+
this._build();
|
|
3338
|
+
this.s.dt.on('preXhr.dtsb', function (e, settings, data) {
|
|
3339
|
+
if (_this.s.dt.page.info().serverSide) {
|
|
3340
|
+
data.searchBuilder = _this._collapseArray(_this.getDetails(true));
|
|
3341
|
+
}
|
|
3342
|
+
});
|
|
3343
|
+
this.s.dt.on('column-reorder', function () {
|
|
3344
|
+
_this.rebuild(_this.getDetails());
|
|
3345
|
+
});
|
|
3346
|
+
if (loadState) {
|
|
3347
|
+
var loadedState = this.s.dt.state.loaded();
|
|
3348
|
+
// If the loaded State is not null rebuild based on it for statesave
|
|
3349
|
+
if (loadedState !== null && loadedState.searchBuilder !== undefined) {
|
|
3350
|
+
this.s.topGroup.rebuild(loadedState.searchBuilder);
|
|
3351
|
+
this.s.topGroup.dom.container.trigger('dtsb-redrawContents');
|
|
3352
|
+
// If using SSP we want to restrict the amount of server calls that take place
|
|
3353
|
+
// and this information will already have been processed
|
|
3354
|
+
if (!this.s.dt.page.info().serverSide) {
|
|
3355
|
+
if (loadedState.page) {
|
|
3356
|
+
this.s.dt.page(loadedState.page).draw('page');
|
|
3357
|
+
}
|
|
3358
|
+
else if (this.s.dt.scroller && loadedState.scroller) {
|
|
3359
|
+
this.s.dt.scroller().scrollToRow(loadedState.scroller.topRow);
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
this.s.topGroup.setListeners();
|
|
3363
|
+
}
|
|
3364
|
+
// Otherwise load any predefined options
|
|
3365
|
+
else if (this.c.preDefined !== false) {
|
|
3366
|
+
this.c.preDefined = this._applyPreDefDefaults(this.c.preDefined);
|
|
3367
|
+
this.rebuild(this.c.preDefined);
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
this._setEmptyListener();
|
|
3371
|
+
this.s.dt.state.save();
|
|
3372
|
+
};
|
|
3373
|
+
SearchBuilder.prototype._collapseArray = function (criteria) {
|
|
3374
|
+
if (criteria.logic === undefined) {
|
|
3375
|
+
if (criteria.value !== undefined) {
|
|
3376
|
+
criteria.value.sort(function (a, b) {
|
|
3377
|
+
if (!isNaN(+a)) {
|
|
3378
|
+
a = +a;
|
|
3379
|
+
b = +b;
|
|
3380
|
+
}
|
|
3381
|
+
if (a < b) {
|
|
3382
|
+
return -1;
|
|
3383
|
+
}
|
|
3384
|
+
else if (b < a) {
|
|
3385
|
+
return 1;
|
|
3386
|
+
}
|
|
3387
|
+
else {
|
|
3388
|
+
return 0;
|
|
3389
|
+
}
|
|
3390
|
+
});
|
|
3391
|
+
criteria.value1 = criteria.value[0];
|
|
3392
|
+
criteria.value2 = criteria.value[1];
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
else {
|
|
3396
|
+
for (var i = 0; i < criteria.criteria.length; i++) {
|
|
3397
|
+
criteria.criteria[i] = this._collapseArray(criteria.criteria[i]);
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
return criteria;
|
|
3401
|
+
};
|
|
3402
|
+
/**
|
|
3403
|
+
* Updates the title of the SearchBuilder
|
|
3404
|
+
*
|
|
3405
|
+
* @param count the number of filters in the SearchBuilder
|
|
3406
|
+
*/
|
|
3407
|
+
SearchBuilder.prototype._updateTitle = function (count) {
|
|
3408
|
+
this.dom.title.html(this.s.dt.i18n('searchBuilder.title', this.c.i18n.title, count));
|
|
3409
|
+
};
|
|
3410
|
+
/**
|
|
3411
|
+
* Builds all of the dom elements together
|
|
3412
|
+
*/
|
|
3413
|
+
SearchBuilder.prototype._build = function () {
|
|
3414
|
+
var _this = this;
|
|
3415
|
+
// Empty and setup the container
|
|
3416
|
+
this.dom.clearAll.remove();
|
|
3417
|
+
this.dom.container.empty();
|
|
3418
|
+
var count = this.s.topGroup.count();
|
|
3419
|
+
this._updateTitle(count);
|
|
3420
|
+
this.dom.titleRow.append(this.dom.title);
|
|
3421
|
+
this.dom.container.append(this.dom.titleRow);
|
|
3422
|
+
this.dom.topGroup = this.s.topGroup.getNode();
|
|
3423
|
+
this.dom.container.append(this.dom.topGroup);
|
|
3424
|
+
this._setRedrawListener();
|
|
3425
|
+
var tableNode = this.s.dt.table(0).node();
|
|
3426
|
+
if (!$$1.fn.dataTable.ext.search.includes(this.s.search)) {
|
|
3427
|
+
// Custom search function for SearchBuilder
|
|
3428
|
+
this.s.search = function (settings, searchData, dataIndex) {
|
|
3429
|
+
if (settings.nTable !== tableNode) {
|
|
3430
|
+
return true;
|
|
3431
|
+
}
|
|
3432
|
+
return _this.s.topGroup.search(searchData, dataIndex);
|
|
3433
|
+
};
|
|
3434
|
+
// Add SearchBuilder search function to the dataTables search array
|
|
3435
|
+
$$1.fn.dataTable.ext.search.push(this.s.search);
|
|
3436
|
+
}
|
|
3437
|
+
this.s.dt.on('destroy.dtsb', function () {
|
|
3438
|
+
_this.dom.container.remove();
|
|
3439
|
+
_this.dom.clearAll.remove();
|
|
3440
|
+
var searchIdx = $$1.fn.dataTable.ext.search.indexOf(_this.s.search);
|
|
3441
|
+
while (searchIdx !== -1) {
|
|
3442
|
+
$$1.fn.dataTable.ext.search.splice(searchIdx, 1);
|
|
3443
|
+
searchIdx = $$1.fn.dataTable.ext.search.indexOf(_this.s.search);
|
|
3444
|
+
}
|
|
3445
|
+
_this.s.dt.off('.dtsb');
|
|
3446
|
+
$$1(_this.s.dt.table().node()).off('.dtsb');
|
|
3447
|
+
});
|
|
3448
|
+
};
|
|
3449
|
+
/**
|
|
3450
|
+
* Checks if the clearAll button should be added or not
|
|
3451
|
+
*/
|
|
3452
|
+
SearchBuilder.prototype._checkClear = function () {
|
|
3453
|
+
if (this.s.topGroup.s.criteria.length > 0) {
|
|
3454
|
+
this.dom.clearAll.insertAfter(this.dom.title);
|
|
3455
|
+
this._setClearListener();
|
|
3456
|
+
}
|
|
3457
|
+
else {
|
|
3458
|
+
this.dom.clearAll.remove();
|
|
3459
|
+
}
|
|
3460
|
+
};
|
|
3461
|
+
/**
|
|
3462
|
+
* Update the count in the title/button
|
|
3463
|
+
*
|
|
3464
|
+
* @param count Number of filters applied
|
|
3465
|
+
*/
|
|
3466
|
+
SearchBuilder.prototype._filterChanged = function (count) {
|
|
3467
|
+
var fn = this.c.filterChanged;
|
|
3468
|
+
if (typeof fn === 'function') {
|
|
3469
|
+
fn(count, this.s.dt.i18n('searchBuilder.button', this.c.i18n.button, count));
|
|
3470
|
+
}
|
|
3471
|
+
};
|
|
3472
|
+
/**
|
|
3473
|
+
* Set the listener for the clear button
|
|
3474
|
+
*/
|
|
3475
|
+
SearchBuilder.prototype._setClearListener = function () {
|
|
3476
|
+
var _this = this;
|
|
3477
|
+
this.dom.clearAll.unbind('click');
|
|
3478
|
+
this.dom.clearAll.on('click.dtsb', function () {
|
|
3479
|
+
_this.s.topGroup = new Group(_this.s.dt, _this.c, undefined, undefined, undefined, undefined, _this.s.serverData);
|
|
3480
|
+
_this._build();
|
|
3481
|
+
_this.s.dt.draw();
|
|
3482
|
+
_this.s.topGroup.setListeners();
|
|
3483
|
+
_this.dom.clearAll.remove();
|
|
3484
|
+
_this._setEmptyListener();
|
|
3485
|
+
_this._filterChanged(0);
|
|
3486
|
+
return false;
|
|
3487
|
+
});
|
|
3488
|
+
};
|
|
3489
|
+
/**
|
|
3490
|
+
* Set the listener for the Redraw event
|
|
3491
|
+
*/
|
|
3492
|
+
SearchBuilder.prototype._setRedrawListener = function () {
|
|
3493
|
+
var _this = this;
|
|
3494
|
+
this.s.topGroup.dom.container.unbind('dtsb-redrawContents');
|
|
3495
|
+
this.s.topGroup.dom.container.on('dtsb-redrawContents.dtsb', function () {
|
|
3496
|
+
_this._checkClear();
|
|
3497
|
+
_this.s.topGroup.redrawContents();
|
|
3498
|
+
_this.s.topGroup.setupLogic();
|
|
3499
|
+
_this._setEmptyListener();
|
|
3500
|
+
var count = _this.s.topGroup.count();
|
|
3501
|
+
_this._updateTitle(count);
|
|
3502
|
+
_this._filterChanged(count);
|
|
3503
|
+
// If using SSP we want to restrict the amount of server calls that take place
|
|
3504
|
+
// and this information will already have been processed
|
|
3505
|
+
if (!_this.s.dt.page.info().serverSide) {
|
|
3506
|
+
_this.s.dt.draw();
|
|
3507
|
+
}
|
|
3508
|
+
_this.s.dt.state.save();
|
|
3509
|
+
});
|
|
3510
|
+
this.s.topGroup.dom.container.unbind('dtsb-redrawContents-noDraw');
|
|
3511
|
+
this.s.topGroup.dom.container.on('dtsb-redrawContents-noDraw.dtsb', function () {
|
|
3512
|
+
_this._checkClear();
|
|
3513
|
+
_this.s.topGroup.s.preventRedraw = true;
|
|
3514
|
+
_this.s.topGroup.redrawContents();
|
|
3515
|
+
_this.s.topGroup.s.preventRedraw = false;
|
|
3516
|
+
_this.s.topGroup.setupLogic();
|
|
3517
|
+
_this._setEmptyListener();
|
|
3518
|
+
var count = _this.s.topGroup.count();
|
|
3519
|
+
_this._updateTitle(count);
|
|
3520
|
+
_this._filterChanged(count);
|
|
3521
|
+
});
|
|
3522
|
+
this.s.topGroup.dom.container.unbind('dtsb-redrawLogic');
|
|
3523
|
+
this.s.topGroup.dom.container.on('dtsb-redrawLogic.dtsb', function () {
|
|
3524
|
+
_this.s.topGroup.redrawLogic();
|
|
3525
|
+
var count = _this.s.topGroup.count();
|
|
3526
|
+
_this._updateTitle(count);
|
|
3527
|
+
_this._filterChanged(count);
|
|
3528
|
+
});
|
|
3529
|
+
this.s.topGroup.dom.container.unbind('dtsb-add');
|
|
3530
|
+
this.s.topGroup.dom.container.on('dtsb-add.dtsb', function () {
|
|
3531
|
+
var count = _this.s.topGroup.count();
|
|
3532
|
+
_this._updateTitle(count);
|
|
3533
|
+
_this._filterChanged(count);
|
|
3534
|
+
});
|
|
3535
|
+
this.s.dt.on('postEdit.dtsb postCreate.dtsb postRemove.dtsb', function () {
|
|
3536
|
+
_this.s.topGroup.redrawContents();
|
|
3537
|
+
});
|
|
3538
|
+
this.s.topGroup.dom.container.unbind('dtsb-clearContents');
|
|
3539
|
+
this.s.topGroup.dom.container.on('dtsb-clearContents.dtsb', function () {
|
|
3540
|
+
_this._setUp(false);
|
|
3541
|
+
_this._filterChanged(0);
|
|
3542
|
+
_this.s.dt.draw();
|
|
3543
|
+
});
|
|
3544
|
+
};
|
|
3545
|
+
/**
|
|
3546
|
+
* Sets listeners to check whether clearAll should be added or removed
|
|
3547
|
+
*/
|
|
3548
|
+
SearchBuilder.prototype._setEmptyListener = function () {
|
|
3549
|
+
var _this = this;
|
|
3550
|
+
this.s.topGroup.dom.add.on('click.dtsb', function () {
|
|
3551
|
+
_this._checkClear();
|
|
3552
|
+
});
|
|
3553
|
+
this.s.topGroup.dom.container.on('dtsb-destroy.dtsb', function () {
|
|
3554
|
+
_this.dom.clearAll.remove();
|
|
3555
|
+
});
|
|
3556
|
+
};
|
|
3557
|
+
SearchBuilder.version = '1.4.2';
|
|
3558
|
+
SearchBuilder.classes = {
|
|
3559
|
+
button: 'dtsb-button',
|
|
3560
|
+
clearAll: 'dtsb-clearAll',
|
|
3561
|
+
container: 'dtsb-searchBuilder',
|
|
3562
|
+
inputButton: 'dtsb-iptbtn',
|
|
3563
|
+
title: 'dtsb-title',
|
|
3564
|
+
titleRow: 'dtsb-titleRow'
|
|
3565
|
+
};
|
|
3566
|
+
SearchBuilder.defaults = {
|
|
3567
|
+
columns: true,
|
|
3568
|
+
conditions: {
|
|
3569
|
+
'date': Criteria.dateConditions,
|
|
3570
|
+
'html': Criteria.stringConditions,
|
|
3571
|
+
'html-num': Criteria.numConditions,
|
|
3572
|
+
'html-num-fmt': Criteria.numFmtConditions,
|
|
3573
|
+
'luxon': Criteria.luxonDateConditions,
|
|
3574
|
+
'moment': Criteria.momentDateConditions,
|
|
3575
|
+
'num': Criteria.numConditions,
|
|
3576
|
+
'num-fmt': Criteria.numFmtConditions,
|
|
3577
|
+
'string': Criteria.stringConditions
|
|
3578
|
+
},
|
|
3579
|
+
depthLimit: false,
|
|
3580
|
+
enterSearch: false,
|
|
3581
|
+
filterChanged: undefined,
|
|
3582
|
+
greyscale: false,
|
|
3583
|
+
i18n: {
|
|
3584
|
+
add: 'Add Condition',
|
|
3585
|
+
button: {
|
|
3586
|
+
0: 'Search Builder',
|
|
3587
|
+
_: 'Search Builder (%d)'
|
|
3588
|
+
},
|
|
3589
|
+
clearAll: 'Clear All',
|
|
3590
|
+
condition: 'Condition',
|
|
3591
|
+
conditions: {
|
|
3592
|
+
array: {
|
|
3593
|
+
contains: 'Contains',
|
|
3594
|
+
empty: 'Empty',
|
|
3595
|
+
equals: 'Equals',
|
|
3596
|
+
not: 'Not',
|
|
3597
|
+
notEmpty: 'Not Empty',
|
|
3598
|
+
without: 'Without'
|
|
3599
|
+
},
|
|
3600
|
+
date: {
|
|
3601
|
+
after: 'After',
|
|
3602
|
+
before: 'Before',
|
|
3603
|
+
between: 'Between',
|
|
3604
|
+
empty: 'Empty',
|
|
3605
|
+
equals: 'Equals',
|
|
3606
|
+
not: 'Not',
|
|
3607
|
+
notBetween: 'Not Between',
|
|
3608
|
+
notEmpty: 'Not Empty'
|
|
3609
|
+
},
|
|
3610
|
+
// eslint-disable-next-line id-blacklist
|
|
3611
|
+
number: {
|
|
3612
|
+
between: 'Between',
|
|
3613
|
+
empty: 'Empty',
|
|
3614
|
+
equals: 'Equals',
|
|
3615
|
+
gt: 'Greater Than',
|
|
3616
|
+
gte: 'Greater Than Equal To',
|
|
3617
|
+
lt: 'Less Than',
|
|
3618
|
+
lte: 'Less Than Equal To',
|
|
3619
|
+
not: 'Not',
|
|
3620
|
+
notBetween: 'Not Between',
|
|
3621
|
+
notEmpty: 'Not Empty'
|
|
3622
|
+
},
|
|
3623
|
+
// eslint-disable-next-line id-blacklist
|
|
3624
|
+
string: {
|
|
3625
|
+
contains: 'Contains',
|
|
3626
|
+
empty: 'Empty',
|
|
3627
|
+
endsWith: 'Ends With',
|
|
3628
|
+
equals: 'Equals',
|
|
3629
|
+
not: 'Not',
|
|
3630
|
+
notContains: 'Does Not Contain',
|
|
3631
|
+
notEmpty: 'Not Empty',
|
|
3632
|
+
notEndsWith: 'Does Not End With',
|
|
3633
|
+
notStartsWith: 'Does Not Start With',
|
|
3634
|
+
startsWith: 'Starts With'
|
|
3635
|
+
}
|
|
3636
|
+
},
|
|
3637
|
+
data: 'Data',
|
|
3638
|
+
"delete": '×',
|
|
3639
|
+
deleteTitle: 'Delete filtering rule',
|
|
3640
|
+
left: '<',
|
|
3641
|
+
leftTitle: 'Outdent criteria',
|
|
3642
|
+
logicAnd: 'And',
|
|
3643
|
+
logicOr: 'Or',
|
|
3644
|
+
right: '>',
|
|
3645
|
+
rightTitle: 'Indent criteria',
|
|
3646
|
+
title: {
|
|
3647
|
+
0: 'Custom Search Builder',
|
|
3648
|
+
_: 'Custom Search Builder (%d)'
|
|
3649
|
+
},
|
|
3650
|
+
value: 'Value',
|
|
3651
|
+
valueJoiner: 'and'
|
|
3652
|
+
},
|
|
3653
|
+
logic: 'AND',
|
|
3654
|
+
orthogonal: {
|
|
3655
|
+
display: 'display',
|
|
3656
|
+
search: 'filter'
|
|
3657
|
+
},
|
|
3658
|
+
preDefined: false
|
|
3659
|
+
};
|
|
3660
|
+
return SearchBuilder;
|
|
3661
|
+
}());
|
|
3662
|
+
|
|
3663
|
+
/*! SearchBuilder 1.4.2
|
|
3664
|
+
* ©SpryMedia Ltd - datatables.net/license/mit
|
|
3665
|
+
*/
|
|
3666
|
+
setJQuery($);
|
|
3667
|
+
setJQuery$1($);
|
|
3668
|
+
setJQuery$2($);
|
|
3669
|
+
var dataTable = $.fn.dataTable;
|
|
3670
|
+
// eslint-disable-next-line no-extra-parens
|
|
3671
|
+
DataTable.SearchBuilder = SearchBuilder;
|
|
3672
|
+
// eslint-disable-next-line no-extra-parens
|
|
3673
|
+
dataTable.SearchBuilder = SearchBuilder;
|
|
3674
|
+
// eslint-disable-next-line no-extra-parens
|
|
3675
|
+
DataTable.Group = Group;
|
|
3676
|
+
// eslint-disable-next-line no-extra-parens
|
|
3677
|
+
dataTable.Group = Group;
|
|
3678
|
+
// eslint-disable-next-line no-extra-parens
|
|
3679
|
+
DataTable.Criteria = Criteria;
|
|
3680
|
+
// eslint-disable-next-line no-extra-parens
|
|
3681
|
+
dataTable.Criteria = Criteria;
|
|
3682
|
+
// eslint-disable-next-line no-extra-parens
|
|
3683
|
+
var apiRegister = DataTable.Api.register;
|
|
3684
|
+
// Set up object for plugins
|
|
3685
|
+
DataTable.ext.searchBuilder = {
|
|
3686
|
+
conditions: {}
|
|
3687
|
+
};
|
|
3688
|
+
DataTable.ext.buttons.searchBuilder = {
|
|
3689
|
+
action: function (e, dt, node, config) {
|
|
3690
|
+
this.popover(config._searchBuilder.getNode(), {
|
|
3691
|
+
align: 'container',
|
|
3692
|
+
span: 'container'
|
|
3693
|
+
});
|
|
3694
|
+
var topGroup = config._searchBuilder.s.topGroup;
|
|
3695
|
+
// Need to redraw the contents to calculate the correct positions for the elements
|
|
3696
|
+
if (topGroup !== undefined) {
|
|
3697
|
+
topGroup.dom.container.trigger('dtsb-redrawContents-noDraw');
|
|
3698
|
+
}
|
|
3699
|
+
if (topGroup.s.criteria.length === 0) {
|
|
3700
|
+
$('.' + $.fn.dataTable.Group.classes.add.replace(/ /g, '.')).click();
|
|
3701
|
+
}
|
|
3702
|
+
},
|
|
3703
|
+
config: {},
|
|
3704
|
+
init: function (dt, node, config) {
|
|
3705
|
+
var sb = new DataTable.SearchBuilder(dt, $.extend({
|
|
3706
|
+
filterChanged: function (count, text) {
|
|
3707
|
+
dt.button(node).text(text);
|
|
3708
|
+
}
|
|
3709
|
+
}, config.config));
|
|
3710
|
+
dt.button(node).text(config.text || dt.i18n('searchBuilder.button', sb.c.i18n.button, 0));
|
|
3711
|
+
config._searchBuilder = sb;
|
|
3712
|
+
},
|
|
3713
|
+
text: null
|
|
3714
|
+
};
|
|
3715
|
+
apiRegister('searchBuilder.getDetails()', function (deFormatDates) {
|
|
3716
|
+
if (deFormatDates === void 0) { deFormatDates = false; }
|
|
3717
|
+
var ctx = this.context[0];
|
|
3718
|
+
// If SearchBuilder has not been initialised on this instance then return
|
|
3719
|
+
return ctx._searchBuilder ?
|
|
3720
|
+
ctx._searchBuilder.getDetails(deFormatDates) :
|
|
3721
|
+
null;
|
|
3722
|
+
});
|
|
3723
|
+
apiRegister('searchBuilder.rebuild()', function (details) {
|
|
3724
|
+
var ctx = this.context[0];
|
|
3725
|
+
// If SearchBuilder has not been initialised on this instance then return
|
|
3726
|
+
if (ctx._searchBuilder === undefined) {
|
|
3727
|
+
return null;
|
|
3728
|
+
}
|
|
3729
|
+
ctx._searchBuilder.rebuild(details);
|
|
3730
|
+
return this;
|
|
3731
|
+
});
|
|
3732
|
+
apiRegister('searchBuilder.container()', function () {
|
|
3733
|
+
var ctx = this.context[0];
|
|
3734
|
+
// If SearchBuilder has not been initialised on this instance then return
|
|
3735
|
+
return ctx._searchBuilder ?
|
|
3736
|
+
ctx._searchBuilder.getNode() :
|
|
3737
|
+
null;
|
|
3738
|
+
});
|
|
3739
|
+
/**
|
|
3740
|
+
* Init function for SearchBuilder
|
|
3741
|
+
*
|
|
3742
|
+
* @param settings the settings to be applied
|
|
3743
|
+
* @param options the options for SearchBuilder
|
|
3744
|
+
* @returns JQUERY<HTMLElement> Returns the node of the SearchBuilder
|
|
3745
|
+
*/
|
|
3746
|
+
function _init(settings, options) {
|
|
3747
|
+
var api = new DataTable.Api(settings);
|
|
3748
|
+
var opts = options
|
|
3749
|
+
? options
|
|
3750
|
+
: api.init().searchBuilder || DataTable.defaults.searchBuilder;
|
|
3751
|
+
var searchBuilder = new SearchBuilder(api, opts);
|
|
3752
|
+
var node = searchBuilder.getNode();
|
|
3753
|
+
return node;
|
|
3754
|
+
}
|
|
3755
|
+
// Attach a listener to the document which listens for DataTables initialisation
|
|
3756
|
+
// events so we can automatically initialise
|
|
3757
|
+
$(document).on('preInit.dt.dtsp', function (e, settings) {
|
|
3758
|
+
if (e.namespace !== 'dt') {
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
if (settings.oInit.searchBuilder ||
|
|
3762
|
+
DataTable.defaults.searchBuilder) {
|
|
3763
|
+
if (!settings._searchBuilder) {
|
|
3764
|
+
_init(settings);
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
// DataTables `dom` feature option
|
|
3769
|
+
DataTable.ext.feature.push({
|
|
3770
|
+
cFeature: 'Q',
|
|
3771
|
+
fnInit: _init
|
|
3772
|
+
});
|
|
3773
|
+
// DataTables 2 layout feature
|
|
3774
|
+
if (DataTable.ext.features) {
|
|
3775
|
+
DataTable.ext.features.register('searchBuilder', _init);
|
|
3776
|
+
}
|
|
3777
|
+
|
|
3778
|
+
}());
|
|
3779
|
+
|
|
3780
|
+
|
|
3781
|
+
export default DataTable;
|