UNPKG

@progress/kendo-angular-grid

Version:

Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.

394 lines (387 loc) 22.3 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, HostBinding, Input, Inject, Optional, TemplateRef } from '@angular/core'; import { EditService } from '../editing/edit.service'; import { isSpanColumn, isCheckboxColumn, isRowReorderColumn } from '../columns/column-base'; import { CommandColumnComponent } from '../columns/command-column.component'; import { isColumnComponent } from '../columns/column.component'; import { columnsToRender } from "../columns/column-common"; import { ReactiveFormsModule } from '@angular/forms'; import { isPresent, isNullOrEmptyString, extractFormat } from '../utils'; import { CELL_CONTEXT } from './common/cell-context'; import { IdService } from '../common/id.service'; import { reorderIcon } from '@progress/kendo-svg-icons'; import { ContextService } from '../common/provider.service'; import { FieldAccessorPipe } from './common/field-accessor.pipe'; import { IconWrapperComponent } from '@progress/kendo-angular-icons'; import { SelectionCheckboxDirective } from '../selection/selection-checkbox.directive'; import { FocusableDirective } from '../navigation/focusable.directive'; import { NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet, NgFor, NgSwitchDefault } from '@angular/common'; import { CheckBoxComponent, NumericTextBoxComponent, TextBoxComponent } from '@progress/kendo-angular-inputs'; import { DatePickerComponent } from '@progress/kendo-angular-dateinputs'; import * as i0 from "@angular/core"; import * as i1 from "../editing/edit.service"; import * as i2 from "../common/id.service"; import * as i3 from "../common/provider.service"; import * as i4 from "@angular/forms"; /** * @hidden */ export class CellComponent { editService; idService; ctx; cellContext; get commandCellClass() { return this.isCommand(this.column); } get dragHandleCellClass() { return isRowReorderColumn(this.column); } get dragRowHandleLabel() { return isRowReorderColumn(this.column) ? this.ctx.localization.get('dragRowHandleLabel') : undefined; } column; columnIndex; isNew = false; isLoading = false; isVirtual = false; loadingTemplate; set rowIndex(index) { this._rowIndex = index; this.updateCellContext(); } get rowIndex() { return this._rowIndex; } dataItem; reorderIcon = reorderIcon; get isEdited() { if (!(this.editService.isEditing() || this.isNew) || !this.isColumnEditable) { return false; } const editContext = this.editService.columnContext(this.rowIndex, this.column); return this.isFieldEditable(editContext, this.column); } get showLoading() { return this.isVirtual && this.isLoading; } get formGroup() { return this.editService.context(this.rowIndex).group; } get templateContext() { return this._templateContext; } get editTemplateContext() { this._editTemplateContext.$implicit = this.formGroup; this._editTemplateContext.isNew = this.isNew; this._editTemplateContext.column = this.column; this._editTemplateContext.dataItem = this.dataItem; this._editTemplateContext.formGroup = this.formGroup; this._editTemplateContext.rowIndex = this.rowIndex; return this._editTemplateContext; } get rowReorderTemplateContext() { this._rowReorderTemplateContext.$implicit = this.dataItem; this._rowReorderTemplateContext.columnIndex = this.columnIndex; this._rowReorderTemplateContext.rowIndex = this.rowIndex; return this._rowReorderTemplateContext; } get format() { if (isColumnComponent(this.column) && !isNullOrEmptyString(this.column.format)) { return extractFormat(this.column.format); } return undefined; } get isBoundColumn() { return this.column.field && !this.column.templateRef; } get isCheckboxColumn() { return isCheckboxColumn(this.column) && !this.column.templateRef; } get selectionCheckboxId() { return this.idService.selectionCheckboxId(this.rowIndex); } get selectionCheckboxLabel() { return this.ctx.localization.get('selectionCheckboxLabel'); } get isSpanColumn() { return isSpanColumn(this.column) && !this.column.templateRef; } get childColumns() { return columnsToRender([this.column]); } get isRowReorderColumn() { return isRowReorderColumn(this.column) && !this.column.templateRef; } get isRowSelectable() { return this.column.rowSelectable(this._rowIndex); } _rowIndex; get isColumnEditable() { if (!this.column || this.isCommand(this.column)) { return false; } return this.column.editable !== false; } _templateContext = {}; _editTemplateContext = {}; _rowReorderTemplateContext = {}; constructor(editService, idService, ctx, cellContext) { this.editService = editService; this.idService = idService; this.ctx = ctx; this.cellContext = cellContext; } ngDoCheck() { this.updateCellContext(); } ngOnChanges() { this.updateTemplateContext(); } ngAfterContentChecked() { this.updateTemplateContext(); } isCommand(column) { return column instanceof CommandColumnComponent; } isFieldEditable(editContext, column) { if (!isPresent(editContext)) { return false; } if (isPresent(column.editTemplate)) { return true; } return isPresent(editContext.group) && isPresent(editContext.group.get(column.field)); } updateCellContext() { if (this.cellContext) { this.cellContext.rowIndex = this._rowIndex; } } updateTemplateContext() { if (!this.column.templateRef) { return; } const context = this._templateContext; context.isNew = this.isNew; context.column = this.column; context.dataItem = this.dataItem; context.rowIndex = this.rowIndex; context.columnIndex = this.columnIndex; context.$implicit = this.dataItem; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellComponent, deps: [{ token: i1.EditService }, { token: i2.IdService }, { token: i3.ContextService }, { token: CELL_CONTEXT, optional: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CellComponent, isStandalone: true, selector: "[kendoGridCell]", inputs: { column: "column", columnIndex: "columnIndex", isNew: "isNew", isLoading: "isLoading", isVirtual: "isVirtual", loadingTemplate: "loadingTemplate", rowIndex: "rowIndex", dataItem: "dataItem" }, host: { properties: { "class.k-command-cell": "this.commandCellClass", "class.k-drag-cell": "this.dragHandleCellClass", "class.k-touch-action-none": "this.dragHandleCellClass", "attr.aria-label": "this.dragRowHandleLabel" } }, usesOnChanges: true, ngImport: i0, template: ` <ng-container [ngSwitch]="isEdited"> <ng-container *ngSwitchCase="false"> <ng-container *ngIf="!showLoading; else loading"> <ng-template *ngIf="column.templateRef" [ngTemplateOutlet]="column.templateRef" [ngTemplateOutletContext]="templateContext"> </ng-template> <ng-container *ngIf="isSpanColumn"> <ng-container *ngFor="let childColumn of childColumns"> {{ dataItem | valueOf: childColumn.field: childColumn.format}} </ng-container> </ng-container> <ng-container *ngIf="isBoundColumn">{{ dataItem | valueOf: column.field: column.format}}</ng-container> <ng-container *ngIf="isCheckboxColumn && !isNew"> <ng-container *ngIf="isRowSelectable; else nonSelectableRow"> <kendo-checkbox [kendoGridSelectionCheckbox]="rowIndex" [attr.id]="selectionCheckboxId" [inputAttributes]="{'aria-label': selectionCheckboxLabel}"> </kendo-checkbox> </ng-container> <ng-template #nonSelectableRow> <kendo-checkbox *ngIf="column.showDisabledCheckbox" [kendoGridSelectionCheckbox]="rowIndex" [attr.id]="selectionCheckboxId" [inputAttributes]="{'aria-label': selectionCheckboxLabel}" [disabled]="true" ></kendo-checkbox> </ng-template> </ng-container> <ng-container *ngIf="isRowReorderColumn && !isNew"> <kendo-icon-wrapper *ngIf="!column.dragHandleTemplate?.first" name="reorder" [svgIcon]="reorderIcon"> </kendo-icon-wrapper> <ng-template *ngIf="column.dragHandleTemplate?.first" [ngTemplateOutlet]="column.rowDragHandleTemplateRef" [ngTemplateOutletContext]="rowReorderTemplateContext"> </ng-template> </ng-container> </ng-container> <ng-template #loading> <ng-template *ngIf="loadingTemplate" [ngTemplateOutlet]="loadingTemplate" [ngTemplateOutletContext]="{$implicit: column}"> </ng-template> <div *ngIf="!loadingTemplate" class="k-skeleton-text k-skeleton"></div> </ng-template> </ng-container> <ng-container *ngSwitchCase="true"> <ng-template *ngIf="column.editTemplateRef" [ngTemplateOutlet]="column.editTemplateRef" [ngTemplateOutletContext]="editTemplateContext"> </ng-template> <ng-container [ngSwitch]="column.editor" *ngIf="!column.editTemplateRef"> <kendo-numerictextbox *ngSwitchCase="'numeric'" [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-numerictextbox> <kendo-datepicker *ngSwitchCase="'date'" [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-datepicker> <kendo-checkbox *ngSwitchCase="'boolean'" [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-checkbox> <kendo-textbox *ngSwitchDefault [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-textbox> </ng-container> </ng-container> </ng-container> `, isInline: true, dependencies: [{ kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoGridFocusable],\n [kendoGridEditCommand],\n [kendoGridRemoveCommand],\n [kendoGridSaveCommand],\n [kendoGridCancelCommand],\n [kendoGridSelectionCheckbox]\n ", inputs: ["kendoGridFocusable"] }, { kind: "directive", type: SelectionCheckboxDirective, selector: "[kendoGridSelectionCheckbox]", inputs: ["kendoGridSelectionCheckbox"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { 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: "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", "title", "subtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: FieldAccessorPipe, name: "valueOf" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }, { 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"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellComponent, decorators: [{ type: Component, args: [{ selector: '[kendoGridCell]', template: ` <ng-container [ngSwitch]="isEdited"> <ng-container *ngSwitchCase="false"> <ng-container *ngIf="!showLoading; else loading"> <ng-template *ngIf="column.templateRef" [ngTemplateOutlet]="column.templateRef" [ngTemplateOutletContext]="templateContext"> </ng-template> <ng-container *ngIf="isSpanColumn"> <ng-container *ngFor="let childColumn of childColumns"> {{ dataItem | valueOf: childColumn.field: childColumn.format}} </ng-container> </ng-container> <ng-container *ngIf="isBoundColumn">{{ dataItem | valueOf: column.field: column.format}}</ng-container> <ng-container *ngIf="isCheckboxColumn && !isNew"> <ng-container *ngIf="isRowSelectable; else nonSelectableRow"> <kendo-checkbox [kendoGridSelectionCheckbox]="rowIndex" [attr.id]="selectionCheckboxId" [inputAttributes]="{'aria-label': selectionCheckboxLabel}"> </kendo-checkbox> </ng-container> <ng-template #nonSelectableRow> <kendo-checkbox *ngIf="column.showDisabledCheckbox" [kendoGridSelectionCheckbox]="rowIndex" [attr.id]="selectionCheckboxId" [inputAttributes]="{'aria-label': selectionCheckboxLabel}" [disabled]="true" ></kendo-checkbox> </ng-template> </ng-container> <ng-container *ngIf="isRowReorderColumn && !isNew"> <kendo-icon-wrapper *ngIf="!column.dragHandleTemplate?.first" name="reorder" [svgIcon]="reorderIcon"> </kendo-icon-wrapper> <ng-template *ngIf="column.dragHandleTemplate?.first" [ngTemplateOutlet]="column.rowDragHandleTemplateRef" [ngTemplateOutletContext]="rowReorderTemplateContext"> </ng-template> </ng-container> </ng-container> <ng-template #loading> <ng-template *ngIf="loadingTemplate" [ngTemplateOutlet]="loadingTemplate" [ngTemplateOutletContext]="{$implicit: column}"> </ng-template> <div *ngIf="!loadingTemplate" class="k-skeleton-text k-skeleton"></div> </ng-template> </ng-container> <ng-container *ngSwitchCase="true"> <ng-template *ngIf="column.editTemplateRef" [ngTemplateOutlet]="column.editTemplateRef" [ngTemplateOutletContext]="editTemplateContext"> </ng-template> <ng-container [ngSwitch]="column.editor" *ngIf="!column.editTemplateRef"> <kendo-numerictextbox *ngSwitchCase="'numeric'" [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-numerictextbox> <kendo-datepicker *ngSwitchCase="'date'" [format]="format" [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-datepicker> <kendo-checkbox *ngSwitchCase="'boolean'" [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-checkbox> <kendo-textbox *ngSwitchDefault [formControl]="$any(formGroup.get(column.field))" kendoGridFocusable ></kendo-textbox> </ng-container> </ng-container> </ng-container> `, standalone: true, imports: [NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet, NgFor, FocusableDirective, SelectionCheckboxDirective, IconWrapperComponent, NumericTextBoxComponent, DatePickerComponent, NgSwitchDefault, FieldAccessorPipe, ReactiveFormsModule, CheckBoxComponent, TextBoxComponent] }] }], ctorParameters: function () { return [{ type: i1.EditService }, { type: i2.IdService }, { type: i3.ContextService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CELL_CONTEXT] }] }]; }, propDecorators: { commandCellClass: [{ type: HostBinding, args: ['class.k-command-cell'] }], dragHandleCellClass: [{ type: HostBinding, args: ['class.k-drag-cell'] }, { type: HostBinding, args: ['class.k-touch-action-none'] }], dragRowHandleLabel: [{ type: HostBinding, args: ['attr.aria-label'] }], column: [{ type: Input }], columnIndex: [{ type: Input }], isNew: [{ type: Input }], isLoading: [{ type: Input }], isVirtual: [{ type: Input }], loadingTemplate: [{ type: Input }], rowIndex: [{ type: Input }], dataItem: [{ type: Input }] } });