@progress/kendo-angular-grid
Version:
Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.
226 lines (225 loc) • 10.2 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, Input, NgZone, Renderer2, ChangeDetectorRef, ViewChild } from '@angular/core';
import { PopupService } from '@progress/kendo-angular-popup';
import { ColumnInfoService } from '../common/column-info.service';
import { closest } from '../rendering/common/dom-queries';
import { Keys, guid, isDocumentAvailable } from '@progress/kendo-angular-common';
import { columnsIcon } from '@progress/kendo-svg-icons';
import { ButtonComponent } from '@progress/kendo-angular-buttons';
import { ContextService } from '../common/provider.service';
import { ColumnListComponent } from './column-list.component';
import * as i0 from "@angular/core";
import * as i1 from "../common/provider.service";
import * as i2 from "../common/column-info.service";
import * as i3 from "@progress/kendo-angular-popup";
/**
* Represents the component for toggling visibility of the Grid columns visibility. [See example](slug:columnmenu_grid#toc-using-standalone-column-chooser).
* To show and hide the columns without including the column chooser item in the [Column Menu](slug:columnmenu_grid),
* add the component inside the [ToolbarTemplate](slug:toolbartemplate_grid) directive.
*
* @example
* ```html
* <kendo-grid [data]="data">
* <ng-template kendoGridToolbarTemplate>
* <kendo-grid-column-chooser></kendo-grid-column-chooser>
* </ng-template>
* <kendo-grid-column field="ProductID"></kendo-grid-column>
* </kendo-grid>
* ```
*/
export class ColumnChooserComponent {
ctx;
columnInfoService;
popupService;
ngZone;
renderer;
changeDetector;
/**
* Specifies if the changes in the visibility of the column will be immediately applied.
*
* @default false
*/
autoSync = false;
/**
* Specifies if all columns can be hidden.
*
* @default true
*/
allowHideAll = true;
anchor;
columnList;
get columns() {
return this.columnInfoService.leafNamedColumns;
}
columnsIcon = columnsIcon;
popupRef;
popupId;
closeClick;
escapeListener;
constructor(ctx, columnInfoService, popupService, ngZone, renderer, changeDetector) {
this.ctx = ctx;
this.columnInfoService = columnInfoService;
this.popupService = popupService;
this.ngZone = ngZone;
this.renderer = renderer;
this.changeDetector = changeDetector;
}
ngOnDestroy() {
this.close();
}
/**
* @hidden
*/
toggle(anchor, template) {
if (!this.popupRef) {
const direction = this.ctx.localization.rtl ? 'right' : 'left';
this.popupRef = this.popupService.open({
anchor: anchor.element,
content: template,
positionMode: 'absolute',
anchorAlign: { vertical: 'bottom', horizontal: direction },
popupAlign: { vertical: 'top', horizontal: direction }
});
const popupElement = this.popupRef?.popupElement;
if (popupElement) {
const popupId = `k-${guid()}`;
const popupAriaElement = popupElement.querySelector('.k-popup');
this.ngZone.runOutsideAngular(() => {
this.escapeListener = this.renderer.listen(popupAriaElement, 'keydown', (e) => {
if (e.keyCode === Keys.Escape) {
this.close(true);
}
});
});
this.renderer.setAttribute(popupElement, 'dir', this.ctx.localization.rtl ? 'rtl' : 'ltr');
this.renderer.setAttribute(popupAriaElement, 'id', popupId);
this.renderer.setAttribute(popupAriaElement, 'role', 'dialog');
this.popupId = popupId;
}
if (!isDocumentAvailable()) {
return;
}
this.ngZone.runOutsideAngular(() => this.closeClick = this.renderer.listen('document', 'click', ({ target }) => {
if (!closest(target, node => node === this.popupRef.popupElement || node === anchor.element)) {
this.ngZone.run(() => {
this.close();
});
}
}));
}
else {
this.close();
}
}
/**
* @hidden
*/
onApply(changed) {
this.close(true);
if (changed.length) {
this.changeDetector.markForCheck();
this.columnInfoService.changeVisibility(changed);
}
}
/**
* @hidden
*/
onChange(changed) {
this.changeDetector.markForCheck();
this.columnInfoService.changeVisibility(changed);
}
close(focusAnchor = false) {
if (this.popupRef) {
this.popupRef.close();
this.popupRef = null;
this.changeDetector.markForCheck();
this.escapeListener?.();
}
this.detachClose();
focusAnchor && this.anchor.element.focus();
}
detachClose() {
if (this.closeClick) {
this.closeClick();
this.closeClick = null;
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnChooserComponent, deps: [{ token: i1.ContextService }, { token: i2.ColumnInfoService }, { token: i3.PopupService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnChooserComponent, isStandalone: true, selector: "kendo-grid-column-chooser", inputs: { autoSync: "autoSync", allowHideAll: "allowHideAll" }, viewQueries: [{ propertyName: "anchor", first: true, predicate: ["anchor"], descendants: true }, { propertyName: "columnList", first: true, predicate: ["columnList"], descendants: true }], ngImport: i0, template: `
<button #anchor
kendoButton
type="button"
(click)="toggle(anchor, template)"
fillMode="flat"
[attr.title]="ctx.localization.get('columns')"
icon="columns"
[svgIcon]="columnsIcon"
[attr.aria-haspopup]="'dialog'"
[attr.aria-expanded]="!!(popupRef)"
[attr.aria-controls]="!!(popupRef) ? popupId : undefined"></button>
<ng-template #template>
<span class='k-column-chooser-title'>{{ ctx.localization.get('columns') }}</span>
<kendo-grid-columnlist
#columnList
[columns]="columns"
[ariaLabel]="ctx.localization.get('columns')"
[isLast]="true"
[applyText]="ctx.localization.get('columnsApply')"
[resetText]="ctx.localization.get('columnsReset')"
[autoSync]="autoSync"
[allowHideAll]="allowHideAll"
(apply)="onApply($event)"
(columnChange)="onChange($event)">
</kendo-grid-columnlist>
</ng-template>
`, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ColumnListComponent, selector: "kendo-grid-columnlist", inputs: ["columns", "autoSync", "ariaLabel", "allowHideAll", "applyText", "resetText", "actionsClass", "isLast", "isExpanded", "service"], outputs: ["reset", "apply", "columnChange"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnChooserComponent, decorators: [{
type: Component,
args: [{
selector: 'kendo-grid-column-chooser',
template: `
<button #anchor
kendoButton
type="button"
(click)="toggle(anchor, template)"
fillMode="flat"
[attr.title]="ctx.localization.get('columns')"
icon="columns"
[svgIcon]="columnsIcon"
[attr.aria-haspopup]="'dialog'"
[attr.aria-expanded]="!!(popupRef)"
[attr.aria-controls]="!!(popupRef) ? popupId : undefined"></button>
<ng-template #template>
<span class='k-column-chooser-title'>{{ ctx.localization.get('columns') }}</span>
<kendo-grid-columnlist
#columnList
[columns]="columns"
[ariaLabel]="ctx.localization.get('columns')"
[isLast]="true"
[applyText]="ctx.localization.get('columnsApply')"
[resetText]="ctx.localization.get('columnsReset')"
[autoSync]="autoSync"
[allowHideAll]="allowHideAll"
(apply)="onApply($event)"
(columnChange)="onChange($event)">
</kendo-grid-columnlist>
</ng-template>
`,
standalone: true,
imports: [ButtonComponent, ColumnListComponent]
}]
}], ctorParameters: function () { return [{ type: i1.ContextService }, { type: i2.ColumnInfoService }, { type: i3.PopupService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { autoSync: [{
type: Input
}], allowHideAll: [{
type: Input
}], anchor: [{
type: ViewChild,
args: ['anchor']
}], columnList: [{
type: ViewChild,
args: ['columnList']
}] } });