Common Issues with the Grid Filter Menu
Environment
| Product | Progress® Kendo UI® for Angular Data Grid |
Description
This article covers three common problems with the Angular Grid filter menu:
- The filter menu closes when the user interacts with a DatePicker.
- The filter is not applied after the user clicks the Filter button.
- A custom filter component displays a stale value that is out of sync with the applied filter.
Filter Menu Closes When Interacting with a DatePicker
Cause: By default, the filter menu closes when the user clicks outside its container. The DatePicker calendar renders in a separate popup outside the filter menu boundary, so clicking inside the calendar is treated as an outside click.
Solution: Inject the SinglePopupService in the custom filter component to intercept the onClose event. Check whether the currently active element belongs to the filter menu or to a related popup, and call preventDefault() to keep the menu open.
private closeSubscription: Subscription;
constructor(private element: ElementRef, private popupService: SinglePopupService) {
this.closeSubscription = popupService.onClose.subscribe((e: PopupCloseEvent) => {
if (document.activeElement &&
(this.element.nativeElement.contains(document.activeElement) ||
document.querySelector('.k-animation-container')?.contains(document.activeElement))) {
e.preventDefault();
}
});
}
public ngOnDestroy(): void {
this.closeSubscription.unsubscribe();
}
Import Subscription from rxjs when you use this pattern.
For the complete implementation, refer to the Filter Menu with Popup section.
Filter Is Not Applied After Clicking the Filter Button
Cause: The filter is not applied when the CompositeFilterDescriptor passed to filterService.filter() is invalid, when the field property does not match the column's field value exactly, or when the filterable input is set to the wrong mode.
Solution: Verify the following:
- The
filterService.filter()method receives a validCompositeFilterDescriptorobject. An emptyfiltersarray clears the column filter rather than applying one. - The
fieldproperty in each filter descriptor matches the exactfieldvalue of the column, including letter casing. For example,'ProductName'does not match'productName'. - The Grid's
filterableinput is set to'menu'and not totrueor'row'.
public onFilterChange(value: string, filterService: FilterService): void {
filterService.filter({
filters: value ? [{ field: 'ProductName', operator: 'contains', value }] : [],
logic: 'and'
});
}
Custom Filter Component Value Is Out of Sync
Cause: Custom filter components need to derive their displayed value from the filter template context variable rather than maintaining their own internal state. If the component stores the filter value independently, it can get out of sync when the Grid filter state changes from outside the component.
Solution: Read the active filter state from the filter variable provided by the kendoGridFilterMenuTemplate template context. Derive the component's current value from the CompositeFilterDescriptor on each change detection cycle.
The following snippet shows a pipe-based approach that extracts the active values from the filter descriptor.
@Pipe({ name: 'filterValues', standalone: true })
export class FilterValuesPipe implements PipeTransform {
public transform(filter: CompositeFilterDescriptor): unknown[] {
const flatten = (f: CompositeFilterDescriptor): FilterDescriptor[] => {
const filters = (f || {}).filters;
if (!filters) { return []; }
return filters.reduce(
(acc, cur) => acc.concat(isCompositeFilterDescriptor(cur) ? flatten(cur) : [cur]),
[]
);
};
return flatten(filter).map(d => d.value);
}
}
Bind the filtering component's value to the output of this pipe in the template.
<kendo-multiselect
[value]="filter | filterValues"
(valueChange)="onFilterChange($event, filterService)">
</kendo-multiselect>
For the complete implementation, refer to the Custom Filters section.