@syncfusion/ej2-querybuilder 19.3.43 → 19.4.38
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/.github/PULL_REQUEST_TEMPLATE/Bug.md +63 -0
- package/.github/PULL_REQUEST_TEMPLATE/feature.md +39 -0
- package/CHANGELOG.md +11 -0
- package/dist/ej2-querybuilder.umd.min.js +2 -2
- package/dist/ej2-querybuilder.umd.min.js.map +1 -1
- package/dist/es6/ej2-querybuilder.es2015.js +79 -24
- package/dist/es6/ej2-querybuilder.es2015.js.map +1 -1
- package/dist/es6/ej2-querybuilder.es5.js +79 -24
- package/dist/es6/ej2-querybuilder.es5.js.map +1 -1
- package/dist/global/ej2-querybuilder.min.js +2 -2
- package/dist/global/ej2-querybuilder.min.js.map +1 -1
- package/dist/global/index.d.ts +1 -1
- package/package.json +11 -11
- package/src/query-builder/query-builder.d.ts +6 -0
- package/src/query-builder/query-builder.js +79 -24
- package/styles/bootstrap4.css +5 -0
- package/styles/bootstrap5-dark.css +5 -0
- package/styles/bootstrap5.css +5 -0
- package/styles/query-builder/_fluent-definition.scss +107 -0
- package/styles/query-builder/bootstrap4.css +5 -0
- package/styles/query-builder/bootstrap5-dark.css +5 -0
- package/styles/query-builder/bootstrap5.css +5 -0
- package/styles/query-builder/icons/_fluent.scss +8 -0
|
@@ -134,6 +134,9 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
134
134
|
this.isNotified = false;
|
|
135
135
|
this.isAddSuccess = false;
|
|
136
136
|
this.isNotValueChange = false;
|
|
137
|
+
this.isFieldChange = false;
|
|
138
|
+
this.isFieldClose = false;
|
|
139
|
+
this.isDestroy = false;
|
|
137
140
|
MultiSelect.Inject(CheckBoxSelection);
|
|
138
141
|
}
|
|
139
142
|
getPersistData() {
|
|
@@ -606,8 +609,8 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
606
609
|
ddlField = {
|
|
607
610
|
dataSource: this.columns,
|
|
608
611
|
fields: this.fields, placeholder: this.l10n.getConstant('SelectField'),
|
|
609
|
-
popupHeight: ((this.columns.length > 5) ? height : 'auto'),
|
|
610
|
-
change: this.changeField.bind(this), value: rule ? ddlValue : null, open: this.popupOpen.bind(this)
|
|
612
|
+
popupHeight: ((this.columns.length > 5) ? height : 'auto'), close: this.fieldClose.bind(this, ruleElem.id + '_filterkey'),
|
|
613
|
+
change: this.changeField.bind(this), value: rule ? ddlValue : null, open: this.popupOpen.bind(this, true)
|
|
611
614
|
};
|
|
612
615
|
if (this.fieldModel) {
|
|
613
616
|
ddlField = Object.assign({}, ddlField, this.fieldModel);
|
|
@@ -629,11 +632,11 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
629
632
|
const ddlValue = this.isImportRules ? rule.field : rule.field;
|
|
630
633
|
ddlField = {
|
|
631
634
|
fields: { dataSource: this.columns,
|
|
632
|
-
value:
|
|
635
|
+
value: 'field', text: 'label', child: 'columns', expanded: 'expanded' },
|
|
633
636
|
placeholder: this.l10n.getConstant('SelectField'), showClearButton: false,
|
|
634
637
|
popupHeight: ((this.columns.length > 5) ? height : 'auto'), changeOnBlur: false,
|
|
635
638
|
change: this.changeField.bind(this), value: this.isImportRules ? [ddlValue] : null,
|
|
636
|
-
open: this.popupOpen.bind(this)
|
|
639
|
+
open: this.popupOpen.bind(this, false)
|
|
637
640
|
};
|
|
638
641
|
if (this.fieldModel) {
|
|
639
642
|
ddlField = Object.assign({}, ddlField, this.fieldModel);
|
|
@@ -878,7 +881,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
878
881
|
else {
|
|
879
882
|
clsName = 'e-removerule e-rule-delete e-css e-btn e-small e-button-hide';
|
|
880
883
|
}
|
|
881
|
-
const delBtnElem = this.createElement('button', { attrs: { class: clsName } });
|
|
884
|
+
const delBtnElem = this.createElement('button', { attrs: { type: 'button', class: clsName } });
|
|
882
885
|
tempElem.appendChild(delBtnElem);
|
|
883
886
|
fieldElem.appendChild(tempElem);
|
|
884
887
|
ruleElem.appendChild(fieldElem);
|
|
@@ -929,7 +932,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
929
932
|
}
|
|
930
933
|
if (isGroup) {
|
|
931
934
|
const clsName = this.showButtons.groupDelete ? 'e-deletegroup' : 'e-deletegroup e-button-hide';
|
|
932
|
-
dltGroupBtn = this.createElement('button', { attrs: { class: clsName } });
|
|
935
|
+
dltGroupBtn = this.createElement('button', { attrs: { type: 'button', class: clsName } });
|
|
933
936
|
const button = new Button({ iconCss: 'e-icons e-delete-icon', cssClass: 'e-small e-round' });
|
|
934
937
|
button.appendTo(dltGroupBtn);
|
|
935
938
|
dltGroupBtn.setAttribute('title', this.l10n.getConstant('DeleteGroup'));
|
|
@@ -1233,21 +1236,38 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
1233
1236
|
}
|
|
1234
1237
|
}
|
|
1235
1238
|
}
|
|
1239
|
+
fieldClose(id) {
|
|
1240
|
+
if (this.isFieldChange || this.isDestroy) {
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
this.isFieldClose = true;
|
|
1244
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1245
|
+
const ddl = getComponent(id, 'dropdownlist');
|
|
1246
|
+
const item = ddl.popupObj.element.querySelector('.e-active');
|
|
1247
|
+
const itemData = ddl.getItemData();
|
|
1248
|
+
ddl.value = itemData.value;
|
|
1249
|
+
const customArgs = { element: ddl.element, value: itemData.value, isInteracted: true,
|
|
1250
|
+
previousItemData: this.prevItemData, previousItem: null, item: item, itemData: itemData, event: null, e: null };
|
|
1251
|
+
this.changeField(customArgs);
|
|
1252
|
+
this.isFieldChange = false;
|
|
1253
|
+
}
|
|
1236
1254
|
changeField(args) {
|
|
1237
1255
|
if (args.isInteracted) {
|
|
1256
|
+
this.isFieldChange = true;
|
|
1257
|
+
this.prevItemData = args.itemData;
|
|
1238
1258
|
const fieldElem = closest(args.element, '.e-rule-filter') || closest(args.element, '.e-rule-sub-filter');
|
|
1239
1259
|
const column = this.fieldMode === 'DropdownTree' ? this.getColumn(args.value[0]) : this.getColumn(args.value);
|
|
1240
1260
|
if (this.fieldMode === 'DropdownTree' && fieldElem != null) {
|
|
1241
|
-
const ddtElem = fieldElem.querySelector(
|
|
1261
|
+
const ddtElem = fieldElem.querySelector('.e-control');
|
|
1242
1262
|
const ddt = getComponent(ddtElem, 'dropdowntree');
|
|
1243
1263
|
if (column) {
|
|
1244
|
-
if (column.type
|
|
1264
|
+
if (column.type === 'object') {
|
|
1245
1265
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1246
1266
|
ddt.value = args.oldValue;
|
|
1247
1267
|
ddt.dataBind();
|
|
1248
1268
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1249
1269
|
if (isNullOrUndefined(args.oldValue)) {
|
|
1250
|
-
ddtElem.value =
|
|
1270
|
+
ddtElem.value = '';
|
|
1251
1271
|
}
|
|
1252
1272
|
else {
|
|
1253
1273
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1411,7 +1431,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
1411
1431
|
popupHeight: ((subFieldData.length > 5) ? height : 'auto'),
|
|
1412
1432
|
change: this.changeField.bind(this),
|
|
1413
1433
|
index: 0,
|
|
1414
|
-
open: this.popupOpen.bind(this)
|
|
1434
|
+
open: this.popupOpen.bind(this, false)
|
|
1415
1435
|
});
|
|
1416
1436
|
dropDownList.appendTo('#' + ruleId + '_subfilterkey' + this.subFilterCounter);
|
|
1417
1437
|
if (this.isImportRules) {
|
|
@@ -1532,7 +1552,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
1532
1552
|
change: this.changeField.bind(this),
|
|
1533
1553
|
index: 0,
|
|
1534
1554
|
value: value,
|
|
1535
|
-
open: this.popupOpen.bind(this)
|
|
1555
|
+
open: this.popupOpen.bind(this, false)
|
|
1536
1556
|
};
|
|
1537
1557
|
if (this.operatorModel) {
|
|
1538
1558
|
ddlOperator = Object.assign({}, ddlOperator, this.operatorModel);
|
|
@@ -1551,10 +1571,13 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
1551
1571
|
this.updateRules(ddlArgs.element, ddlArgs.item);
|
|
1552
1572
|
}
|
|
1553
1573
|
}
|
|
1554
|
-
popupOpen(args) {
|
|
1574
|
+
popupOpen(isField, args) {
|
|
1555
1575
|
if (this.enableRtl) {
|
|
1556
1576
|
addClass([args.popup.element], 'e-rtl');
|
|
1557
1577
|
}
|
|
1578
|
+
if (isField) {
|
|
1579
|
+
this.isFieldClose = false;
|
|
1580
|
+
}
|
|
1558
1581
|
}
|
|
1559
1582
|
destroyControls(target, isRuleTemplate) {
|
|
1560
1583
|
const element = isRuleTemplate ? target : target.nextElementSibling;
|
|
@@ -1747,7 +1770,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
1747
1770
|
change: this.changeValue.bind(this, i),
|
|
1748
1771
|
close: this.closePopup.bind(this, i),
|
|
1749
1772
|
actionBegin: this.multiSelectOpen.bind(this, parentId + '_valuekey' + i),
|
|
1750
|
-
open: this.popupOpen.bind(this)
|
|
1773
|
+
open: this.popupOpen.bind(this, false)
|
|
1751
1774
|
};
|
|
1752
1775
|
if (this.valueModel && this.valueModel.multiSelectModel) {
|
|
1753
1776
|
multiSelectValue = Object.assign({}, multiSelectValue, this.valueModel.multiSelectModel);
|
|
@@ -2168,6 +2191,9 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
2168
2191
|
return 0;
|
|
2169
2192
|
}
|
|
2170
2193
|
getPreviousItemData(prevItemData, column) {
|
|
2194
|
+
if (this.isFieldClose && prevItemData) {
|
|
2195
|
+
prevItemData = this.getColumn(prevItemData.value);
|
|
2196
|
+
}
|
|
2171
2197
|
if (column.template && prevItemData && Object.keys(prevItemData).length < 4) {
|
|
2172
2198
|
prevItemData.template = column.template;
|
|
2173
2199
|
}
|
|
@@ -2659,6 +2685,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
2659
2685
|
* @returns {void}
|
|
2660
2686
|
*/
|
|
2661
2687
|
destroy() {
|
|
2688
|
+
this.isDestroy = true;
|
|
2662
2689
|
const queryElement = this.element;
|
|
2663
2690
|
if (!queryElement) {
|
|
2664
2691
|
return;
|
|
@@ -2714,6 +2741,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
2714
2741
|
this.clearQBTemplate();
|
|
2715
2742
|
}
|
|
2716
2743
|
classList(this.element, [], ['e-rtl', 'e-responsive', 'e-device']);
|
|
2744
|
+
this.isDestroy = false;
|
|
2717
2745
|
}
|
|
2718
2746
|
/**
|
|
2719
2747
|
* Adds single or multiple rules.
|
|
@@ -2841,7 +2869,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
2841
2869
|
}
|
|
2842
2870
|
});
|
|
2843
2871
|
const textElem = this.createElement('textarea', { attrs: { class: 'e-summary-text', readonly: 'true' }, styles: 'max-height:500px' });
|
|
2844
|
-
const editElem = this.createElement('button', { attrs: { class: 'e-edit-rule e-css e-btn e-small e-flat e-primary' } });
|
|
2872
|
+
const editElem = this.createElement('button', { attrs: { type: 'button', class: 'e-edit-rule e-css e-btn e-small e-flat e-primary' } });
|
|
2845
2873
|
const divElem = this.createElement('div', { attrs: { class: 'e-summary-btndiv' } });
|
|
2846
2874
|
contentElem.appendChild(textElem);
|
|
2847
2875
|
textElem.textContent = this.getSqlFromRules(this.rule);
|
|
@@ -3495,6 +3523,9 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
3495
3523
|
rule.not = notValue;
|
|
3496
3524
|
}
|
|
3497
3525
|
}
|
|
3526
|
+
else if ((isNullOrUndefined(rule.condition)) && isNullOrUndefined(rule.rules)) {
|
|
3527
|
+
rule = { 'label': '', 'field': '', 'operator': '', 'type': '', 'value': '' };
|
|
3528
|
+
}
|
|
3498
3529
|
else {
|
|
3499
3530
|
if (this.enableNotCondition) {
|
|
3500
3531
|
rule = { 'condition': rule.condition, 'rules': rule.rules, 'not': rule.not };
|
|
@@ -3678,7 +3709,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
3678
3709
|
}
|
|
3679
3710
|
}
|
|
3680
3711
|
}
|
|
3681
|
-
else if (ruleColl[i].operator.length) {
|
|
3712
|
+
else if (!isNullOrUndefined(ruleColl[i].operator) && !isNullOrUndefined(ruleColl[i].operator.length)) {
|
|
3682
3713
|
const oper = ruleColl[i].operator.toLowerCase();
|
|
3683
3714
|
let isDateFilter = false;
|
|
3684
3715
|
const dateOperColl = ['equal', 'notequal', 'greaterthan', 'greaterthanorequal', 'lessthan', 'lessthanorequal'];
|
|
@@ -4381,6 +4412,12 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
4381
4412
|
this.parser.push(['Literal', matchValue]);
|
|
4382
4413
|
return matchValue.length + 2;
|
|
4383
4414
|
}
|
|
4415
|
+
// eslint-disable-next-line
|
|
4416
|
+
if (this.checkNumberLiteral(sqlString)) {
|
|
4417
|
+
matchValue = /^[0-9]+(\.[0-9]+)?/.exec(sqlString)[0];
|
|
4418
|
+
this.parser.push(['Literal', matchValue]);
|
|
4419
|
+
return matchValue.length;
|
|
4420
|
+
}
|
|
4384
4421
|
//String
|
|
4385
4422
|
if (/^'((?:[^\\']+?|\\.|'')*)'(?!')/.exec(sqlString)) {
|
|
4386
4423
|
matchValue = /^'((?:[^\\']+?|\\.|'')*)'(?!')/.exec(sqlString)[0];
|
|
@@ -4420,6 +4457,25 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
4420
4457
|
}
|
|
4421
4458
|
return false;
|
|
4422
4459
|
}
|
|
4460
|
+
checkNumberLiteral(sqlString) {
|
|
4461
|
+
const lastParser = this.parser[this.parser.length - 1];
|
|
4462
|
+
if (!lastParser) {
|
|
4463
|
+
return true;
|
|
4464
|
+
}
|
|
4465
|
+
else {
|
|
4466
|
+
if (/^[0-9]+(\.[0-9]+)?/.exec(sqlString)) {
|
|
4467
|
+
const secParser = this.parser[this.parser.length - 2];
|
|
4468
|
+
const betweenParser = this.parser[this.parser.length - 3];
|
|
4469
|
+
if (lastParser[0] === 'Left' && (secParser && secParser[0] === 'Conditions')) {
|
|
4470
|
+
return true;
|
|
4471
|
+
}
|
|
4472
|
+
if (lastParser[0] === 'Conditions' && (betweenParser && betweenParser[1].indexOf('between') < 0)) {
|
|
4473
|
+
return true;
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
return false;
|
|
4478
|
+
}
|
|
4423
4479
|
getOperator(value, operator) {
|
|
4424
4480
|
const operators = {
|
|
4425
4481
|
'=': 'equal', '!=': 'notequal', '<': 'lessthan', '>': 'greaterthan', '<=': 'lessthanorequal',
|
|
@@ -4448,14 +4504,8 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
4448
4504
|
return operators[operator];
|
|
4449
4505
|
}
|
|
4450
4506
|
getTypeFromColumn(rules) {
|
|
4451
|
-
const columnData = this.
|
|
4452
|
-
|
|
4453
|
-
if (columnData[i].field === rules.field) {
|
|
4454
|
-
rules.type = columnData[i].type;
|
|
4455
|
-
break;
|
|
4456
|
-
}
|
|
4457
|
-
}
|
|
4458
|
-
return rules.type;
|
|
4507
|
+
const columnData = this.getColumn(rules.field);
|
|
4508
|
+
return columnData.type;
|
|
4459
4509
|
}
|
|
4460
4510
|
processParser(parser, rules, levelColl) {
|
|
4461
4511
|
let j;
|
|
@@ -4470,6 +4520,7 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
4470
4520
|
let lLen;
|
|
4471
4521
|
let grpCount;
|
|
4472
4522
|
let operator;
|
|
4523
|
+
let isLeftOpened = false;
|
|
4473
4524
|
for (let i = 0, iLen = parser.length; i < iLen; i++) {
|
|
4474
4525
|
if (parser[i][0] === 'Literal') {
|
|
4475
4526
|
rule = { label: parser[i][1], field: parser[i][1] };
|
|
@@ -4488,8 +4539,12 @@ let QueryBuilder = class QueryBuilder extends Component {
|
|
|
4488
4539
|
j = i + 1;
|
|
4489
4540
|
jLen = iLen;
|
|
4490
4541
|
for (j = i + 1; j < jLen; j++) {
|
|
4491
|
-
if (parser[j][0] === '
|
|
4542
|
+
if (operator.indexOf('between') < 0 && parser[j][0] === 'Left') {
|
|
4543
|
+
isLeftOpened = true;
|
|
4544
|
+
}
|
|
4545
|
+
else if (parser[j][0] === 'Right' && isLeftOpened) {
|
|
4492
4546
|
i = j;
|
|
4547
|
+
isLeftOpened = false;
|
|
4493
4548
|
break;
|
|
4494
4549
|
}
|
|
4495
4550
|
else {
|