UNPKG

@progress/kendo-angular-filter

Version:
1,049 lines (1,033 loc) 121 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import * as i0 from '@angular/core'; import { Injectable, Directive, Component, Input, ContentChild, EventEmitter, Output, isDevMode, forwardRef, ViewChildren, HostListener, HostBinding, ContentChildren, NgModule } from '@angular/core'; import * as i1 from '@progress/kendo-angular-l10n'; import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n'; import { validatePackage } from '@progress/kendo-licensing'; import { Keys, TemplateContextDirective, ResizeBatchService } from '@progress/kendo-angular-common'; import { xIcon, filterAddGroupIcon, filterAddExpressionIcon } from '@progress/kendo-svg-icons'; import { ButtonComponent } from '@progress/kendo-angular-buttons'; import { DatePickerComponent, DatePickerCustomMessagesComponent, CalendarDOMService, CenturyViewService, DecadeViewService, MonthViewService, YearViewService, TimePickerDOMService, HoursService, MinutesService, SecondsService, MillisecondsService, DayPeriodService } from '@progress/kendo-angular-dateinputs'; import { DropDownListComponent, ValueTemplateDirective, ItemTemplateDirective } from '@progress/kendo-angular-dropdowns'; import { NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent, TextBoxComponent } from '@progress/kendo-angular-inputs'; import { NgIf, NgSwitch, NgSwitchCase, NgFor, NgClass } from '@angular/common'; import { IconsService } from '@progress/kendo-angular-icons'; import { PopupService } from '@progress/kendo-angular-popup'; import { DialogContainerService, DialogService, WindowService, WindowContainerService, NavigationService as NavigationService$1 } from '@progress/kendo-angular-dialog'; /** * @hidden */ class FilterService { normalizedValue = { logic: 'and', filters: [] }; filters = []; addFilterGroup(item) { const filterGroup = { logic: 'and', filters: [] }; item.filters.push(filterGroup); } addFilterExpression(item) { const filterExpression = { operator: 'eq', value: null, field: null }; item.filters.push(filterExpression); } remove(item, positionIndex, parentItem) { if (!parentItem) { parentItem = this.normalizedValue; } if (item === parentItem) { parentItem.filters = []; return; } const index = parentItem.filters.indexOf(item); if (index >= 0 && index === positionIndex) { parentItem.filters = parentItem.filters.filter((i) => i !== item); return; } parentItem.filters.forEach((filter) => filter.filters && this.remove(item, positionIndex, filter)); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterService, decorators: [{ type: Injectable }] }); /** * @hidden */ const nullOperators = ["isnull", "isnotnull", "isempty", "isnotempty"]; /** * @hidden */ const numericOperators = [ { text: "Is equal to", value: "eq" }, { text: "Not equal to", value: "neq" }, { text: "Greater than or equal to", value: "gte" }, { text: "Greater than", value: "gt" }, { text: "Less than or equal to", value: "lte" }, { text: "Less than", value: "lt" }, { text: "Is null", value: "isnull" }, { text: "Is not null", value: "isnotnull" } ]; /** * @hidden */ const stringOperators = [ { text: "Is equal to", value: "eq" }, { text: "Not equal to", value: "neq" }, { text: "Contains", value: "contains" }, { text: "Does not contain", value: "doesnotcontain" }, { text: "Starts with", value: "startswith" }, { text: "Ends with", value: "endswith" }, { text: "Is null", value: "isnull" }, { text: "Is not null", value: "isnotnull" }, { text: "Is empty", value: "isempty" }, { text: "Is not empty", value: "isnotempty" } ]; /** * @hidden */ const booleanOperators = [ { text: "Is equal to", value: "eq" }, { text: "Is not equal to", value: "neq" } ]; /** * @hidden */ const dateOperators = [ { text: "Is equal to", value: "eq" }, { text: "Not equal to", value: "neq" }, { text: "Greater than or equal to", value: "gte" }, { text: "Greater than", value: "gt" }, { text: "Less than or equal to", value: "lte" }, { text: "Less than", value: "lt" }, { text: "Is null", value: "isnull" }, { text: "Is not null", value: "isnotnull" } ]; /** * @hidden */ const isArray = (value) => Array.isArray(value); /** * @hidden */ const getKeyByValue = (object, value) => { return object && Object.keys(object).find(key => object[key] === value); }; /** * @hidden */ const defaultStringOperators = { "filterEqOperator": "eq", "filterNotEqOperator": "neq", "filterContainsOperator": "contains", "filterNotContainsOperator": "doesnotcontain", "filterStartsWithOperator": "startswith", "filterEndsWithOperator": "endswith", "filterIsNullOperator": "isnull", "filterIsNotNullOperator": "isnotnull", "filterIsEmptyOperator": "isempty", "filterIsNotEmptyOperator": "isnotempty" }; /** * @hidden */ const defaultNumericOperators = { "filterEqOperator": "eq", "filterNotEqOperator": "neq", "filterGteOperator": "gte", "filterGtOperator": "gt", "filterLteOperator": "lte", "filterLtOperator": "lt", "filterIsNullOperator": "isnull", "filterIsNotNullOperator": "isnotnull" }; /** * @hidden */ const defaultDateOperators = { "filterEqOperator": "eq", "filterNotEqOperator": "neq", "filterAfterOrEqualOperator": "gte", "filterAfterOperator": "gt", "filterBeforeOrEqualOperator": "lte", "filterBeforeOperator": "lt", "filterIsNullOperator": "isnull", "filterIsNotNullOperator": "isnotnull" }; /** * @hidden */ const defaultOperators = { "string": defaultStringOperators, "number": defaultNumericOperators, "date": defaultDateOperators }; /** * @hidden */ const logicOperators = { "filterAndLogic": 'and', "filterOrLogic": 'or' }; /** * @hidden */ const isFilterEditor = (editorType) => { const supportedEditorTypes = ['string', 'number', 'boolean', 'date']; return supportedEditorTypes.indexOf(editorType) >= 0; }; /** * @hidden */ const localizeOperators = operators => localization => Object.keys(operators).map(key => ({ text: localization.get(key), value: operators[key] })); /** * @hidden */ const isPresent = (value) => value !== null && value !== undefined; /** * @hidden */ class FilterItem { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterItem, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterItem }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterItem, decorators: [{ type: Injectable }] }); /** * @hidden */ const selectors = { andButton: `button.k-group-start`, orButton: `button.k-group-end`, addFilterButton: `button[icon="filter-add-expression"]`, addGroupButton: `button[icon="filter-add-group"]`, removeButton: `button[icon="x"]`, filterFieldWrapper: `.k-filter-field`, filterOperatorWrapper: `.k-filter-operator`, filterValueEditorWrapper: `.k-filter-value`, kendoDropDownListComponent: `kendo-dropdownlist`, kendoInput: `.k-input`, kendoInputInner: `.k-input-inner`, inputElement: `input`, textAreaElement: `textarea`, kendoToolbar: `.k-toolbar`, kendoButton: `.k-button`, kendoFilterToolbarItem: `.k-toolbar-item`, kendoFilterToolbarButton: `.k-toolbar-button` }; /** * @hidden */ const packageMetadata = { name: '@progress/kendo-angular-filter', productName: 'Kendo UI for Angular', productCode: 'KENDOUIANGULAR', productCodes: ['KENDOUIANGULAR'], publishDate: 1751463369, version: '19.2.0', licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/' }; /** * Directive for providing a custom value editor template in the Filter component. * Used as a structural directive to customize the filter value editor UI. * * @example * ```html * <ng-template kendoFilterValueEditorTemplate let-value> * <!-- custom editor markup --> * </ng-template> * ``` */ class FilterValueEditorTemplateDirective { templateRef; constructor(templateRef) { this.templateRef = templateRef; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterValueEditorTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterValueEditorTemplateDirective, isStandalone: true, selector: "[kendoFilterValueEditorTemplate]", ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterValueEditorTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoFilterValueEditorTemplate]', standalone: true }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } }); /** * Represents the [Kendo UI Filter Field component for Angular]({% slug api_filter_filterfieldcomponent %}). * Used to declare filter expressions for the Filter component. * * @example * ```html * <kendo-filter> * <kendo-filter-field field="country" editor="string" [operators]="['neq', 'eq', 'contains']"></kendo-filter-field> * <kendo-filter-field field="budget" editor="number"></kendo-filter-field> * <kendo-filter-field field="discontinued" title="Discontinued" editor="boolean"></kendo-filter-field> * <kendo-filter-field field="ordered on" title="Ordered on" editor="date"></kendo-filter-field> * <kendo-filter> * ``` */ class FilterFieldComponent { /** * Specifies the `field` that will be used by the user-defined filter. */ field; /** * Specifies the `title` text that will be displayed by the user-defined filter. * If the `title` isn't set, the value passed to `field` is used. */ set title(_title) { if (_title) { this._title = _title; } else { this._title = this.field; } } get title() { return this._title; } _title; /** * Specifies the user-defined filter `editor` type that will be used. * The available options are 'string', 'number', 'boolean', and 'date'. */ editor; /** * Specifies the operators that will be available in the order of providing them. * If no operators are provided, default operators are used for each filter type. * * The default string operators are: * * `eq`&mdash; Is equal to * * `neq`&mdash; Is not equal to * * `isnull`&mdash; Is null * * `isnotnull`&mdash; Is not null * * `contains`&mdash; Contains * * `doesnotcontain`&mdash; Does not contain * * `startswith`&mdash; Starts with * * `endswith`&mdash; Ends with * * `isempty`&mdash; Is empty * * `isnotempty`&mdash; Is not empty * * The default number and date operators are: * * `eq`&mdash; Is equals to * * `neq`&mdash; Is not equal to * * `isnull`&mdash; Is null * * `isnotnull`&mdash; Is not null * * `gt`&mdash; Greater than * * `gte`&mdash; Greater than or equal to * * `lt`&mdash; Less than * * `lte`&mdash; Less than or equal to * * The boolean operator is always set to `eq` */ operators; /** * Specifies the user-defined filter `editor` format that will be used. ([see example]({% slug filter_editor_formats %})) */ editorFormat; /** * @hidden */ editorTemplate; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterFieldComponent, isStandalone: true, selector: "kendo-filter-field", inputs: { field: "field", title: "title", editor: "editor", operators: "operators", editorFormat: "editorFormat" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: FilterValueEditorTemplateDirective, descendants: true }], ngImport: i0, template: ``, isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterFieldComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-filter-field', template: ``, standalone: true }] }], propDecorators: { field: [{ type: Input }], title: [{ type: Input }], editor: [{ type: Input }], operators: [{ type: Input }], editorFormat: [{ type: Input }], editorTemplate: [{ type: ContentChild, args: [FilterValueEditorTemplateDirective] }] } }); /** * @hidden */ class NavigationService { cdr; renderer; hierarchicalFilterItems = []; flattenFilterItems = []; currentToolbarItemIndex = 0; currentToolbarItemChildrenIndex = 0; isFilterNavigationActivated = true; isFilterExpressionComponentFocused = false; currentlyFocusedElement; constructor(cdr, renderer) { this.cdr = cdr; this.renderer = renderer; } processKeyDown(key, event) { switch (key) { case Keys.ArrowUp: { event.preventDefault(); if (!this.isFilterExpressionComponentFocused) { this.currentToolbarItemChildrenIndex = 0; if (this.currentToolbarItemIndex > 0) { this.currentToolbarItemIndex--; } const elementToFocus = this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren[0]; this.focusCurrentElement(elementToFocus); } break; } case Keys.ArrowDown: { event.preventDefault(); if (!this.isFilterExpressionComponentFocused) { this.currentToolbarItemChildrenIndex = 0; if (this.currentToolbarItemIndex < this.flattenFilterItems.length - 1) { this.currentToolbarItemIndex++; } const elementToFocus = this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren[0]; this.focusCurrentElement(elementToFocus); } break; } case Keys.Enter: { const isEventTargetKendoFilterToolbarItem = event.target.closest(selectors.kendoFilterToolbarItem); const isEventTargetButton = event.target.closest(selectors.kendoButton); if (this.isFilterNavigationActivated && !this.isFilterExpressionComponentFocused && isEventTargetKendoFilterToolbarItem && !isEventTargetButton) { event.preventDefault(); this.isFilterExpressionComponentFocused = true; const focusableElement = this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren[this.currentToolbarItemChildrenIndex]; const elementToFocus = focusableElement.querySelector(selectors.KendoDropDownListComponent) || focusableElement.querySelector(selectors.kendoInputInner) || focusableElement.querySelector(selectors.inputElement) || focusableElement.querySelector(selectors.textAreaElement); this.focusCurrentElement(elementToFocus); } break; } case Keys.Escape: { if (this.isFilterExpressionComponentFocused) { event.preventDefault(); this.isFilterExpressionComponentFocused = false; const elementToFocus = this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren[this.currentToolbarItemChildrenIndex]; this.focusCurrentElement(elementToFocus); } break; } case Keys.ArrowRight: { if (this.isFilterNavigationActivated && !this.isFilterExpressionComponentFocused) { event.preventDefault(); if (this.currentToolbarItemChildrenIndex < this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren.length - 1) { this.currentToolbarItemChildrenIndex++; } const elementToFocus = this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren[this.currentToolbarItemChildrenIndex]; this.focusCurrentElement(elementToFocus); } break; } case Keys.ArrowLeft: { if (this.isFilterNavigationActivated && !this.isFilterExpressionComponentFocused) { event.preventDefault(); if (this.currentToolbarItemChildrenIndex > 0) { this.currentToolbarItemChildrenIndex--; } const elementToFocus = this.flattenFilterItems[this.currentToolbarItemIndex].focusableChildren[this.currentToolbarItemChildrenIndex]; this.focusCurrentElement(elementToFocus); } break; } default: break; } } focusCurrentElement(element, isOnMouseDown) { this.renderer.setAttribute(this.currentlyFocusedElement, 'tabindex', '-1'); this.currentlyFocusedElement = element; if (element) { this.renderer.setAttribute(this.currentlyFocusedElement, 'tabindex', '0'); if (!isOnMouseDown) { this.currentlyFocusedElement.focus(); } } } flattenHierarchicalFilterItems(filterItems) { filterItems.forEach((filterRow) => { const flattenItem = { component: filterRow, isGroup: false, toolbarElement: filterRow.toolbarElement, focusableChildren: [] }; this.flattenFilterItems.push(flattenItem); if ((filterRow['operators'] && filterRow['filterItems']?.length > 0)) { this.setGroupItemChildren(flattenItem, filterRow); this.flattenHierarchicalFilterItems(filterRow['filterItems']); } else if (filterRow['operators'] && filterRow['filterItems']?.length === 0) { this.setGroupItemChildren(flattenItem, filterRow); } else { flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.filterFieldWrapper)); if (filterRow.toolbarElement.querySelector('.k-filter-operator')) { flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.filterOperatorWrapper)); } flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.filterValueEditorWrapper)); flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.removeButton)); } }); } setGroupItemChildren(flattenItem, filterRow) { flattenItem.isGroup = true; flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.andButton)); flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.orButton)); flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.addFilterButton)); flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.addGroupButton)); flattenItem.focusableChildren.push(filterRow.toolbarElement.querySelector(selectors.removeButton)); } setItemIndexes() { this.flattenFilterItems.forEach((item, index) => { item.component['itemNumber'] = index; }); this.cdr.detectChanges(); } reset(items) { this.flattenFilterItems = []; this.hierarchicalFilterItems = items; this.flattenHierarchicalFilterItems(items); this.setItemIndexes(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; } }); /** * @hidden */ const FilterErrorMessages = { missingFilters: `Pass at least one user-defined filter through the [filters] input property or nest kendo-filter-field components. See https://www.telerik.com/kendo-angular-ui/components/filter/#data-binding`, missingFilterForUsedField: (field) => `There is no user-defined filter with '${field}' field provided through the [filters] input property.`, missingValueForBooleanField: (field) => `Provide a value for the boolean '${field}' user-defined filter as the operator is always set to 'eq'.`, operatorBooleanField: (field) => `The operator of the boolean '${field}' user-defined filter is always set to 'eq'.`, filterMissingUsedOperator: (field, operator) => `The user-defined filter with field '${field}' is missing the '${operator}' operator.`, improperNumericEditorValue: (title) => `The provided value for the numeric editor of the '${title}' filter expression isn't one of a supported type string or NumberFormat. See https://www.telerik.com/kendo-angular-ui/components/filter/#editor-formats/`, improperDateEditorValue: (title) => `The provided value for the date editor of the '${title}' filter expression isn't one of a supported type string or DateFormat. See https://www.telerik.com/kendo-angular-ui/components/filter/#editor-formats/` }; /** * @hidden */ class BaseFilterRowComponent { element; navigationService; localization; renderer; index; valueChange = new EventEmitter(); constructor(element, navigationService, localization, renderer) { this.element = element; this.navigationService = navigationService; this.localization = localization; this.renderer = renderer; } itemNumber = 0; get toolbarElement() { return this.element.nativeElement.querySelector('.k-toolbar'); } messageFor(key) { return this.localization.get(key); } onMouseDown(event) { let elementToFocus; const closestFilterToolbarItem = event.target.closest(selectors.kendoFilterToolbarItem); const closestButton = event.target.closest(selectors.kendoFilterToolbarButton); const closestToolbarItem = event.target.closest(selectors.kendoToolbar); if (closestFilterToolbarItem || closestButton) { const index = Array.from(closestToolbarItem.children).indexOf(closestFilterToolbarItem) > -1 ? Array.from(closestToolbarItem.children).indexOf(closestFilterToolbarItem) : Array.from(closestToolbarItem.children).indexOf(closestButton); this.navigationService.currentToolbarItemChildrenIndex = index; this.navigationService.isFilterNavigationActivated = true; this.navigationService.isFilterExpressionComponentFocused = true; const wrapperElement = this.navigationService.flattenFilterItems[this.itemNumber].focusableChildren[index]; elementToFocus = wrapperElement.querySelector(selectors.kendoDropDownListComponent) || wrapperElement.querySelector(selectors.kendoInput) || wrapperElement.querySelector(selectors.kendoInputInner) || wrapperElement.querySelector(selectors.inputElement) || wrapperElement.querySelector(selectors.textAreaElement) || wrapperElement.querySelector(selectors.kendoButton) || wrapperElement; } else { this.navigationService.currentToolbarItemChildrenIndex = 0; this.navigationService.isFilterNavigationActivated = false; this.navigationService.isFilterExpressionComponentFocused = false; elementToFocus = this.navigationService.flattenFilterItems[this.itemNumber].focusableChildren[0]; } this.navigationService.currentToolbarItemIndex = this.itemNumber; this.navigationService.focusCurrentElement(elementToFocus, true); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BaseFilterRowComponent, deps: [{ token: i0.ElementRef }, { token: NavigationService }, { token: i1.LocalizationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: BaseFilterRowComponent, inputs: { index: "index" }, outputs: { valueChange: "valueChange" }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BaseFilterRowComponent, decorators: [{ type: Directive, args: [{}] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: NavigationService }, { type: i1.LocalizationService }, { type: i0.Renderer2 }]; }, propDecorators: { index: [{ type: Input }], valueChange: [{ type: Output }] } }); /** * @hidden */ class AriaLabelValueDirective { hostElement; renderer; ariaLabel; constructor(hostElement, renderer) { this.hostElement = hostElement; this.renderer = renderer; } ngOnInit() { const target = this.hostElement.nativeElement.querySelector('input') || this.hostElement.nativeElement; this.renderer.setAttribute(target, 'aria-label', this.ariaLabel); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AriaLabelValueDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: AriaLabelValueDirective, isStandalone: true, selector: "[kendoAriaLabelValue]", inputs: { ariaLabel: ["kendoAriaLabelValue", "ariaLabel"] }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AriaLabelValueDirective, decorators: [{ type: Directive, args: [{ selector: '[kendoAriaLabelValue]', standalone: true }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { ariaLabel: [{ type: Input, args: ['kendoAriaLabelValue'] }] } }); /** * @hidden */ class FilterDateEditorComponent { localization; currentItem; isDisabled; format; valueChange = new EventEmitter(); constructor(localization) { this.localization = localization; } messageFor(key) { return this.localization.get(key); } onValueChange(value) { this.currentItem.value = value; this.valueChange.emit(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterDateEditorComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterDateEditorComponent, isStandalone: true, selector: "kendo-filter-date-editor", inputs: { currentItem: "currentItem", isDisabled: "isDisabled", format: "format" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: ` <kendo-datepicker [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [disabled]="isDisabled" [format]="format"> <kendo-datepicker-messages [toggle]="messageFor('editorDateToggleText')" [today]="messageFor('editorDateTodayText')"> </kendo-datepicker-messages> </kendo-datepicker> `, isInline: true, dependencies: [{ kind: "component", type: DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "adaptiveTitle", "adaptiveSubtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "component", type: DatePickerCustomMessagesComponent, selector: "kendo-datepicker-messages" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterDateEditorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-filter-date-editor', template: ` <kendo-datepicker [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [disabled]="isDisabled" [format]="format"> <kendo-datepicker-messages [toggle]="messageFor('editorDateToggleText')" [today]="messageFor('editorDateTodayText')"> </kendo-datepicker-messages> </kendo-datepicker> `, standalone: true, imports: [DatePickerComponent, AriaLabelValueDirective, DatePickerCustomMessagesComponent] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { currentItem: [{ type: Input }], isDisabled: [{ type: Input }], format: [{ type: Input }], valueChange: [{ type: Output }] } }); /** * @hidden */ class FilterBooleanEditorComponent { localization; cdr; currentItem; valueChange = new EventEmitter(); items; defaultItem; localizationSubscription; constructor(localization, cdr) { this.localization = localization; this.cdr = cdr; } ngOnInit() { this.localizationSubscription = this.localization.changes.subscribe(() => { this.defaultItem = this.getDefaultItem(); this.items = this.getValueItems(); this.cdr.detectChanges(); }); this.items = this.getValueItems(); this.defaultItem = this.getDefaultItem(); } getDefaultItem() { return { text: this.localization.get("filterBooleanAll"), value: null }; } getValueItems() { return [ { text: this.localization.get("filterIsTrue"), value: true }, { text: this.localization.get("filterIsFalse"), value: false } ]; } ngOnDestroy() { if (this.localizationSubscription) { this.localizationSubscription.unsubscribe(); } } messageFor(key) { return this.localization.get(key); } onValueChange(value) { this.currentItem.value = value; this.valueChange.emit(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterBooleanEditorComponent, deps: [{ token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterBooleanEditorComponent, isStandalone: true, selector: "kendo-filter-boolean-editor", inputs: { currentItem: "currentItem" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: ` <kendo-dropdownlist [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [data]="items" [defaultItem]="defaultItem" [valuePrimitive]="true" textField="text" valueField="value" > </kendo-dropdownlist> `, isInline: true, dependencies: [{ kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterBooleanEditorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-filter-boolean-editor', template: ` <kendo-dropdownlist [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [data]="items" [defaultItem]="defaultItem" [valuePrimitive]="true" textField="text" valueField="value" > </kendo-dropdownlist> `, standalone: true, imports: [DropDownListComponent, AriaLabelValueDirective] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { currentItem: [{ type: Input }], valueChange: [{ type: Output }] } }); /** * @hidden */ class FilterNumericEditorComponent { localization; currentItem; isDisabled; format; valueChange = new EventEmitter(); constructor(localization) { this.localization = localization; } messageFor(key) { return this.localization.get(key); } onValueChange(value) { this.currentItem.value = value; this.valueChange.emit(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterNumericEditorComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterNumericEditorComponent, isStandalone: true, selector: "kendo-filter-numeric-editor", inputs: { currentItem: "currentItem", isDisabled: "isDisabled", format: "format" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: ` <kendo-numerictextbox [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [disabled]="isDisabled" [format]="format"> <kendo-numerictextbox-messages [increment]="messageFor('editorNumericIncrement')" [decrement]="messageFor('editorNumericDecrement')"> </kendo-numerictextbox-messages> </kendo-numerictextbox> `, isInline: true, dependencies: [{ kind: "component", type: NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "component", type: NumericTextBoxCustomMessagesComponent, selector: "kendo-numerictextbox-messages" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterNumericEditorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-filter-numeric-editor', template: ` <kendo-numerictextbox [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [disabled]="isDisabled" [format]="format"> <kendo-numerictextbox-messages [increment]="messageFor('editorNumericIncrement')" [decrement]="messageFor('editorNumericDecrement')"> </kendo-numerictextbox-messages> </kendo-numerictextbox> `, standalone: true, imports: [NumericTextBoxComponent, AriaLabelValueDirective, NumericTextBoxCustomMessagesComponent] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { currentItem: [{ type: Input }], isDisabled: [{ type: Input }], format: [{ type: Input }], valueChange: [{ type: Output }] } }); /** * @hidden */ class FilterTextEditorComponent { localization; currentItem; isDisabled; valueChange = new EventEmitter(); constructor(localization) { this.localization = localization; } messageFor(key) { return this.localization.get(key); } onValueChange(value) { this.currentItem.value = value; this.valueChange.emit(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterTextEditorComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterTextEditorComponent, isStandalone: true, selector: "kendo-filter-text-editor", inputs: { currentItem: "currentItem", isDisabled: "isDisabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: ` <kendo-textbox [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [disabled]="isDisabled"> </kendo-textbox> `, isInline: true, dependencies: [{ kind: "component", type: TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterTextEditorComponent, decorators: [{ type: Component, args: [{ selector: 'kendo-filter-text-editor', template: ` <kendo-textbox [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')" [value]="currentItem.value" (valueChange)="onValueChange($event)" [disabled]="isDisabled"> </kendo-textbox> `, standalone: true, imports: [TextBoxComponent, AriaLabelValueDirective] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { currentItem: [{ type: Input }], isDisabled: [{ type: Input }], valueChange: [{ type: Output }] } }); /** * @hidden */ class FilterExpressionOperatorsComponent { localization; currentItem; editorType; valueChange = new EventEmitter(); operators = []; constructor(localization) { this.localization = localization; } messageFor(key) { return this.localization.get(key); } getOperator(operatorValue) { return this.messageFor(getKeyByValue(defaultOperators[this.editorType], operatorValue)); } operatorValueChange(value) { this.valueChange.emit(value); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterExpressionOperatorsComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterExpressionOperatorsComponent, isStandalone: true, selector: "kendo-filter-expression-operators", inputs: { currentItem: "currentItem", editorType: "editorType", operators: "operators" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: ` <kendo-dropdownlist [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')" [data]="operators" [title]="messageFor('filterExpressionOperators')" [(value)]="currentItem.operator" (valueChange)="operatorValueChange($event)" [valuePrimitive]="true" textField="text" valueField="value" > <ng-template kendoDropDownListValueTemplate let-dataItem> <span>{{ getOperator(dataItem.value) }}</span> </ng-template> <ng-template kendoDropDownListItemTemplate let-dataItem> <span>{{ getOperator(dataItem.value) }}</span> </ng-template> </kendo-dropdownlist> `, isInline: true, dependencies: [{ kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "directive", type: ValueTemplateDirective, selector: "[kendoDropDownListValueTemplate],[kendoDropDownTreeValueTemplate]" }, { kind: "directive", type: ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterExpressionOperatorsComponent, decorators: [{ type: Component, args: [{ selector: "kendo-filter-expression-operators", template: ` <kendo-dropdownlist [tabindex]="-1" [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')" [data]="operators" [title]="messageFor('filterExpressionOperators')" [(value)]="currentItem.operator" (valueChange)="operatorValueChange($event)" [valuePrimitive]="true" textField="text" valueField="value" > <ng-template kendoDropDownListValueTemplate let-dataItem> <span>{{ getOperator(dataItem.value) }}</span> </ng-template> <ng-template kendoDropDownListItemTemplate let-dataItem> <span>{{ getOperator(dataItem.value) }}</span> </ng-template> </kendo-dropdownlist> `, standalone: true, imports: [DropDownListComponent, AriaLabelValueDirective, ValueTemplateDirective, ItemTemplateDirective] }] }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { currentItem: [{ type: Input }], editorType: [{ type: Input }], valueChange: [{ type: Output }], operators: [{ type: Input }] } }); /** * @hidden */ class FilterExpressionComponent extends BaseFilterRowComponent { filterService; cdr; /** * @hidden */ xIcon = xIcon; static ngAcceptInputType_currentItem; currentItem; operators = []; isBoolean = false; editorType; isEditorDisabled = false; editorTemplate; editorFormat; get currentFilterExpression() { return this.getFilterExpressionByField(this.currentItem.field); } get numericEditorFormat() { const isSupportedFormat = typeof this.editorFormat !== 'string' && !this.isNumberFormat(this.editorFormat); if (this.editorFormat && isSupportedFormat) { console.warn(FilterErrorMessages.improperNumericEditorValue(this.currentFilterExpression.title)); } return this.editorFormat; } get dateEditorFormat() { const isSupportedFormat = typeof this.editorFormat !== 'string' && !this.isDateFormat(this.editorFormat); if (this.editorFormat && isSupportedFormat) { console.warn(FilterErrorMessages.improperDateEditorValue(this.currentFilterExpression.title)); } return this.editorFormat; } isNumberFormat(obj) { if (isDevMode() && obj && (obj['currency'] || obj['currencyDisplay'] || obj['maximumFractionDigits'] || obj['minimumIntegerDigits'] || obj['style'] || obj['useGrouping'])) { return true; } else { return false; } } isDateFormat(obj) { if (isDevMode() && obj && obj['displayFormat'] && obj['inputFormat']) { return true; } else { return false; } } localizationSubscription; constructor(filterService, cdr, element, navigationService, localization, renderer) { super(element, navigationService, localization, renderer); this.filterService = filterService; this.cdr = cdr; } ngOnInit() { this.isEditorDisabled = nullOperators.indexOf(this.currentItem.operator) >= 0; const foundFilter = this.getFilterExpressionByField(this.currentItem.field); if (this.currentItem.field) {