UNPKG

@syncfusion/ej2-querybuilder

Version:
1,066 lines (1,065 loc) 378 kB
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