@refinitiv-ui/efx-grid 6.0.40 → 6.0.42
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/column-selection-dialog/lib/column-selection-dialog.d.ts +2 -1
- package/lib/column-selection-dialog/lib/column-selection-dialog.js +23 -7
- package/lib/core/dist/core.js +846 -881
- package/lib/core/dist/core.min.js +1 -1
- package/lib/core/es6/grid/Core.d.ts +4 -0
- package/lib/core/es6/grid/Core.js +91 -27
- package/lib/core/es6/grid/plugins/SortableTitlePlugin.d.ts +3 -2
- package/lib/core/es6/grid/plugins/SortableTitlePlugin.js +26 -26
- package/lib/core/es6/grid/util/util.js +25 -9
- package/lib/grid/index.js +1 -1
- package/lib/rt-grid/dist/rt-grid.js +2253 -1755
- package/lib/rt-grid/dist/rt-grid.min.js +1 -1
- package/lib/rt-grid/es6/Grid.d.ts +22 -0
- package/lib/rt-grid/es6/Grid.js +146 -11
- package/lib/rt-grid/es6/RowDefinition.d.ts +2 -2
- package/lib/rt-grid/es6/RowDefinition.js +37 -18
- package/lib/tr-grid-column-grouping/es6/ColumnGrouping.d.ts +4 -0
- package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +60 -59
- package/lib/tr-grid-column-stack/es6/ColumnStack.d.ts +9 -3
- package/lib/tr-grid-column-stack/es6/ColumnStack.js +290 -364
- package/lib/tr-grid-util/es6/CellPainter.d.ts +2 -1
- package/lib/tr-grid-util/es6/CellPainter.js +6 -4
- package/lib/tr-grid-util/es6/DateTime.js +3 -3
- package/lib/tr-grid-util/es6/ExpressionParser.d.ts +10 -0
- package/lib/tr-grid-util/es6/ExpressionParser.js +366 -0
- package/lib/tr-grid-util/es6/FilterBuilder.d.ts +10 -6
- package/lib/tr-grid-util/es6/FilterBuilder.js +264 -234
- package/lib/tr-grid-util/es6/FilterOperators.d.ts +3 -1
- package/lib/tr-grid-util/es6/FilterOperators.js +51 -2
- package/lib/tr-grid-util/es6/GridPlugin.js +1 -1
- package/lib/tr-grid-util/es6/Util.d.ts +0 -3
- package/lib/tr-grid-util/es6/Util.js +0 -53
- package/lib/tr-grid-util/es6/formula/Formula.js +3 -3
- package/lib/types/es6/ColumnDragging.d.ts +51 -0
- package/lib/types/es6/ColumnGrouping.d.ts +4 -0
- package/lib/types/es6/ColumnStack.d.ts +9 -3
- package/lib/types/es6/Core/grid/Core.d.ts +4 -0
- package/lib/types/es6/Core/grid/plugins/SortableTitlePlugin.d.ts +3 -2
- package/lib/types/es6/ExtensionOptions.d.ts +2 -0
- package/lib/types/es6/Extensions.d.ts +3 -1
- package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +2 -2
- package/lib/types/es6/index.d.ts +1 -0
- package/lib/versions.json +4 -4
- package/package.json +1 -1
@@ -1,11 +1,13 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { FilterOperators } from "./FilterOperators.js";
|
1
|
+
import { FilterOperators, OperatorFunctions } from "./FilterOperators.js";
|
2
|
+
import { ExpressionParser } from "./ExpressionParser.js";
|
4
3
|
|
5
4
|
/** @typedef {Object} FilterBuilder~Options
|
6
|
-
* @property {string} field
|
7
|
-
* @property {Function=} formatter
|
8
|
-
* @property {string=} formattedField
|
5
|
+
* @property {(string|null)=} field=null
|
6
|
+
* @property {Function=} formatter=null
|
7
|
+
* @property {string=} formattedField=""
|
8
|
+
* @property {boolean=} useUTCTime=false A flag used for selecting time between local time and UTC time from the given input in a filter condition. This flag does not apply to Date objects stored in a grid
|
9
|
+
* @property {Function=} rawDataAccessor=null
|
10
|
+
* @property {Function=} formattedDataAccessor=null
|
9
11
|
*/
|
10
12
|
|
11
13
|
/** @typedef {Array} FilterBuilder~Condition
|
@@ -20,7 +22,7 @@ import { FilterOperators } from "./FilterOperators.js";
|
|
20
22
|
*/
|
21
23
|
|
22
24
|
/** @private
|
23
|
-
* @type {Object.<string,
|
25
|
+
* @type {Object.<string, number>}
|
24
26
|
* @const
|
25
27
|
*/
|
26
28
|
var connectorMap = {
|
@@ -33,11 +35,166 @@ var connectorMap = {
|
|
33
35
|
|
34
36
|
/** @private
|
35
37
|
* @function
|
36
|
-
* @param {
|
38
|
+
* @param {*} val
|
39
|
+
* @return {number}
|
40
|
+
*/
|
41
|
+
var convertToNumber = function(val) {
|
42
|
+
if(typeof val === "number") {
|
43
|
+
return val;
|
44
|
+
}
|
45
|
+
if(val) {
|
46
|
+
// WARNING: spaces (" ") and newline ("\n") characters could be parsed as 0
|
47
|
+
// TODO: Check if we need to use parseFloat instead of Number
|
48
|
+
return Number(val); // Could return NaN. true value will be converted to 1
|
49
|
+
}
|
50
|
+
if(val === false) {
|
51
|
+
return 0;
|
52
|
+
}
|
53
|
+
return NaN; // null, NaN, undefined, empty string
|
54
|
+
};
|
55
|
+
/** @private
|
56
|
+
* @function
|
57
|
+
* @param {*} val
|
37
58
|
* @return {string}
|
38
59
|
*/
|
39
|
-
var
|
40
|
-
|
60
|
+
var convertToString = function(val) {
|
61
|
+
if(typeof val === "string") {
|
62
|
+
return val;
|
63
|
+
}
|
64
|
+
if(val) {
|
65
|
+
return val + "";
|
66
|
+
}
|
67
|
+
if(val === 0) {
|
68
|
+
return "0";
|
69
|
+
}
|
70
|
+
if(val === false) {
|
71
|
+
return "false";
|
72
|
+
}
|
73
|
+
return ""; // null, NaN, undefined
|
74
|
+
};
|
75
|
+
/** Retrieve date part and ignore time part from the Date object
|
76
|
+
* @private
|
77
|
+
* @function
|
78
|
+
* @param {Date} dateObj
|
79
|
+
* @param {boolean=} useUTCTime
|
80
|
+
* @return {number}
|
81
|
+
*/
|
82
|
+
var convertToDateValue = function(dateObj, useUTCTime) {
|
83
|
+
if(dateObj && dateObj.getTime) {
|
84
|
+
if(useUTCTime) {
|
85
|
+
return dateObj.getUTCFullYear() * 10000 + dateObj.getUTCMonth() * 100 + dateObj.getUTCDate();
|
86
|
+
} else {
|
87
|
+
return dateObj.getFullYear() * 10000 + dateObj.getMonth() * 100 + dateObj.getDate();
|
88
|
+
}
|
89
|
+
}
|
90
|
+
return NaN;
|
91
|
+
};
|
92
|
+
/** @private
|
93
|
+
* @function
|
94
|
+
* @param {Object} ctx
|
95
|
+
* @param {Object} rowData
|
96
|
+
* @return {boolean}
|
97
|
+
*/
|
98
|
+
var _filterByConditions = function(ctx, rowData) {
|
99
|
+
var conds = ctx._conds;
|
100
|
+
var condCount = conds ? conds.length : 0;
|
101
|
+
|
102
|
+
if(!condCount) {
|
103
|
+
return true; // There is no filter condition
|
104
|
+
}
|
105
|
+
|
106
|
+
var fieldName = ctx._fieldName;
|
107
|
+
var fmtFieldName = ctx._formattedFieldName;
|
108
|
+
|
109
|
+
var val = rowData[fieldName];
|
110
|
+
if(ctx._rawDataAccessor) {
|
111
|
+
val = ctx._rawDataAccessor(val);
|
112
|
+
}
|
113
|
+
var str, num, dateVal; // intentionally left undefined
|
114
|
+
var finalResult = false;
|
115
|
+
var result = false;
|
116
|
+
for(var i = 0; i < condCount; ++i) {
|
117
|
+
var orConnector = 0;
|
118
|
+
if(i > 0) {
|
119
|
+
orConnector = connectorMap[conds[i - 1].connector];
|
120
|
+
// TODO: AND operator has higher precedence than OR operator
|
121
|
+
if(orConnector) {
|
122
|
+
if(finalResult) {
|
123
|
+
return true; // Since OR operator is performed last, it can basically override everything
|
124
|
+
}
|
125
|
+
} else if(!finalResult) { // And connector
|
126
|
+
continue; // AND operator has to be perfomed before OR operator
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
var cond = conds[i];
|
131
|
+
var opDef = FilterOperators[cond.operatorId];
|
132
|
+
result = false;
|
133
|
+
|
134
|
+
var opType = opDef.type;
|
135
|
+
var opId = opDef.id;
|
136
|
+
var opFunc = OperatorFunctions[opId];
|
137
|
+
if(opType === "blank") {
|
138
|
+
result = opFunc(val);
|
139
|
+
} else if(opType === "number") {
|
140
|
+
if(num == null) {
|
141
|
+
num = convertToNumber(val);
|
142
|
+
}
|
143
|
+
|
144
|
+
result = opFunc(num, cond.value);
|
145
|
+
} else if(opType === "date") {
|
146
|
+
if(dateVal == null) {
|
147
|
+
dateVal = convertToDateValue(val, false); // Even though date is stored as UTC time, we use local time for filtering
|
148
|
+
}
|
149
|
+
|
150
|
+
result = opFunc(dateVal, cond.value);
|
151
|
+
} else { // string type
|
152
|
+
if(str == null) {
|
153
|
+
if(ctx._formattedDataAccessor) {
|
154
|
+
str = ctx._formattedDataAccessor(rowData[fieldName]);
|
155
|
+
} else if(ctx._formatter) {
|
156
|
+
str = ctx._formatter(rowData);
|
157
|
+
} else if(fmtFieldName !== fieldName) {
|
158
|
+
str = rowData[fmtFieldName];
|
159
|
+
if(str == null) {
|
160
|
+
str = val;
|
161
|
+
}
|
162
|
+
} else {
|
163
|
+
str = val;
|
164
|
+
}
|
165
|
+
str = convertToString(str);
|
166
|
+
if(!opDef.caseSensitive) {
|
167
|
+
str = str.toLowerCase();
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
result = opFunc(str, cond.value);
|
172
|
+
}
|
173
|
+
if(i > 0) {
|
174
|
+
if(orConnector) {
|
175
|
+
finalResult = (finalResult || result);
|
176
|
+
} else {
|
177
|
+
finalResult = (finalResult && result);
|
178
|
+
}
|
179
|
+
} else {
|
180
|
+
finalResult = result;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
return finalResult;
|
184
|
+
};
|
185
|
+
/** @private
|
186
|
+
* @function
|
187
|
+
* @param {Object} ctx
|
188
|
+
* @param {Object} rowData
|
189
|
+
* @return {boolean}
|
190
|
+
*/
|
191
|
+
var _filterByObjectMap = function(ctx, rowData) {
|
192
|
+
var val = rowData[ctx._fieldName];
|
193
|
+
if(ctx._rawDataAccessor) {
|
194
|
+
val = ctx._rawDataAccessor(val);
|
195
|
+
}
|
196
|
+
|
197
|
+
return ctx._itemMap[val] ? true : false;
|
41
198
|
};
|
42
199
|
|
43
200
|
/** @private
|
@@ -48,7 +205,7 @@ var toJsConnector = function(str) {
|
|
48
205
|
var conditionToArray = function(cond) {
|
49
206
|
return [
|
50
207
|
cond.operatorId,
|
51
|
-
cond.
|
208
|
+
cond.origValue,
|
52
209
|
cond.connector
|
53
210
|
];
|
54
211
|
};
|
@@ -92,6 +249,10 @@ FilterBuilder.prototype._formattedFieldName = "";
|
|
92
249
|
* @private
|
93
250
|
*/
|
94
251
|
FilterBuilder.prototype._formatter = null;
|
252
|
+
/** @type {boolean}
|
253
|
+
* @private
|
254
|
+
*/
|
255
|
+
FilterBuilder.prototype._useUTCTime = false;
|
95
256
|
/** @type {Function}
|
96
257
|
* @private
|
97
258
|
*/
|
@@ -143,6 +304,19 @@ FilterBuilder.prototype.init = function(options) {
|
|
143
304
|
var field = options["field"];
|
144
305
|
if(field) {
|
145
306
|
this.setFieldDefinition(field, options["formatter"], options["formattedField"]);
|
307
|
+
} else if(field != null) {
|
308
|
+
this.setFieldDefinition("");
|
309
|
+
}
|
310
|
+
|
311
|
+
var useUTCTime = options["useUTCTime"];
|
312
|
+
if(useUTCTime != null) {
|
313
|
+
this._useUTCTime = useUTCTime ? true : false;
|
314
|
+
}
|
315
|
+
|
316
|
+
var rawDataAccessor = options["rawDataAccessor"];
|
317
|
+
var formattedDataAccessor = options["formattedDataAccessor"];
|
318
|
+
if(rawDataAccessor != null || formattedDataAccessor != null) {
|
319
|
+
this.setDataAccessors(rawDataAccessor, formattedDataAccessor);
|
146
320
|
}
|
147
321
|
};
|
148
322
|
|
@@ -152,11 +326,18 @@ FilterBuilder.prototype.init = function(options) {
|
|
152
326
|
* @param {string=} formattedField
|
153
327
|
*/
|
154
328
|
FilterBuilder.prototype.setFieldDefinition = function(fieldName, formatter, formattedField) {
|
155
|
-
this._fieldName = fieldName;
|
156
|
-
this._formattedFieldName = (formattedField) ? formattedField :
|
329
|
+
this._fieldName = fieldName; // Quote/doublequote characters don't need to be escaped as eval has been removed
|
330
|
+
this._formattedFieldName = (formattedField) ? formattedField : this._fieldName + "_FORMATTED";
|
157
331
|
this._formatter = formatter || null;
|
158
332
|
this._conditions.length = 0;
|
159
333
|
};
|
334
|
+
/** Set UTC usage flag. This flag is used for selecting time between local time and UTC time from the given input in a filter condition. This flag does not apply to Date objects stored in a grid
|
335
|
+
* @public
|
336
|
+
* @param {boolean} useUTCTime
|
337
|
+
*/
|
338
|
+
FilterBuilder.prototype.setDefaultUTCUsage = function(useUTCTime) {
|
339
|
+
this._useUTCTime = useUTCTime ? true : false;
|
340
|
+
};
|
160
341
|
/** @public
|
161
342
|
* @param {Function=} rawDataAccessor Raw data getter for custom data type
|
162
343
|
* @param {Function=} formattedDataAccessor Formatted data getter for custom data type. If this is specified, formatter and formattedField will be overriden.
|
@@ -167,33 +348,35 @@ FilterBuilder.prototype.setDataAccessors = function(rawDataAccessor, formattedDa
|
|
167
348
|
};
|
168
349
|
/** @public
|
169
350
|
* @param {string} oper Operator id (e.g., "GT", "CONT", "EQ")
|
170
|
-
* @param {string|number} value
|
351
|
+
* @param {string|number|Date} value If date type operator is specified, this should be accompanied with useUTCTime flag to indicate whether local or UTC time to be used.
|
171
352
|
* @param {string=} connector Possible values are "OR" and "AND"
|
172
|
-
* @param {boolean=} useUTCTime If
|
353
|
+
* @param {boolean=} useUTCTime If the value is not specified, the default setting will be used
|
173
354
|
* @return {boolean} Return true, if the new condition is added
|
174
355
|
*/
|
175
356
|
FilterBuilder.prototype.addCondition = function (oper, value, connector, useUTCTime) {
|
176
|
-
|
177
|
-
var opDef = FilterOperators[
|
357
|
+
var opId = oper ? oper.toUpperCase() : "";
|
358
|
+
var opDef = FilterOperators[opId];
|
178
359
|
if (!opDef) {
|
179
360
|
return false; // Unknown operation
|
180
361
|
}
|
181
362
|
|
182
363
|
if (value === "{}" || value === "{*}") { // ignore operator if the value is BLANK or NON-BLANK
|
183
|
-
|
184
|
-
opDef = FilterOperators[
|
185
|
-
} else if (!value) {
|
364
|
+
opId = (opDef.positive ^ value === "{}") ? "EQ_NBLANK" : "EQ_BLANK";
|
365
|
+
opDef = FilterOperators[opId];
|
366
|
+
} else if (!value && opDef.type !== "blank") {
|
186
367
|
if(value !== 0 && value !== false) {
|
187
368
|
return false; // Invalid comparer value ("", null, undefined, NaN)
|
188
369
|
}
|
189
370
|
}
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
371
|
+
var cond = {
|
372
|
+
operatorId: opId,
|
373
|
+
origValue: value,
|
374
|
+
connector: connector || ""
|
375
|
+
};
|
376
|
+
if(useUTCTime != null) {
|
377
|
+
cond.useUTCTime = useUTCTime;
|
378
|
+
}
|
379
|
+
this._conditions.push(cond);
|
197
380
|
|
198
381
|
return true;
|
199
382
|
};
|
@@ -236,192 +419,65 @@ FilterBuilder.prototype.getConditions = function () {
|
|
236
419
|
* @return {Function} Filter function that takes rowData object
|
237
420
|
*/
|
238
421
|
FilterBuilder.prototype.buildFilter = function() {
|
239
|
-
if (!this._fieldName) {
|
240
|
-
|
241
|
-
if(!len) { return null; }
|
242
|
-
|
243
|
-
var i, opDef;
|
244
|
-
var hasTextOp = 0; // EQ, NEQ, BEGIN, NBEGIN, END, NEND, CONT, NCONT
|
245
|
-
var hasCaseInsensitiveOp = 0; // BEGIN, NBEGIN, END, NEND, CONT, NCONT
|
246
|
-
var hasNumberOp = 0; // GT, GTE, LT, LTE
|
247
|
-
var hasDateOp = 0;
|
248
|
-
// var hasBlankOp = 0; // EQ_BLANK, EQ_NBLANK
|
249
|
-
|
250
|
-
// Collect filter info
|
251
|
-
for (i = 0; i < len; i++) {
|
252
|
-
opDef = FilterOperators[this._conditions[i].operatorId];
|
253
|
-
if(opDef.type === "string") {
|
254
|
-
++hasTextOp;
|
255
|
-
}
|
256
|
-
if(opDef.type === "number") {
|
257
|
-
++hasNumberOp;
|
258
|
-
}
|
259
|
-
if(opDef.type === "date") {
|
260
|
-
++hasDateOp;
|
261
|
-
}
|
262
|
-
if(!opDef.caseSensitive) {
|
263
|
-
++hasCaseInsensitiveOp;
|
264
|
-
}
|
422
|
+
if (!this._fieldName) {
|
423
|
+
return null;
|
265
424
|
}
|
266
|
-
var
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
var contextObj = null;
|
271
|
-
var filterStr = ["var val = rowData['" + escapedFieldName + "'];"];
|
272
|
-
|
273
|
-
if(this._rawDataAccessor) {
|
274
|
-
if(!contextObj) {
|
275
|
-
contextObj = {};
|
276
|
-
}
|
277
|
-
contextObj["rawDataAccessor"] = this._rawDataAccessor;
|
278
|
-
filterStr.push("val = this.rawDataAccessor(val);");
|
425
|
+
var condCount = this._conditions.length;
|
426
|
+
if(!condCount) {
|
427
|
+
return null;
|
279
428
|
}
|
280
429
|
|
281
|
-
// Prepare
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
filterStr.push("var str = rowData['" + FilterBuilder._escapeQuotes(fmtFieldName) + "'];");
|
299
|
-
filterStr.push("if(!str && str !== 0) {"); // TODO: support false boolean value
|
300
|
-
filterStr.push(" str = (!val && val !== 0) ? '' : val + '';");
|
301
|
-
filterStr.push("}");
|
302
|
-
} else {
|
303
|
-
filterStr.push("var str = (!val && val !== 0) ? '' : val + '';"); // TODO: support false boolean value
|
430
|
+
// Prepare user value to be in ready to use form to boost performance
|
431
|
+
var formatter = this._formatter;
|
432
|
+
var conds = this._conditions.slice();
|
433
|
+
for(var i = 0; i < condCount; ++i) {
|
434
|
+
var cond = conds[i];
|
435
|
+
var opDef = FilterOperators[cond.operatorId];
|
436
|
+
var opType = opDef.type;
|
437
|
+
var value = cond.origValue;
|
438
|
+
|
439
|
+
if(opType === "number") {
|
440
|
+
value = convertToNumber(value);
|
441
|
+
} else if(opType === "date") {
|
442
|
+
var dateObj = null;
|
443
|
+
if(value instanceof Date) {
|
444
|
+
dateObj = value;
|
445
|
+
} else if(typeof value === "number" || typeof value === "string") {
|
446
|
+
dateObj = new Date(value);
|
304
447
|
}
|
305
|
-
|
306
|
-
|
307
|
-
|
448
|
+
value = convertToDateValue(
|
449
|
+
dateObj,
|
450
|
+
cond.useUTCTime != null ? cond.useUTCTime : this._useUTCTime
|
451
|
+
);
|
452
|
+
} else if(opType === "string") {
|
453
|
+
if(formatter) { // WARNING: This is not in sync when _formattedDataAccessor exists
|
454
|
+
var dummyRow = {};
|
455
|
+
dummyRow[fieldName] = inputStr;
|
456
|
+
dummyRow[fmtFieldName] = inputStr;
|
457
|
+
value = formatter(dummyRow); // WARNING: dummyRow may not provide enough data for formatting correctly
|
308
458
|
}
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
}
|
313
|
-
} else if(hasDateOp) {
|
314
|
-
filterStr.push("var ts = 0;");
|
315
|
-
filterStr.push("if(!val || val != val || !val.getTime) {");
|
316
|
-
filterStr.push(" return false;");
|
317
|
-
filterStr.push("}");
|
318
|
-
}
|
319
|
-
|
320
|
-
// Compose condition string
|
321
|
-
var condStr = [];
|
322
|
-
for (i = 0; i < len; i++) {
|
323
|
-
if (i > 0) {
|
324
|
-
condStr.push(toJsConnector(this._conditions[i - 1].connector));
|
325
|
-
}
|
326
|
-
|
327
|
-
var cond = this._conditions[i];
|
328
|
-
opDef = FilterOperators[cond.operatorId];
|
329
|
-
|
330
|
-
if(opDef.type === "blank") { // Blank checking operation (EQ_BLANK, and EQ_NBLANK) requires no data transformation
|
331
|
-
condStr.push("(" + opDef.formula + ")");
|
332
|
-
continue;
|
333
|
-
}
|
334
|
-
|
335
|
-
// Prepare input-value
|
336
|
-
var inputVal = cond.value; // Expect input value to already be formatted value or raw value
|
337
|
-
if(opDef.type === "string") {
|
338
|
-
if(typeof inputVal !== "string") {
|
339
|
-
if(this._formatter) {
|
340
|
-
var dummyRow = {};
|
341
|
-
dummyRow[fieldName] = inputVal;
|
342
|
-
dummyRow[fmtFieldName] = inputVal;
|
343
|
-
inputVal = this._formatter(dummyRow); // WARNING: dummyRow may not provide enough data for formatting correctly
|
344
|
-
} else if(inputVal) {
|
345
|
-
inputVal = inputVal + "";
|
346
|
-
} else if(inputVal === 0) {
|
347
|
-
inputVal = "0";
|
348
|
-
} else if(inputVal === false) {
|
349
|
-
inputVal = "false";
|
350
|
-
}
|
351
|
-
|
352
|
-
if(!inputVal) {
|
353
|
-
inputVal = "";
|
354
|
-
}
|
459
|
+
value = convertToString(value);
|
460
|
+
if(!opDef.caseSensitive) {
|
461
|
+
value = value.toLowerCase();
|
355
462
|
}
|
356
|
-
|
357
|
-
|
358
|
-
inputVal = inputVal.toLowerCase();
|
359
|
-
}
|
360
|
-
|
361
|
-
// After data type conversion, add quotes to be parsed by eval method
|
362
|
-
inputVal = "'" + FilterBuilder._escapeQuotes(inputVal) + "'";
|
363
|
-
} else if(opDef.type === "date") {
|
364
|
-
if(DateTime.isValidDate(inputVal)) {
|
365
|
-
var varName;
|
366
|
-
if(!cond.useUTCTime){
|
367
|
-
filterStr.push("ts = new Date(val.getFullYear(),val.getMonth(),val.getDate())");
|
368
|
-
} else {
|
369
|
-
filterStr.push("ts = new Date(Date.UTC(val.getUTCFullYear(),val.getUTCMonth(),val.getUTCDate()))");
|
370
|
-
}
|
371
|
-
filterStr.push("ts = ts.getTime()");
|
372
|
-
filterStr.push("if(ts !== ts) {");
|
373
|
-
filterStr.push(" return false;");
|
374
|
-
filterStr.push("}");
|
375
|
-
|
376
|
-
if(cond.operatorId === "DT") {
|
377
|
-
varName = "ts" + (i + 1);
|
378
|
-
inputVal = inputVal.getTime();
|
379
|
-
} else {
|
380
|
-
varName = "date" + (i + 1);
|
381
|
-
}
|
382
|
-
if(!contextObj) {
|
383
|
-
contextObj = {};
|
384
|
-
}
|
385
|
-
contextObj[varName] = inputVal;
|
386
|
-
inputVal = "this." + varName;
|
387
|
-
} else {
|
388
|
-
inputVal = NaN;
|
389
|
-
}
|
390
|
-
} else if(opDef.type === "number" ) {
|
391
|
-
if(typeof inputVal !== "number") {
|
392
|
-
if(inputVal) {
|
393
|
-
if(inputVal === true) {
|
394
|
-
inputVal = 1;
|
395
|
-
} else {
|
396
|
-
inputVal = parseFloat(inputVal);
|
397
|
-
}
|
398
|
-
} else if(inputVal === false) {
|
399
|
-
inputVal = 0;
|
400
|
-
} else { // NaN, empty string, undefined, null
|
401
|
-
inputVal = NaN;
|
402
|
-
}
|
403
|
-
}
|
404
|
-
} // else case is blank operator type which requires no input value
|
405
|
-
|
406
|
-
// Build condition string
|
407
|
-
condStr.push("(" + opDef.formula.replace(/input/g, inputVal) + ")");
|
463
|
+
}
|
464
|
+
cond.value = value;
|
408
465
|
}
|
409
466
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
}
|
419
|
-
} catch(err) {} // eslint-disable-line no-empty
|
467
|
+
var ctx = {
|
468
|
+
_conds: conds,
|
469
|
+
_fieldName: this._fieldName || "",
|
470
|
+
_formatter: formatter || null,
|
471
|
+
_formattedFieldName: this._formattedFieldName || "",
|
472
|
+
_rawDataAccessor: this._rawDataAccessor || null,
|
473
|
+
_formattedDataAccessor: this._formattedDataAccessor || null
|
474
|
+
};
|
420
475
|
|
421
476
|
// Release all resources after building the filter whether success or not
|
422
477
|
this._conditions.length = 0;
|
423
|
-
return
|
478
|
+
return _filterByConditions.bind(null, ctx);
|
424
479
|
};
|
480
|
+
|
425
481
|
/** @public
|
426
482
|
* @param {string} filterStr For instance, GT♦100♦AND♣LTE♦200
|
427
483
|
* @param {string} field
|
@@ -455,32 +511,15 @@ var buildFilterFromObjectMap = function(obj, field, rawDataAccessor) {
|
|
455
511
|
if(!obj || !field) {
|
456
512
|
return null;
|
457
513
|
}
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
// TODO: Field name cannot contain double quote string. Handle this case
|
463
|
-
funcAry.push(' var val = rowData["' + field + '"]');
|
514
|
+
var ctx = {
|
515
|
+
_fieldName: field,
|
516
|
+
_itemMap: obj
|
517
|
+
};
|
464
518
|
if(rawDataAccessor) {
|
465
|
-
|
466
|
-
contextObj = {};
|
467
|
-
}
|
468
|
-
contextObj["rawDataAccessor"] = rawDataAccessor;
|
469
|
-
funcAry.push(" val = this.rawDataAccessor(val);");
|
519
|
+
ctx._rawDataAccessor = rawDataAccessor;
|
470
520
|
}
|
471
|
-
funcAry.push(" return itemMap[val] ? true : false;");
|
472
|
-
funcAry.push("})");
|
473
|
-
|
474
|
-
var funcStr = funcAry.join("\n");
|
475
|
-
var filterFunc = null;
|
476
|
-
try {
|
477
|
-
filterFunc = eval(funcStr);
|
478
|
-
} catch (err) {} // eslint-disable-line
|
479
521
|
|
480
|
-
|
481
|
-
return filterFunc.bind(contextObj, obj);
|
482
|
-
}
|
483
|
-
return null;
|
522
|
+
return _filterByObjectMap.bind(null, ctx);
|
484
523
|
};
|
485
524
|
|
486
525
|
/** @public
|
@@ -498,7 +537,7 @@ FilterBuilder.prototype.parse = function(condition, field, formatter, formattedF
|
|
498
537
|
if(condition.indexOf("♦") >= 0) {
|
499
538
|
return this.buildMonitorFilter(condition, field, formatter, formattedField);
|
500
539
|
} else {
|
501
|
-
return
|
540
|
+
return ExpressionParser.parse(condition);
|
502
541
|
}
|
503
542
|
} else if(type === "function") {
|
504
543
|
return condition;
|
@@ -515,14 +554,5 @@ FilterBuilder.prototype.parse = function(condition, field, formatter, formattedF
|
|
515
554
|
return null;
|
516
555
|
};
|
517
556
|
|
518
|
-
/** @private
|
519
|
-
* @function
|
520
|
-
* @param {string} str
|
521
|
-
* @return {string}
|
522
|
-
*/
|
523
|
-
FilterBuilder._escapeQuotes = function(str) {
|
524
|
-
return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'); // eslint-disable-line no-control-regex
|
525
|
-
};
|
526
|
-
|
527
557
|
export default FilterBuilder;
|
528
558
|
export { FilterBuilder, buildFilterFromObjectMap };
|