UNPKG

@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
/**----------------------------------------------------------------------------------------- * 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'] }] } });