@progress/kendo-angular-filter 2.0.1-dev.202205190755 → 2.1.0-dev.202206150812

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import * as i0 from '@angular/core';
6
- import { Injectable, Directive, Input, EventEmitter, Component, Output, forwardRef, isDevMode, HostBinding, NgModule } from '@angular/core';
6
+ import { Injectable, Directive, Component, Input, ContentChild, EventEmitter, Output, forwardRef, isDevMode, HostBinding, ContentChildren, NgModule } from '@angular/core';
7
7
  import * as i1 from '@progress/kendo-angular-l10n';
8
8
  import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
9
9
  import { validatePackage } from '@progress/kendo-licensing';
@@ -24,10 +24,11 @@ import { LabelModule } from '@progress/kendo-angular-label';
24
24
  */
25
25
  class FilterService {
26
26
  constructor() {
27
+ this.normalizedValue = { logic: 'and', filters: [] };
27
28
  this.filters = [];
28
29
  }
29
30
  addFilterGroup(item) {
30
- let filterGroup = { logic: 'or', filters: [] };
31
+ let filterGroup = { logic: 'and', filters: [] };
31
32
  item.filters.push(filterGroup);
32
33
  }
33
34
  addFilterExpression(item) {
@@ -200,11 +201,86 @@ const packageMetadata = {
200
201
  name: '@progress/kendo-angular-filter',
201
202
  productName: 'Kendo UI for Angular',
202
203
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
203
- publishDate: 1652946928,
204
+ publishDate: 1655280742,
204
205
  version: '',
205
206
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
206
207
  };
207
208
 
209
+ class FilterValueEditorTemplateDirective {
210
+ constructor(templateRef) {
211
+ this.templateRef = templateRef;
212
+ }
213
+ }
214
+ FilterValueEditorTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterValueEditorTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
215
+ FilterValueEditorTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.16", type: FilterValueEditorTemplateDirective, selector: "[kendoFilterValueEditorTemplate]", ngImport: i0 });
216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterValueEditorTemplateDirective, decorators: [{
217
+ type: Directive,
218
+ args: [{
219
+ selector: '[kendoFilterValueEditorTemplate]'
220
+ }]
221
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
222
+
223
+ /**
224
+ * Represents the [Kendo UI Filter Field component for Angular]({% slug api_filter_filterfieldcomponent %}).
225
+ * The Filter Field component can be used to add Filter Expressions declaratively.
226
+ * @example
227
+ * ```
228
+ * @Component({
229
+ * selector: 'my-app',
230
+ * template: `
231
+ * <kendo-filter (valueChange)="onValueChange($event)">
232
+ * <kendo-filter-field field="country" editor="string" [operators]="['neq', 'eq', 'contains']"></kendo-filter-field>
233
+ * <kendo-filter-field field="budget" editor="number"></kendo-filter-field>
234
+ * <kendo-filter-field field="discontinued" title="Discontinued" editor="boolean"></kendo-filter-field>
235
+ * <kendo-filter-field field="ordered on" title="Ordered on" editor="date"></kendo-filter-field>
236
+ * <kendo-filter>
237
+ * `
238
+ * })
239
+ * export class AppComponent {
240
+ * onValueChange(e: CompositeFilterDescriptor){
241
+ * console.log(e)
242
+ * }
243
+ * }
244
+ * ```
245
+ */
246
+ class FilterFieldComponent {
247
+ /**
248
+ * Specifies the `title` text that will be displayed by the user-defined filter.
249
+ * If the `title` isn't set, the value passed to `field` is used.
250
+ */
251
+ set title(_title) {
252
+ if (_title) {
253
+ this._title = _title;
254
+ }
255
+ else {
256
+ this._title = this.field;
257
+ }
258
+ }
259
+ get title() {
260
+ return this._title;
261
+ }
262
+ }
263
+ FilterFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
264
+ FilterFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterFieldComponent, selector: "kendo-filter-field", inputs: { field: "field", title: "title", editor: "editor", operators: "operators" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: FilterValueEditorTemplateDirective, descendants: true }], ngImport: i0, template: ``, isInline: true });
265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterFieldComponent, decorators: [{
266
+ type: Component,
267
+ args: [{
268
+ selector: 'kendo-filter-field',
269
+ template: ``
270
+ }]
271
+ }], propDecorators: { field: [{
272
+ type: Input
273
+ }], title: [{
274
+ type: Input
275
+ }], editor: [{
276
+ type: Input
277
+ }], operators: [{
278
+ type: Input
279
+ }], editorTemplate: [{
280
+ type: ContentChild,
281
+ args: [FilterValueEditorTemplateDirective]
282
+ }] } });
283
+
208
284
  /**
209
285
  * @hidden
210
286
  */
