@syncfusion/ej2-querybuilder
Version:
Essential JS 2 QueryBuilder
1,066 lines (1,065 loc) • 378 kB
JavaScript
import { ChildProperty, Property, Collection, Component, getComponent, removeClass, isNullOrUndefined, Animation, extend, closest, addClass, select, append, detach, rippleEffect, getInstance, getValue, getNumericObject, Browser, classList, Internationalization, getUniqueID, L10n, Draggable, remove, compile, EventHandler, cldrData, Event, Complex, NotifyPropertyChanges } from '@syncfusion/ej2-base';
import { Button, CheckBox, RadioButton } from '@syncfusion/ej2-buttons';
import { MultiSelect, CheckBoxSelection, DropDownList, DropDownTree } from '@syncfusion/ej2-dropdowns';
import { Query, DataManager, Deferred, Predicate } from '@syncfusion/ej2-data';
import { NumericTextBox, TextBox } from '@syncfusion/ej2-inputs';
import { DatePicker } from '@syncfusion/ej2-calendars';
import { DropDownButton } from '@syncfusion/ej2-splitbuttons';
import { Tooltip, showSpinner, hideSpinner, createSpinner } from '@syncfusion/ej2-popups';
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
* Defines the Columns of Query Builder
*/
class Columns extends ChildProperty {
}
__decorate([
Property(null)
], Columns.prototype, "field", void 0);
__decorate([
Property(null)
], Columns.prototype, "label", void 0);
__decorate([
Property(null)
], Columns.prototype, "type", void 0);
__decorate([
Property(null)
], Columns.prototype, "values", void 0);
__decorate([
Property(null)
], Columns.prototype, "operators", void 0);
__decorate([
Property()
], Columns.prototype, "ruleTemplate", void 0);
__decorate([
Property(null)
], Columns.prototype, "template", void 0);
__decorate([
Property({ isRequired: true, min: 0, max: Number.MAX_VALUE })
], Columns.prototype, "validation", void 0);
__decorate([
Property(null)
], Columns.prototype, "format", void 0);
__decorate([
Property(null)
], Columns.prototype, "step", void 0);
__decorate([
Property(null)
], Columns.prototype, "value", void 0);
__decorate([
Property(null)
], Columns.prototype, "category", void 0);
__decorate([
Property(null)
], Columns.prototype, "columns", void 0);
/**
* Defines the rule of Query Builder
*/
class Rule extends ChildProperty {
}
__decorate([
Property(null)
], Rule.prototype, "condition", void 0);
__decorate([
Collection([], Rule)
], Rule.prototype, "rules", void 0);
__decorate([
Property(null)
], Rule.prototype, "field", void 0);
__decorate([
Property(null)
], Rule.prototype, "label", void 0);
__decorate([
Property(null)
], Rule.prototype, "type", void 0);
__decorate([
Property(null)
], Rule.prototype, "operator", void 0);
__decorate([
Property(null)
], Rule.prototype, "value", void 0);
__decorate([
Property(false)
], Rule.prototype, "not", void 0);
__decorate([
Property(null)
], Rule.prototype, "isLocked", void 0);
/**
* Defines the property for value.
*/
class Value extends ChildProperty {
}
__decorate([
Property(null)
], Value.prototype, "numericTextBoxModel", void 0);
__decorate([
Property(null)
], Value.prototype, "multiSelectModel", void 0);
__decorate([
Property(null)
], Value.prototype, "datePickerModel", void 0);
__decorate([
Property(null)
], Value.prototype, "textBoxModel", void 0);
__decorate([
Property(null)
], Value.prototype, "radioButtonModel", void 0);
/**
* Defines the ruleDelete, groupInsert, and groupDelete options of Query Builder.
*/
class ShowButtons extends ChildProperty {
}
__decorate([
Property(false)
], ShowButtons.prototype, "cloneRule", void 0);
__decorate([
Property(false)
], ShowButtons.prototype, "cloneGroup", void 0);
__decorate([
Property(false)
], ShowButtons.prototype, "lockRule", void 0);
__decorate([
Property(false)
], ShowButtons.prototype, "lockGroup", void 0);
__decorate([
Property(true)
], ShowButtons.prototype, "ruleDelete", void 0);
__decorate([
Property(true)
], ShowButtons.prototype, "groupInsert", void 0);
__decorate([
Property(true)
], ShowButtons.prototype, "groupDelete", void 0);
let QueryBuilder = class QueryBuilder extends Component {
constructor(options, element) {
super(options, element);
this.isReadonly = true;
this.fields = { text: 'label', value: 'field' };
this.updatedRule = { not: false, condition: 'and', isLocked: false };
this.isLocale = false;
this.isRefreshed = false;
this.isNotified = false;
this.isAddSuccess = false;
this.isNotValueChange = false;
this.isFieldChange = false;
this.isFieldClose = false;
this.isDestroy = false;
this.isGetNestedData = false;
this.isCustomOprCols = [];
this.groupCounter = 0;
this.lockItems = [];
this.groupIndex = -1;
this.ruleIndex = -1;
this.isLastGroup = false;
this.cloneGrpBtnClick = false;
this.isMiddleGroup = false;
this.cloneRuleBtnClick = false;
this.isValueEmpty = false;
this.isPropChange = false;
MultiSelect.Inject(CheckBoxSelection);
}
getPersistData() {
return this.addOnPersist(['rule']);
}
/**
* Clears the rules without root rule.
*
* @returns {void}.
*/
reset() {
this.isImportRules = false;
let bodyElem = this.element.querySelector('.e-group-body');
const inputElement = this.element.querySelectorAll('input.e-control');
for (let i = 0, len = inputElement.length; i < len; i++) {
if (inputElement[i].className.indexOf('e-tooltip') > -1) {
getComponent(inputElement[i], 'tooltip').destroy();
}
else if (inputElement[i].parentElement.className.indexOf('e-tooltip') > -1) {
getComponent(inputElement[i].parentElement, 'tooltip').destroy();
}
}
if (bodyElem) {
bodyElem.innerHTML = '';
}
else {
const grpContainer = this.createElement('div', { attrs: { class: 'e-group-container' } });
const grpHeader = this.createElement('div', { attrs: { class: 'e-group-header' } });
const grpBody = this.createElement('div', { attrs: { class: 'e-group-body' } });
grpContainer.appendChild(grpHeader).appendChild(grpBody);
this.element.appendChild(grpContainer);
bodyElem = this.element.querySelector('.e-group-body');
}
if (this.headerTemplate && this.isRoot) {
this.element.innerHTML = '';
this.isRoot = false;
}
if (this.enableNotCondition) {
removeClass(this.element.querySelectorAll('.e-qb-toggle'), 'e-active-toggle');
}
bodyElem.appendChild(this.createElement('div', { attrs: { class: 'e-rule-list' } }));
this.levelColl[this.element.id + '_group0'] = [0];
this.setProperties({ rule: { condition: 'and', not: false, rules: [] } }, true);
this.disableRuleCondition(bodyElem.parentElement);
}
getWrapper() {
return this.element;
}
getModuleName() {
return 'query-builder';
}
requiredModules() {
const modules = [];
modules.push({
member: 'query-library',
args: [this]
});
return modules;
}
GetRootColumnName(field) {
if (!isNullOrUndefined(field)) {
return this.separator ? field.split(this.separator)[0] : field;
}
return '';
}
initialize() {
if (this.dataColl.length) {
const columnKeys = Object.keys(this.dataColl[0]);
const cols = [];
const categories = [];
let type;
let groupBy = false;
let isDate = false;
let value;
const validateObj = { isRequired: true, min: 0, max: Number.MAX_VALUE };
if (this.columns.length) {
this.columnSort();
const columns = this.columns;
for (let i = 0, len = columns.length; i < len; i++) {
this.updateCustomOperator(columns[i], 'initial');
if (!columns[i].type) {
if (columnKeys.indexOf(columns[i].field) > -1) {
value = this.dataColl[0][columns[i].field];
type = typeof value;
if (type === 'string') {
isDate = !isNaN(Date.parse(value));
}
else if (type === 'object') {
isDate = value instanceof Date && !isNaN(value.getTime());
type = 'string';
}
columns[i].type = type;
isDate = false;
}
type = 'string';
}
if (!columns[i].validation) {
columns[i].validation = validateObj;
}
if (columns[i].category) {
groupBy = true;
}
else {
columns[i].category = this.l10n.getConstant('OtherFields');
}
if (categories.indexOf(columns[i].category) < 0) {
categories.push(columns[i].category);
}
if (!columns[i].operators ||
(this.isLocale && this.isCustomOprCols.indexOf(columns[i].field) === -1)) {
columns[i].operators = this.customOperators[columns[i].type + 'Operator'];
}
}
if (groupBy && (categories.length > 1 || categories[0] !== this.l10n.getConstant('OtherFields'))) {
this.fields = { text: 'label', value: 'field', groupBy: 'category' };
}
this.updateSubFieldsFromColumns(this.columns);
}
else {
for (let i = 0, len = columnKeys.length; i < len; i++) {
value = this.dataColl[0][columnKeys[i]];
type = typeof value;
if (type === 'string') {
isDate = !isNaN(Date.parse(value));
}
else if (type === 'object' && !Object.keys(value).length) {
isDate = value instanceof Date && !isNaN(value.getTime());
type = 'string';
}
cols[i] = { 'field': columnKeys[i], 'label': columnKeys[i], 'type': isDate ? 'date' : type,
'validation': validateObj };
isDate = false;
cols[i].operators = this.customOperators[cols[i].type + 'Operator'];
if (type === 'object') {
this.updateSubFields(value, cols[i]);
}
}
this.columns = cols;
}
}
else if (this.columns && this.columns.length) {
const columns = this.columns;
for (let i = 0, len = columns.length; i < len; i++) {
if (columns[i].category) {
this.fields = { text: 'label', value: 'field', groupBy: 'category' };
}
else {
columns[i].category = this.l10n.getConstant('OtherFields');
}
this.updateCustomOperator(columns[i], 'initial');
if (!columns[i].operators ||
(this.isLocale && this.isCustomOprCols.indexOf(columns[i].field) === -1)) {
columns[i].operators = this.customOperators[columns[i].type + 'Operator'];
}
}
this.updateSubFieldsFromColumns(this.columns);
}
this.trigger('dataBound', { type: 'dataBound' });
}
updateSubFieldsFromColumns(col, field) {
for (let i = 0; i < col.length; i++) {
if (this.separator !== '' && col[i].field.indexOf(this.separator) < 0) {
col[i].field = field ? field + this.separator + col[i].field : col[i].field;
}
if (col[i].operators) {
this.updateCustomOperator(col[i]);
}
else if (col[i].type && col[i].type !== 'object') {
col[i].operators = this.customOperators[col[i].type + 'Operator'];
}
if (col[i].columns) {
col[i].type = 'object';
this.updateSubFieldsFromColumns(col[i].columns, col[i].field);
}
}
}
updateSubFields(value, col, data) {
let sampCol;
col.columns = [];
const columnKeys = Object.keys(value);
let field;
let label;
let type;
let result;
data = data ? data : this.dataColl[0];
for (let i = 0, len = columnKeys.length; i < len; i++) {
const compField = col.field.split('.');
if (data) {
result = data[compField[compField.length - 1]][columnKeys[i]];
}
else {
result = this.dataColl[0][col.field][columnKeys[i]];
}
const resData = data[col.field.split(this.separator)[col.field.split(this.separator).length - 1]];
type = typeof result;
field = col.field + this.separator + columnKeys[i];
label = columnKeys[i];
type = (type === 'object' && !isNaN(Date.parse(result))) ? 'date' : type;
sampCol = { field: field, label: label, type: type };
if (type !== 'object') {
sampCol.operators = this.customOperators[type + 'Operator'];
}
col.columns.push(sampCol);
if (type === 'object') {
this.updateSubFields(result, sampCol, resData);
}
}
}
updateCustomOperator(column, from) {
if (column.operators) {
if (!this.isLocale && from === 'initial' && !isNullOrUndefined(this.isCustomOprCols)) {
this.isCustomOprCols.push(column.field);
}
for (let j = 0; j < column.operators.length; j++) {
const sqlIdx = Object.keys(column.operators[j]).indexOf('sqlOperator');
if (sqlIdx > -1) {
const operator = column.operators[j];
const operColl = Object.keys(operator);
const values = operColl.map((key) => operator[`${key}`]).join(',').split(',');
const valueIdx = operColl.indexOf('value');
this.operators[values[valueIdx]] = values[sqlIdx];
}
}
}
}
focusEventHandler(event) {
this.target = event.target;
}
clickEventHandler(event) {
let target = event.target;
let args;
this.isImportRules = false;
let groupID;
if (target.tagName === 'SPAN') {
target = target.parentElement;
}
if (typeof target.className === 'string' && target.className.indexOf('e-collapse-rule') > -1) {
const animation = new Animation({ duration: 1000, delay: 0 });
if (this.element.querySelectorAll('.e-summary-content').length < 1) {
this.renderSummary();
}
const summaryElem = document.getElementById(this.element.id + '_summary_content');
const txtareaElem = summaryElem.querySelector('.e-summary-text');
animation.animate('.e-query-builder', { name: 'SlideLeftIn' });
const groupElem = this.element.querySelector('.e-group-container');
groupElem.style.display = 'none';
txtareaElem.textContent = this.getSqlFromRules(this.rule);
summaryElem.style.display = 'block';
txtareaElem.style.height = txtareaElem.scrollHeight + 'px';
}
if (target.tagName === 'BUTTON' && typeof target.className === 'string' && target.className.indexOf('e-qb-toggle') < 0) {
const animation = new Animation({ duration: 1000, delay: 0 });
switch (true) {
case target.className.indexOf('e-removerule') > -1:
this.actionButton = target;
this.deleteRule(target);
break;
case target.className.indexOf('e-clone-rule-btn') > -1:
this.actionButton = target;
this.cloneRuleBtnClick = true;
this.ruleClone(target);
break;
case target.className.indexOf('e-lock-rule-btn') > -1:
this.actionButton = target;
this.ruleLock(target);
break;
case target.className.indexOf('e-lock-grp-btn') > -1:
this.actionButton = target;
this.groupLock(target);
break;
case target.className.indexOf('e-clone-grp-btn') > -1:
this.actionButton = target;
this.cloneGrpBtnClick = true;
this.groupClone(closest(target, '.e-group-container'));
break;
case target.className.indexOf('e-deletegroup') > -1:
this.actionButton = target;
this.deleteGroup(closest(target, '.e-group-container'));
break;
case target.className.indexOf('e-edit-rule') > -1:
animation.animate('.e-query-builder', { name: 'SlideLeftIn' });
document.getElementById(this.element.id + '_summary_content').style.display = 'none';
if (this.element.querySelectorAll('.e-group-container').length < 1) {
this.addGroupElement(false, this.element, this.rule.condition, false, this.rule.not);
const mRules = extend({}, this.rule, {}, true);
this.setGroupRules(mRules);
this.renderSummaryCollapse();
}
else {
const groupElem = this.element.querySelector('.e-group-container');
if (groupElem.querySelectorAll('.e-collapse-rule').length < 1) {
this.renderSummaryCollapse();
}
groupElem.style.display = 'block';
}
break;
}
}
else if ((target.tagName === 'LABEL' && target.parentElement.className.indexOf('e-btn-group') > -1) ||
(typeof target.className === 'string' && target.className.indexOf('e-qb-toggle') > -1)) {
const element = closest(target, '.e-group-container');
if (!this.headerTemplate) {
const forIdValue = target.getAttribute('for');
let targetValue;
if (forIdValue) {
targetValue = document.getElementById(forIdValue).getAttribute('value');
}
else if (this.enableSeparateConnector) {
if (target.classList.contains('e-btngroup-or-lbl')) {
targetValue = 'or';
}
else if (target.classList.contains('e-btngroup-and-lbl')) {
targetValue = 'and';
}
else {
targetValue = target.textContent;
}
}
groupID = element.id.replace(this.element.id + '_', '');
const group = this.getGroup(groupID);
let ariaChecked;
if (this.enableNotCondition) {
if (target.className.indexOf('e-qb-toggle') > -1) {
const toggleElem = element.getElementsByClassName('e-qb-toggle')[0];
if (toggleElem.className.indexOf('e-active-toggle') > -1) {
removeClass([toggleElem], 'e-active-toggle');
ariaChecked = false;
}
else {
addClass([toggleElem], 'e-active-toggle');
ariaChecked = true;
}
targetValue = group.condition;
}
else {
ariaChecked = group.not;
}
}
args = { groupID: groupID, cancel: false, type: 'condition', value: targetValue.toLowerCase() };
if (this.enableNotCondition) {
args = { groupID: groupID, cancel: false, type: 'condition', value: targetValue.toLowerCase(),
'not': ariaChecked };
}
}
if (!this.isImportRules) {
this.trigger('beforeChange', args, (observedChangeArgs) => {
this.beforeSuccessCallBack(observedChangeArgs, target);
});
}
else {
this.beforeSuccessCallBack(args, target);
}
this.target = target;
}
}
beforeSuccessCallBack(args, target) {
if (args && !args.cancel) {
let element = closest(target, '.e-group-container');
const groupID = element.id.replace(this.element.id + '_', '');
const beforeRules = this.getValidRules(this.rule);
let rule = this.getParentGroup(element);
if (this.enableSeparateConnector) {
if (isNullOrUndefined(closest(target, '.e-rule-container')) &&
element.classList.contains('e-group-container')) {
element = target.parentElement.previousElementSibling !== null ?
target.parentElement.previousElementSibling : element;
}
else {
element = closest(target, '.e-rule-container');
}
const id = element.id.replace(this.element.id + '_', '');
if (element.classList.contains('e-rule-container')) {
rule = this.getRule(element);
rule.condition = args.value;
}
else if (element.classList.contains('e-group-container')) {
rule = this.getGroup(element);
rule.condition = args.value;
}
if (this.enableNotCondition) {
rule.not = args.not;
}
if (!this.isImportRules) {
this.trigger('change', { groupID: groupID, ruleID: id, type: 'condition', value: rule.condition });
}
}
else {
rule.condition = args.value;
if (this.enableNotCondition) {
rule.not = args.not;
}
if (!this.isImportRules) {
this.trigger('change', { groupID: groupID, type: 'condition', value: rule.condition });
}
}
this.filterRules(beforeRules, this.getValidRules(this.rule), 'condition');
if (this.enableSeparateConnector) {
const andElem = target.parentElement.querySelector('.e-btngroup-and');
const orElem = target.parentElement.querySelector('.e-btngroup-or');
if (andElem && orElem) {
if (args.value === 'and') {
andElem.checked = true;
orElem.checked = false;
}
else if (args.value === 'or') {
orElem.checked = true;
andElem.checked = false;
}
}
}
}
}
selectBtn(target, event) {
if (event.name === 'beforeOpen') {
if (this.showButtons.groupInsert || isNullOrUndefined(this.showButtons.groupInsert)) {
if (this.element.querySelectorAll('.e-group-container').length >= this.maxGroupCount + 1) {
addClass([event.element.querySelector('li span.e-addgroup').parentElement], 'e-button-hide');
}
else {
removeClass([event.element.querySelector('li span.e-addgroup').parentElement], 'e-button-hide');
}
if (this.enableRtl) {
addClass([event.element.querySelector('li').parentElement], 'e-rtl');
}
}
else {
addClass([event.element.querySelector('li span.e-addgroup').parentElement], 'e-button-hide');
}
}
else if (event.element.children[0].className.indexOf('e-addrule') > -1) {
this.addRuleElement(closest(target, '.e-group-container'), {});
}
else if (event.element.children[0].className.indexOf('e-addgroup') > -1) {
this.addGroupElement(true, closest(target, '.e-group-container'), '', true);
}
}
appendRuleElem(target, column, type, parentId, action, rule) {
let ruleElem;
let elem;
const ruleListElem = target.querySelector('.e-rule-list');
let args;
if (type === 'change') {
ruleElem = select('#' + parentId, target);
}
else {
ruleElem = this.createElement('div', { attrs: { class: 'e-rule-container' } });
ruleElem.setAttribute('id', target.id + '_rule' + this.ruleIdCounter);
if (this.showButtons.cloneRule && this.cloneRuleBtnClick) {
if (this.ruleIndex < 0) {
ruleListElem.appendChild(ruleElem);
}
else {
if (this.enableSeparateConnector) {
let index = -1;
let tempRuleIndex = this.ruleIndex + 1;
for (let i = 0; i < tempRuleIndex; i++) {
if (i === ruleListElem.children.length) {
break;
}
if (ruleListElem.children[i].classList.contains('e-rule-container')) {
tempRuleIndex++;
index++;
}
}
ruleListElem.insertBefore(ruleElem, ruleListElem.children[this.ruleIndex + index + 1]); // added clone rule to next position
}
else {
ruleListElem.insertBefore(ruleElem, ruleListElem.children[this.ruleIndex + 1]); // added clone rule to next position
}
}
this.cloneRuleBtnClick = false;
}
else {
ruleListElem.appendChild(ruleElem);
}
this.ruleIdCounter++;
}
if (column && column.ruleTemplate && rule) {
args = { requestType: 'template-initialize', ruleID: ruleElem.id, action: action, fields: this.fields, rule: rule };
this.trigger('actionBegin', args);
this.ruleTemplateFn = this.templateParser(column.ruleTemplate);
const templateID = this.element.id + column.field;
let template;
args.fields = this.fields;
args.columns = this.columns;
if (rule.field === '') {
rule.field = column.field;
}
args.operators = this.getOperators(rule.field);
args.operatorFields = { text: 'key', value: 'value' };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (this.isReact) {
template = this.ruleTemplateFn(args, this, ruleElem.id, templateID)[0];
elem = template;
elem.className += ' e-rule-field';
ruleElem.appendChild(elem);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}
else if (this.isAngular) {
const templateColl = this.ruleTemplateFn(args, this, ruleElem.id, templateID);
template = (templateColl[0].nodeType === 3) ? templateColl[1] : templateColl[0];
elem = template;
elem.className += ' e-rule-field';
ruleElem.appendChild(elem);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}
else if (this.isVue3) {
template = this.ruleTemplateFn(args, this, 'Template', templateID);
elem = template;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
append(elem, ruleElem);
if (ruleElem.children.length) {
ruleElem.children[ruleElem.children.length - 1].className += ' e-rule-field';
}
}
else {
template = this.ruleTemplateFn(args, this, 'Template', templateID)[0];
elem = template;
elem.className += ' e-rule-field';
ruleElem.appendChild(elem);
}
}
else {
elem = this.ruleElem.querySelector('.e-rule-field').cloneNode(true);
ruleElem.appendChild(elem);
}
if (this.showButtons.lockGroup) {
removeClass(ruleElem.querySelectorAll('.e-lock-grp-btn'), 'e-button-hide');
}
if (this.showButtons.lockRule) {
removeClass(ruleElem.querySelectorAll('.e-lock-rule-btn'), 'e-button-hide');
}
if (this.showButtons.cloneGroup) {
removeClass(ruleElem.querySelectorAll('.e-clone-grp-btn'), 'e-button-hide');
}
if (this.showButtons.cloneRule) {
removeClass(ruleElem.querySelectorAll('.e-clone-rule-btn'), 'e-button-hide');
}
if (this.showButtons.ruleDelete) {
removeClass(ruleElem.querySelectorAll('.e-lock-grp-btn'), 'e-button-hide');
}
if (this.allowDragAndDrop) {
removeClass(ruleElem.querySelectorAll('.e-drag-qb-rule'), 'e-hidden');
}
if (column && column.ruleTemplate && rule) {
this.renderReactTemplates();
}
return ruleElem;
}
addRuleElement(target, rule, column, action, parentId, isRuleTemplate) {
if (!target) {
return;
}
const args = { groupID: target.id.replace(this.element.id + '_', ''), cancel: false, type: 'insertRule' };
if (!this.isImportRules && !this.isInitialLoad && !this.prvtEvtTgrDaD) {
this.trigger('beforeChange', args, (observedChangeArgs) => {
this.addRuleSuccessCallBack(observedChangeArgs, target, rule, column, action, parentId, isRuleTemplate);
});
}
else {
this.isInitialLoad = false;
this.addRuleSuccessCallBack(args, target, rule, column, action, parentId, isRuleTemplate);
}
}
addRuleSuccessCallBack(args, trgt, rule, col, act, pId, isRlTmp) {
const height = (this.element.className.indexOf('e-device') > -1) ? '250px' : '200px';
let ruleID;
const column = (rule && rule.field) ? this.getColumn(rule.field) : col ? col : this.columns[0];
let operators;
let dropDownList;
let ruleElem;
let newRule = { 'label': '', 'field': '', 'type': '', 'operator': '' };
if (!args.cancel) {
if (column && column.ruleTemplate && rule.field) {
this.selectedColumn = column;
operators = this.selectedColumn.operators;
newRule = { 'label': column.label, 'field': column.field, 'type': column.type, 'operator': operators[0].value };
const passedRule = Object.keys(rule).length ? rule : newRule;
ruleElem = this.appendRuleElem(trgt, column, act, pId, 'field', passedRule);
const args = { requestType: 'template-create', action: 'insert-rule', ruleID: ruleElem.id,
fields: this.fields, rule: passedRule };
this.trigger('actionBegin', args);
}
else {
ruleElem = this.appendRuleElem(trgt, column, act, pId, 'field');
ruleElem.querySelector('.e-filter-input').setAttribute('id', ruleElem.id + '_filterkey');
const element = ruleElem.querySelector('.e-rule-delete');
if (this.element.className.indexOf('e-device') > -1 || this.displayMode === 'Vertical') {
element.textContent = this.l10n.getConstant('Remove');
addClass([element], 'e-flat');
addClass([element], 'e-primary');
}
else {
addClass([element], 'e-round');
addClass([element], 'e-icon-btn');
element.setAttribute('title', this.l10n.getConstant('DeleteRule'));
const spanElement = this.createElement('span', { attrs: { class: 'e-btn-icon e-icons e-delete-icon' } });
ruleElem.querySelector('.e-rule-delete').appendChild(spanElement);
}
if (!this.showButtons.ruleDelete) {
element.classList.add('e-button-hide');
}
}
if (this.displayMode === 'Vertical' || this.element.className.indexOf('e-device') > -1) {
ruleElem.className = 'e-rule-container e-vertical-mode';
}
else {
ruleElem.className = 'e-rule-container e-horizontal-mode';
}
let previousRuleElem = ruleElem.previousElementSibling;
if (this.enableSeparateConnector) {
let prevRule;
let ruleContainer;
if (previousRuleElem && previousRuleElem.classList.contains('e-group-container')) {
ruleContainer = previousRuleElem.querySelectorAll('.e-rule-container');
previousRuleElem = ruleContainer[ruleContainer.length - 1];
}
if (previousRuleElem && previousRuleElem.classList.contains('e-rule-container')) {
prevRule = this.getRule(previousRuleElem);
}
if (this.headerTemplate && previousRuleElem && prevRule) {
this.headerTemplateFn(previousRuleElem, false, prevRule.condition, prevRule, previousRuleElem.id);
}
else if (isNullOrUndefined(previousRuleElem) && ruleElem.id !== this.element.id + '_group0_rule0') {
const group = ruleElem.closest('.e-group-container');
if (group && group.previousElementSibling) {
let prevElem = group.previousElementSibling;
const prevRuleContainer = prevElem.querySelectorAll('.e-rule-container');
if (prevElem.classList.contains('e-group-container')) {
prevElem = prevRuleContainer[prevRuleContainer.length - 1];
}
if (prevElem.classList.contains('e-rule-container')) {
const prevRule = this.getRule(prevElem);
this.headerTemplateFn(prevElem, false, prevRule.condition, prevRule, prevElem.id, true);
}
}
else {
this.headerTemplateFn(ruleElem, false, rule.condition, rule, ruleElem.id, true);
}
}
}
else {
if (previousRuleElem && previousRuleElem.className.indexOf('e-rule-container') > -1) {
if (ruleElem.className.indexOf('e-joined-rule') < 0) {
ruleElem.className += ' e-joined-rule';
}
if (previousRuleElem.className.indexOf('e-prev-joined-rule') < 0) {
previousRuleElem.className += ' e-prev-joined-rule';
}
}
}
if (previousRuleElem && previousRuleElem.className.indexOf('e-group-container') > -1 &&
ruleElem.className.indexOf('e-separate-rule') < 0) {
ruleElem.className += ' e-separate-rule';
}
if (!this.isImportRules) {
this.updateAddedRule(trgt, rule, newRule, isRlTmp, pId, this.enableSeparateConnector ? true : null);
}
if (!column || (column && !column.ruleTemplate) || !rule.field) {
if (this.fieldMode === 'Default') {
let ddlField;
let ddlValue;
if (this.separator && rule.field) {
ddlValue = this.GetRootColumnName(rule.field);
}
else if (this.autoSelectField) {
ddlValue = this.GetRootColumnName(rule.field);
}
else {
ddlValue = this.isImportRules ? this.GetRootColumnName(rule.field) : rule.field;
}
ddlField = {
dataSource: this.columns,
fields: this.fields, placeholder: this.l10n.getConstant('SelectField'),
popupHeight: ((this.columns.length > 5) ? height : 'auto'), close: this.fieldClose.bind(this, ruleElem.id + '_filterkey'),
change: this.changeField.bind(this), value: rule ? ddlValue : null, open: this.popupOpen.bind(this, true), cssClass: 'qb-dropdownlist'
};
if (this.fieldModel) {
ddlField = Object.assign({}, ddlField, this.fieldModel);
}
dropDownList = new DropDownList(ddlField);
dropDownList.appendTo('#' + ruleElem.id + '_filterkey');
let ddlVal;
if (this.separator && rule.field) {
ddlVal = this.GetRootColumnName(rule.field);
}
else {
ddlVal = this.isImportRules ? this.GetRootColumnName(rule.field) :
dropDownList.value;
}
this.selectedColumn = dropDownList.getDataByValue(ddlVal);
if (Object.keys(rule).length) {
this.changeRule(rule, {
element: dropDownList.element, itemData: this.selectedColumn
});
}
}
else {
let ddlField;
const ddlValue = this.isImportRules ? rule.field : rule.field;
this.dummyDropdownTreeDs = extend([], this.columns, [], true);
this.updateDropdowntreeDS(this.dummyDropdownTreeDs);
ddlField = {
fields: { dataSource: this.dummyDropdownTreeDs,
value: 'field', text: 'label', child: 'columns', expanded: 'expanded', selectable: 'selectable' },
placeholder: this.l10n.getConstant('SelectField'), showClearButton: false,
popupHeight: ((this.columns.length > 5) ? height : 'auto'), changeOnBlur: false,
change: this.changeField.bind(this), value: !isNullOrUndefined(ddlValue) ? [ddlValue] : null,
open: this.popupOpen.bind(this, false), treeSettings: { expandOn: 'Click' },
cssClass: 'e-qb-ddt', filtering: this.dropdownTreeFiltering.bind(this), close: this.dropdownTreeClose.bind(this)
};
if (this.fieldModel) {
ddlField = Object.assign({}, ddlField, this.fieldModel);
}
const dropdowntree = new DropDownTree(ddlField);
dropdowntree.appendTo('#' + ruleElem.id + '_filterkey');
if (!isNullOrUndefined(dropdowntree.value)) {
const value = this.getLabelFromColumn(dropdowntree.value[0]);
dropdowntree.element.value = value;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ddlVal = !isNullOrUndefined(rule.field) ?
this.GetRootColumnName(rule.field) : dropdowntree.value;
this.selectedColumn = this.getColumn(ddlVal);
if (Object.keys(rule).length) {
this.changeRule(rule, {
element: dropdowntree.element, itemData: this.selectedColumn
});
}
}
}
ruleID = ruleElem.id.replace(this.element.id + '_', '');
if (rule && rule.isLocked) {
const lockRuleTarget = ruleElem.querySelector('.e-lock-rule-btn');
this.ruleLock(lockRuleTarget);
}
if (!this.isImportRules && !this.prvtEvtTgrDaD) {
this.trigger('change', { groupID: trgt.id.replace(this.element.id + '_', ''), ruleID: ruleID, type: 'insertRule' });
}
}
if (this.enableSeparateConnector && isNullOrUndefined(rule.condition) && ruleID) {
rule = this.getRule(ruleID);
}
if (this.enableSeparateConnector) {
let prevElem = ruleElem.previousElementSibling;
let ruleContainer;
while (prevElem && !prevElem.classList.contains('e-rule-container')) {
if (prevElem.classList.contains('e-group-container')) {
ruleContainer = prevElem.querySelectorAll('.e-rule-container');
prevElem = ruleContainer[ruleContainer.length - 1];
break;
}
prevElem = prevElem.previousElementSibling;
}
if (this.headerTemplate && prevElem) {
const prevRule = this.getRule(prevElem);
const args = { requestType: 'rule-template-create', ruleID: prevElem.id, condition: prevRule.condition,
notCondition: this.enableNotCondition ? true : undefined };
this.trigger('actionBegin', args);
}
else if (isNullOrUndefined(prevElem) && ruleElem.id !== this.element.id + '_group0_rule0') {
const group = ruleElem.closest('.e-group-container');
if (group && group.previousElementSibling && group.previousElementSibling.previousElementSibling) {
let prevElem = group.previousElementSibling.previousElementSibling;
if (prevElem.classList.contains('e-group-container')) {
const ruleContainer = prevElem.querySelectorAll('.e-rule-container');
prevElem = ruleContainer[ruleContainer.length - 1];
}
if (prevElem.classList.contains('e-rule-container')) {
const prevRule = this.getRule(prevElem);
const args = { requestType: 'rule-template-create', ruleID: prevElem.id,
condition: prevRule.condition, notCondition: this.enableNotCondition ? true : undefined };
this.trigger('actionBegin', args);
}
}
}
this.setMultiConnector(ruleElem);
}
}
dropdownTreeFiltering(args) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const proxy = this;
let ruleElemID = '';
const srcElement = args.event.srcElement;
const isClearIcon = srcElement.classList.contains('e-clear-icon');
const inputElem = isClearIcon ? srcElement.parentElement.querySelector('.e-textbox') : srcElement;
ruleElemID = inputElem.id.split('_filterkey')[0];
const ruleElem = document.getElementById(ruleElemID);
this.ddTree = getComponent(ruleElem.querySelector('input.e-dropdowntree'), 'dropdowntree');
const hierarchicalData = extend([], this.columns, [], true);
// Cancel the default filtering.
args.cancel = true;
if (args.text === '') {
this.changeDataSource(hierarchicalData);
}
else {
const matchedDataSource = hierarchicalData
.map((data) => this.nestedChildFilter(args.text, data))
.filter((filteredChild) => filteredChild !== null);
this.changeDataSource(matchedDataSource);
setTimeout(() => {
if (!isNullOrUndefined(proxy.ddTree) && !isNullOrUndefined(proxy.ddTree.treeObj)) {
proxy.ddTree.treeObj.expandAll();
}
}, 100);
}
}
changeDataSource(data) {
this.updateDropdowntreeDS(data);
this.ddTree.treeObj.fields = {
dataSource: data,
value: 'field',
text: 'label',
child: 'columns',
expanded: 'expanded'
};
this.ddTree.treeObj.refresh();
}
nestedChildFilter(value, node) {
const children = node[this.ddTree.fields.child];
if (!children) {
return this.isMatchedNode(value, node) ? node : null;
}
const matchedChildren = children
.map((child) => this.nestedChildFilter(value, child))
.filter((filteredChild) => filteredChild !== null);
if (matchedChildren.length) {
node[this.ddTree.fields.child] = matchedChildren;
return node;
}
else {
node[this.ddTree.fields.child] = children;
return this.isMatchedNode(value, node) ? node : null;
}
}
isMatchedNode(value, node) {
const checkValue = node[this.ddTree.fields.text].toLowerCase();
value = value ? value.toLowerCase() : '';
return checkValue.indexOf(value) !== -1;
}
dropdownTreeClose() {
if (this.ddTree) {
this.changeDataSource(extend([], this.columns, [], true));
}
this.ddTree = null;
}
updateDropdowntreeDS(columns) {
for (let i = 0; i < columns.length; i++) {
if (columns[parseInt(i.toString(), 10)].type === 'object') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (this.isAngular && columns[parseInt(i.toString(), 10)].template) {
delete columns[parseInt(i.toString(), 10)].template;
}
columns[parseInt(i.toString(), 10)].selectable = false;
this.updateDropdowntreeDS(columns[parseInt(i.toString(), 10)].columns);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}
else if (this.isAngular && columns[parseInt(i.toString(), 10)].template) {
delete columns[parseInt(i.toString(), 10)].template;
}
}
}
updateAddedRule(target, rule, newRule, isRuleTemplate, pId, isNewRuleAdded) {
let ruleElem;
let index = 0;
let groupElem;
let rules;
if (isRuleTemplate) {
ruleElem = select('#' + pId, target);
groupElem = closest(target, '.e-group-container');
rules = this.getParentGroup(groupElem);
while (ruleElem && ruleElem.previousElementSibling !== null) {
ruleElem = ruleElem.previousElementSibling;
const enableSeparateCondition = this.enableSeparateConnector && ((!this.headerTemplate && !ruleElem.classList.contains('e-btn-group')) ||
(this.headerTemplate && (ruleElem.classList.contains('e-rule-container') ||
ruleElem.classList.contains('e-group-container'))));
if (!this.enableSeparateConnector || enableSeparateCondition) {
index++;
}
}
rules.rules[index] = rule;
}
else {
groupElem = closest(target, '.e-group-container');
rules = this.getParentGroup(groupElem);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const custom = rule.custom;
if (Object.keys(rule).length) {
if (this.ruleIndex < 0) {
rules.rules.push({
'field': rule.field, 'type': rule.type, 'label': rule.label, 'operator': rule.operator, value: rule.value
});
if (custom) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rules.rules[rules.rules.length - 1].custom = custom;
}
if (this.enableSeparateConnector) {
rules.rules[rules.rules.length - 1].condition = rule.condition ? rule.condition : newRule.condition;
}
}
else {
rules.rules.splice(this.ruleIndex + 1, 0, {
'field': rule.f