@@ -234,18 +310,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
234
310
  class FilterExpressionOperatorsComponent {
235
311
  constructor(localization) {
236
312
  this.localization = localization;
237
- this.operators = [];
238
313
  this.valueChange = new EventEmitter();
314
+ this.operators = [];
239
315
  }
240
316
  messageFor(key) {
241
317
  return this.localization.get(key);
242
318
  }
319
+ getOperator(operatorValue) {
320
+ return this.messageFor(getKeyByValue(defaultOperators[this.editorType], operatorValue));
321
+ }
243
322
  operatorValueChange(value) {
244
323
  this.valueChange.emit(value);
245
324
  }
246
325
  }
247
326
  FilterExpressionOperatorsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterExpressionOperatorsComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
248
- FilterExpressionOperatorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterExpressionOperatorsComponent, selector: "kendo-filter-expression-operators", inputs: { currentItem: "currentItem", operators: "operators" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
327
+ FilterExpressionOperatorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterExpressionOperatorsComponent, selector: "kendo-filter-expression-operators", inputs: { currentItem: "currentItem", editorType: "editorType", operators: "operators" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
249
328
  <kendo-dropdownlist
250
329
  [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')"
251
330
  [data]="operators"
@@ -256,8 +335,14 @@ FilterExpressionOperatorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersio
256
335
  textField="text"
257
336
  valueField="value"
258
337
  >
338
+ <ng-template kendoDropDownListValueTemplate let-dataItem>
339
+ {{ getOperator(dataItem.value) }}
340
+ </ng-template>
341
+ <ng-template kendoDropDownListItemTemplate let-dataItem>
342
+ {{ getOperator(dataItem.value) }}
343
+ </ng-template>
259
344
  </kendo-dropdownlist>
260
- `, isInline: true, components: [{ type: i2.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["iconClass", "loading", "data", "value", "textField", "valueField", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }], directives: [{ type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }] });
345
+ `, isInline: true, components: [{ type: i2.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["iconClass", "loading", "data", "value", "textField", "valueField", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }], directives: [{ type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { type: i2.ValueTemplateDirective, selector: "[kendoDropDownListValueTemplate],[kendoDropDownTreeValueTemplate]" }, { type: i2.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }] });
261
346
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterExpressionOperatorsComponent, decorators: [{
262
347
  type: Component,
263
348
  args: [{
@@ -273,15 +358,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
273
358
  textField="text"
274
359
  valueField="value"
275
360
  >
361
+ <ng-template kendoDropDownListValueTemplate let-dataItem>
362
+ {{ getOperator(dataItem.value) }}
363
+ </ng-template>
364
+ <ng-template kendoDropDownListItemTemplate let-dataItem>
365
+ {{ getOperator(dataItem.value) }}
366
+ </ng-template>
276
367
  </kendo-dropdownlist>
277
368
  `
278
369
  }]
279
370
  }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { currentItem: [{
280
371
  type: Input
281
- }], operators: [{
372
+ }], editorType: [{
282
373
  type: Input
283
374
  }], valueChange: [{
284
375
  type: Output
376
+ }], operators: [{
377
+ type: Input
285
378
  }] } });
286
379
 
287
380
  /**
@@ -300,7 +393,6 @@ FilterTextEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0"
300
393
  FilterTextEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterTextEditorComponent, selector: "kendo-filter-text-editor", inputs: { currentItem: "currentItem", isDisabled: "isDisabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
301
394
  <kendo-textbox
302
395
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
303
- class="k-filter-toolbar-item k-filter-value"
304
396
  [(value)]="currentItem.value"
305
397
  (valueChange)="valueChange.emit()"
306
398
  [disabled]="isDisabled">
@@ -313,7 +405,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
313
405
  template: `
314
406
  <kendo-textbox
315
407
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
316
- class="k-filter-toolbar-item k-filter-value"
317
408
  [(value)]="currentItem.value"
318
409
  (valueChange)="valueChange.emit()"
319
410
  [disabled]="isDisabled">
@@ -344,7 +435,6 @@ FilterNumericEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0
344
435
  FilterNumericEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterNumericEditorComponent, selector: "kendo-filter-numeric-editor", inputs: { currentItem: "currentItem", isDisabled: "isDisabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
345
436
  <kendo-numerictextbox
346
437
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
347
- class="k-filter-toolbar-item k-filter-value"
348
438
  [(value)]="currentItem.value"
349
439
  (valueChange)="valueChange.emit()"
350
440
  [disabled]="isDisabled">
@@ -361,7 +451,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
361
451
  template: `
362
452
  <kendo-numerictextbox
363
453
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
364
- class="k-filter-toolbar-item k-filter-value"
365
454
  [(value)]="currentItem.value"
366
455
  (valueChange)="valueChange.emit()"
367
456
  [disabled]="isDisabled">
@@ -420,7 +509,6 @@ FilterBooleanEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0
420
509
  FilterBooleanEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterBooleanEditorComponent, selector: "kendo-filter-boolean-editor", inputs: { currentItem: "currentItem" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
421
510
  <kendo-dropdownlist
422
511
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
423
- class="k-filter-toolbar-item k-filter-value"
424
512
  [(value)]="currentItem.value"
425
513
  (valueChange)="valueChange.emit()"
426
514
  [data]="items"
@@ -438,7 +526,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
438
526
  template: `
439
527
  <kendo-dropdownlist
440
528
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
441
- class="k-filter-toolbar-item k-filter-value"
442
529
  [(value)]="currentItem.value"
443
530
  (valueChange)="valueChange.emit()"
444
531
  [data]="items"
@@ -472,7 +559,6 @@ FilterDateEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0"
472
559
  FilterDateEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterDateEditorComponent, selector: "kendo-filter-date-editor", inputs: { currentItem: "currentItem", isDisabled: "isDisabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
473
560
  <kendo-datepicker
474
561
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
475
- class="k-filter-toolbar-item k-filter-value"
476
562
  [(value)]="currentItem.value"
477
563
  (valueChange)="valueChange.emit()"
478
564
  [disabled]="isDisabled">
@@ -489,7 +575,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
489
575
  template: `
490
576
  <kendo-datepicker
491
577
  [kendoAriaLabelValue]="messageFor('filterValueAriaLabel')"
492
- class="k-filter-toolbar-item k-filter-value"
493
578
  [(value)]="currentItem.value"
494
579
  (valueChange)="valueChange.emit()"
495
580
  [disabled]="isDisabled">
@@ -534,6 +619,7 @@ class FilterExpressionComponent {
534
619
  this.currentItem.field = this.filterService.filters[0].field;
535
620
  this.setOperators(defaultFilter);
536
621
  }
622
+ this.setEditorTemplate();
537
623
  this.localizationSubscription = this.localization.changes.subscribe(() => {
538
624
  this.setOperators(foundFilter || defaultFilter);
539
625
  this.cdr.detectChanges();
@@ -569,6 +655,7 @@ class FilterExpressionComponent {
569
655
  filterValueChange(value) {
570
656
  this.currentItem.value = null;
571
657
  this.currentItem.field = value;
658
+ this.setEditorTemplate();
572
659
  const foundFilter = this.getFilterExpressionByField(this.currentItem.field);
573
660
  this.setOperators(foundFilter);
574
661
  this.valueChange.emit();
@@ -622,6 +709,12 @@ class FilterExpressionComponent {
622
709
  this.isEditorDisabled = false;
623
710
  }
624
711
  }
712
+ setEditorTemplate() {
713
+ let filterExpression = this.filterService.filters.find((filter) => filter.field === this.currentItem.field);
714
+ if (filterExpression.editorTemplate) {
715
+ this.editorTemplate = filterExpression.editorTemplate;
716
+ }
717
+ }
625
718
  }
626
719
  FilterExpressionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterExpressionComponent, deps: [{ token: FilterService }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
627
720
  FilterExpressionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterExpressionComponent, selector: "kendo-filter-expression", inputs: { index: "index", currentItem: "currentItem" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
@@ -643,16 +736,24 @@ FilterExpressionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.
643
736
  <kendo-filter-expression-operators
644
737
  [currentItem]="currentItem"
645
738
  [operators]="operators"
739
+ [editorType]="getEditorType()"
646
740
  (valueChange)="onOperatorChange($event);">
647
741
  </kendo-filter-expression-operators>
648
742
  </div>
649
743
 
650
- <ng-container [ngSwitch]="getEditorType()">
651
- <kendo-filter-text-editor *ngSwitchCase="'string'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-text-editor>
652
- <kendo-filter-numeric-editor *ngSwitchCase="'number'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-numeric-editor>
653
- <kendo-filter-boolean-editor *ngSwitchCase="'boolean'" [currentItem]="currentItem" (valueChange)="valueChange.emit()"></kendo-filter-boolean-editor>
654
- <kendo-filter-date-editor *ngSwitchCase="'date'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-date-editor>
655
- </ng-container>
744
+ <div class="k-filter-toolbar-item k-filter-value">
745
+ <ng-container *ngIf="!editorTemplate" [ngSwitch]="getEditorType()">
746
+ <kendo-filter-text-editor *ngSwitchCase="'string'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-text-editor>
747
+ <kendo-filter-numeric-editor *ngSwitchCase="'number'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-numeric-editor>
748
+ <kendo-filter-boolean-editor *ngSwitchCase="'boolean'" [currentItem]="currentItem" (valueChange)="valueChange.emit()"></kendo-filter-boolean-editor>
749
+ <kendo-filter-date-editor *ngSwitchCase="'date'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-date-editor>
750
+ </ng-container>
751
+ <ng-container *ngIf="editorTemplate">
752
+ <ng-template
753
+ [templateContext]="{templateRef: editorTemplate, $implicit: currentItem}">
754
+ </ng-template>
755
+ </ng-container>
756
+ </div>
656
757
 
657
758
  <div class="k-filter-toolbar-item">
658
759
  <button
@@ -665,7 +766,7 @@ FilterExpressionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.
665
766
  </div>
666
767
  </div>
667
768
  </div>
668
- `, isInline: true, components: [{ type: i2.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["iconClass", "loading", "data", "value", "textField", "valueField", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { type: FilterExpressionOperatorsComponent, selector: "kendo-filter-expression-operators", inputs: ["currentItem", "operators"], outputs: ["valueChange"] }, { type: FilterTextEditorComponent, selector: "kendo-filter-text-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }, { type: FilterNumericEditorComponent, selector: "kendo-filter-numeric-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }, { type: FilterBooleanEditorComponent, selector: "kendo-filter-boolean-editor", inputs: ["currentItem"], outputs: ["valueChange"] }, { type: FilterDateEditorComponent, selector: "kendo-filter-date-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }], directives: [{ type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i10.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i10.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i11.ButtonDirective, selector: "button[kendoButton], span[kendoButton]", inputs: ["toggleable", "togglable", "selected", "tabIndex", "icon", "iconClass", "imageUrl", "disabled", "size", "rounded", "fillMode", "themeColor", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
769
+ `, isInline: true, components: [{ type: i2.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["iconClass", "loading", "data", "value", "textField", "valueField", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { type: FilterExpressionOperatorsComponent, selector: "kendo-filter-expression-operators", inputs: ["currentItem", "editorType", "operators"], outputs: ["valueChange"] }, { type: FilterTextEditorComponent, selector: "kendo-filter-text-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }, { type: FilterNumericEditorComponent, selector: "kendo-filter-numeric-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }, { type: FilterBooleanEditorComponent, selector: "kendo-filter-boolean-editor", inputs: ["currentItem"], outputs: ["valueChange"] }, { type: FilterDateEditorComponent, selector: "kendo-filter-date-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }], directives: [{ type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i10.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i10.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i11.TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { type: i11.ButtonDirective, selector: "button[kendoButton], span[kendoButton]", inputs: ["toggleable", "togglable", "selected", "tabIndex", "icon", "iconClass", "imageUrl", "disabled", "size", "rounded", "fillMode", "themeColor", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
669
770
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterExpressionComponent, decorators: [{
670
771
  type: Component,
671
772
  args: [{
@@ -689,16 +790,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
689
790
  <kendo-filter-expression-operators
690
791
  [currentItem]="currentItem"
691
792
  [operators]="operators"
793
+ [editorType]="getEditorType()"
692
794
  (valueChange)="onOperatorChange($event);">
693
795
  </kendo-filter-expression-operators>
694
796
  </div>
695
797
 
696
- <ng-container [ngSwitch]="getEditorType()">
697
- <kendo-filter-text-editor *ngSwitchCase="'string'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-text-editor>
698
- <kendo-filter-numeric-editor *ngSwitchCase="'number'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-numeric-editor>
699
- <kendo-filter-boolean-editor *ngSwitchCase="'boolean'" [currentItem]="currentItem" (valueChange)="valueChange.emit()"></kendo-filter-boolean-editor>
700
- <kendo-filter-date-editor *ngSwitchCase="'date'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-date-editor>
701
- </ng-container>
798
+ <div class="k-filter-toolbar-item k-filter-value">
799
+ <ng-container *ngIf="!editorTemplate" [ngSwitch]="getEditorType()">
800
+ <kendo-filter-text-editor *ngSwitchCase="'string'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-text-editor>
801
+ <kendo-filter-numeric-editor *ngSwitchCase="'number'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-numeric-editor>
802
+ <kendo-filter-boolean-editor *ngSwitchCase="'boolean'" [currentItem]="currentItem" (valueChange)="valueChange.emit()"></kendo-filter-boolean-editor>
803
+ <kendo-filter-date-editor *ngSwitchCase="'date'" [currentItem]="currentItem" [isDisabled]="isEditorDisabled" (valueChange)="valueChange.emit()"></kendo-filter-date-editor>
804
+ </ng-container>
805
+ <ng-container *ngIf="editorTemplate">
806
+ <ng-template
807
+ [templateContext]="{templateRef: editorTemplate, $implicit: currentItem}">
808
+ </ng-template>
809
+ </ng-container>
810
+ </div>
702
811
 
703
812
  <div class="k-filter-toolbar-item">
704
813
  <button
@@ -755,6 +864,9 @@ class FilterGroupComponent {
755
864
  messageFor(key) {
756
865
  return this.localization.get(key);
757
866
  }
867
+ getOperator(operatorValue) {
868
+ return this.messageFor(getKeyByValue(logicOperators, operatorValue));
869
+ }
758
870
  selectedChange(logicOperator) {
759
871
  if (this.currentItem.logic !== logicOperator) {
760
872
  this.currentItem.logic = logicOperator;
@@ -788,7 +900,7 @@ FilterGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", v
788
900
  [title]="operator.text"
789
901
  (click)="selectedChange(operator.value)"
790
902
  >
791
- {{operator.text}}
903
+ {{getOperator(operator.value)}}
792
904
  </button>
793
905
  </div>
794
906
  </div>
@@ -856,7 +968,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
856
968
  [title]="operator.text"
857
969
  (click)="selectedChange(operator.value)"
858
970
  >
859
- {{operator.text}}
971
+ {{getOperator(operator.value)}}
860
972
  </button>
861
973
  </div>
862
974
  </div>
@@ -1083,17 +1195,16 @@ class FilterComponent {
1083
1195
  * Specifies the available user-defined filters. At least one filter should be provided.
1084
1196
  */
1085
1197
  set filters(_filters) {
1086
- if (isDevMode() && (!isArray(_filters) || _filters.length === 0)) {
1087
- throw new Error(`Pass at least one user-defined filter through the [filters] input property. See http://www.telerik.com/kendo-angular-ui/components/filter/#data-binding`);
1198
+ if (_filters.length > 0) {
1199
+ this.filterService.filters = _filters.map(filterExpression => {
1200
+ let clonedFilter = Object.assign({}, filterExpression);
1201
+ if (!clonedFilter.title) {
1202
+ clonedFilter.title = clonedFilter.field;
1203
+ }
1204
+ return clonedFilter;
1205
+ });
1206
+ this.setValue(this.value);
1088
1207
  }
1089
- this.filterService.filters = _filters.map(filterExpression => {
1090
- let clonedFilter = Object.assign({}, filterExpression);
1091
- if (!clonedFilter.title) {
1092
- clonedFilter.title = clonedFilter.field;
1093
- }
1094
- return clonedFilter;
1095
- });
1096
- this.setValue(this.value);
1097
1208
  }
1098
1209
  get filters() {
1099
1210
  return this.filterService.filters;
@@ -1104,20 +1215,30 @@ class FilterComponent {
1104
1215
  set value(value) {
1105
1216
  const clonedValue = JSON.parse(JSON.stringify(value));
1106
1217
  this._value = clonedValue;
1107
- this.setValue(this.value);
1218
+ if (this.filters.length > 0) {
1219
+ this.setValue(this.value);
1220
+ }
1108
1221
  }
1109
1222
  get value() {
1110
1223
  return this._value;
1111
1224
  }
1112
1225
  ngOnInit() {
1113
- if (this.filters.length === 0) {
1114
- throw new Error(`Pass at least one user-defined filter through the [filters] input property. See http://www.telerik.com/kendo-angular-ui/components/filter/#data-binding`);
1115
- }
1116
1226
  this.localizationSubscription = this.localization.changes.subscribe(({ rtl }) => {
1117
1227
  this.direction = rtl ? 'rtl' : 'ltr';
1118
1228
  this.cdr.detectChanges();
1119
1229
  });
1120
1230
  }
1231
+ ngAfterViewChecked() {
1232
+ if (this.filterFields && this.filterFields.length > 0) {
1233
+ this.filters = this.filterFields.map((filterField) => {
1234
+ var _a;
1235
+ return (Object.assign(Object.assign({}, filterField), { editorTemplate: (_a = filterField.editorTemplate) === null || _a === void 0 ? void 0 : _a.templateRef }));
1236
+ });
1237
+ }
1238
+ if (this.filters.length === 0) {
1239
+ throw new Error(`Pass at least one user-defined filter through the [filters] input property or nest kendo-filter-field components. See http://www.telerik.com/kendo-angular-ui/components/filter/#data-binding`);
1240
+ }
1241
+ }
1121
1242
  ngOnDestroy() {
1122
1243
  if (this.localizationSubscription) {
1123
1244
  this.localizationSubscription.unsubscribe();
@@ -1143,6 +1264,9 @@ class FilterComponent {
1143
1264
  if (isDevMode() && foundFilter.editor === 'boolean' && (!filterDescriptor.value && filterDescriptor.value !== false)) {
1144
1265
  console.warn(`Provide a value for the boolean '${filterDescriptor.field}' user-defined filter as the operator is always set to 'eq'.`);
1145
1266
  }
1267
+ if (isDevMode() && foundFilter.editor === 'boolean' && filterDescriptor.operator !== 'eq') {
1268
+ console.warn(`The operator of the boolean '${filterDescriptor.field}' user-defined filter is always set to 'eq'.`);
1269
+ }
1146
1270
  if (filterDescriptor.operator && foundFilter.operators && !foundFilter.operators.some(operator => operator === filterDescriptor.operator)) {
1147
1271
  throw new Error(`The user-defined filter with field '${filterDescriptor.field}' is missing the '${filterDescriptor.operator}' operator.`);
1148
1272
  }
@@ -1185,7 +1309,7 @@ FilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", versio
1185
1309
  useValue: 'kendo.filter'
1186
1310
  },
1187
1311
  FilterService
1188
- ], ngImport: i0, template: `
1312
+ ], queries: [{ propertyName: "filterFields", predicate: FilterFieldComponent }], ngImport: i0, template: `
1189
1313
  <ng-container kendoFilterLocalizedMessages
1190
1314
  i18n-editorDateTodayText="kendo.filter.editorDateTodayText|The text of the Today button of the Date editor"
1191
1315
  editorDateTodayText="Today"
@@ -1459,6 +1583,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1459
1583
  type: Input
1460
1584
  }], valueChange: [{
1461
1585
  type: Output
1586
+ }], filterFields: [{
1587
+ type: ContentChildren,
1588
+ args: [FilterFieldComponent]
1462
1589
  }] } });
1463
1590
 
1464
1591
  /**
@@ -1578,7 +1705,9 @@ FilterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "
1578
1705
  FilterDateEditorComponent,
1579
1706
  LocalizedMessagesDirective,
1580
1707
  CustomMessagesComponent,
1581
- AriaLabelValueDirective], imports: [SharedModule], exports: [FilterComponent,
1708
+ AriaLabelValueDirective,
1709
+ FilterFieldComponent,
1710
+ FilterValueEditorTemplateDirective], imports: [SharedModule], exports: [FilterComponent,
1582
1711
  FilterNumericEditorComponent,
1583
1712
  FilterTextEditorComponent,
1584
1713
  FilterExpressionComponent,
@@ -1588,7 +1717,9 @@ FilterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "
1588
1717
  FilterDateEditorComponent,
1589
1718
  LocalizedMessagesDirective,
1590
1719
  CustomMessagesComponent,
1591
- AriaLabelValueDirective] });
1720
+ AriaLabelValueDirective,
1721
+ FilterFieldComponent,
1722
+ FilterValueEditorTemplateDirective] });
1592
1723
  FilterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterModule, imports: [[SharedModule]] });
1593
1724
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterModule, decorators: [{
1594
1725
  type: NgModule,
@@ -1604,7 +1735,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1604
1735
  FilterDateEditorComponent,
1605
1736
  LocalizedMessagesDirective,
1606
1737
  CustomMessagesComponent,
1607
- AriaLabelValueDirective
1738
+ AriaLabelValueDirective,
1739
+ FilterFieldComponent,
1740
+ FilterValueEditorTemplateDirective
1608
1741
  ],
1609
1742
  exports: [FilterComponent,
1610
1743
  FilterNumericEditorComponent,
@@ -1616,7 +1749,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1616
1749
  FilterDateEditorComponent,
1617
1750
  LocalizedMessagesDirective,
1618
1751
  CustomMessagesComponent,
1619
- AriaLabelValueDirective]
1752
+ AriaLabelValueDirective,
1753
+ FilterFieldComponent,
1754
+ FilterValueEditorTemplateDirective]
1620
1755
  }]
1621
1756
  }] });
1622
1757
 
@@ -1624,5 +1759,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1624
1759
  * Generated bundle index. Do not edit.
1625
1760
  */
1626
1761
 
1627
- export { AriaLabelValueDirective, CustomMessagesComponent, FilterBooleanEditorComponent, FilterComponent, FilterDateEditorComponent, FilterExpressionComponent, FilterExpressionOperatorsComponent, FilterGroupComponent, FilterModule, FilterNumericEditorComponent, FilterTextEditorComponent, LocalizedMessagesDirective };
1762
+ export { AriaLabelValueDirective, CustomMessagesComponent, FilterBooleanEditorComponent, FilterComponent, FilterDateEditorComponent, FilterExpressionComponent, FilterExpressionOperatorsComponent, FilterFieldComponent, FilterGroupComponent, FilterModule, FilterNumericEditorComponent, FilterTextEditorComponent, FilterValueEditorTemplateDirective, LocalizedMessagesDirective };
1628
1763
 
@@ -5,6 +5,7 @@
5
5
  import { EventEmitter } from '@angular/core';
6
6
  import { LocalizationService } from '@progress/kendo-angular-l10n';
7
7
  import { FilterDescriptor } from '@progress/kendo-data-query';
8
+ import { FilterEditor, FilterOperator } from './model/filter-expression';
8
9
  import * as i0 from "@angular/core";
9
10
  /**
10
11
  * @hidden
@@ -12,14 +13,16 @@ import * as i0 from "@angular/core";
12
13
  export declare class FilterExpressionOperatorsComponent {
13
14
  private localization;
14
15
  currentItem: FilterDescriptor;
16
+ editorType: FilterEditor;
17
+ valueChange: EventEmitter<FilterOperator>;
15
18
  operators: {
16
19
  text: string;
17
20
  value: string;
18
21
  }[];
19
- valueChange: EventEmitter<string>;
20
22
  constructor(localization: LocalizationService);
21
23
  messageFor(key: string): string;
22
- operatorValueChange(value: string): void;
24
+ getOperator(operatorValue: FilterOperator): string;
25
+ operatorValueChange(value: FilterOperator): void;
23
26
  static ɵfac: i0.ɵɵFactoryDeclaration<FilterExpressionOperatorsComponent, never>;
24
- static ɵcmp: i0.ɵɵComponentDeclaration<FilterExpressionOperatorsComponent, "kendo-filter-expression-operators", never, { "currentItem": "currentItem"; "operators": "operators"; }, { "valueChange": "valueChange"; }, never, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<FilterExpressionOperatorsComponent, "kendo-filter-expression-operators", never, { "currentItem": "currentItem"; "editorType": "editorType"; "operators": "operators"; }, { "valueChange": "valueChange"; }, never, never>;
25
28
  }
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2021 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { ChangeDetectorRef, EventEmitter, OnDestroy, OnInit } from '@angular/core';
5
+ import { ChangeDetectorRef, EventEmitter, OnDestroy, OnInit, TemplateRef } from '@angular/core';
6
6
  import { LocalizationService } from '@progress/kendo-angular-l10n';
7
7
  import { CompositeFilterDescriptor } from '@progress/kendo-data-query';
8
8
  import { FilterDescriptor } from '@progress/kendo-data-query';
@@ -25,6 +25,7 @@ export declare class FilterExpressionComponent implements OnInit, OnDestroy {
25
25
  isBoolean: boolean;
26
26
  editorType: FilterEditor;
27
27
  isEditorDisabled: boolean;
28
+ editorTemplate: TemplateRef<any>;
28
29
  private localizationSubscription;
29
30
  constructor(filterService: FilterService, localization: LocalizationService, cdr: ChangeDetectorRef);
30
31
  ngOnInit(): void;
@@ -44,6 +45,7 @@ export declare class FilterExpressionComponent implements OnInit, OnDestroy {
44
45
  removeFilterExpression(): void;
45
46
  private setOperators;
46
47
  onOperatorChange(value: string): void;
48
+ setEditorTemplate(): void;
47
49
  static ɵfac: i0.ɵɵFactoryDeclaration<FilterExpressionComponent, never>;
48
50
  static ɵcmp: i0.ɵɵComponentDeclaration<FilterExpressionComponent, "kendo-filter-expression", never, { "index": "index"; "currentItem": "currentItem"; }, { "valueChange": "valueChange"; }, never, never>;
49
51
  }