@progress/kendo-angular-treelist
Version:
Kendo UI TreeList for Angular - Display hierarchical data in an Angular tree grid view that supports sorting, filtering, paging, and much more.
362 lines (355 loc) • 20.7 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, HostBinding, Input } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { NgSwitch, NgSwitchCase, NgIf, NgFor, NgTemplateOutlet, NgSwitchDefault } from '@angular/common';
import { caretAltDownIcon, caretAltLeftIcon, caretAltRightIcon, reorderIcon } from '@progress/kendo-svg-icons';
import { LocalizationService } from "@progress/kendo-angular-l10n";
import { DatePickerComponent } from '@progress/kendo-angular-dateinputs';
import { CheckBoxComponent, NumericTextBoxComponent, TextBoxComponent } from '@progress/kendo-angular-inputs';
import { IconWrapperComponent } from '@progress/kendo-angular-icons';
import { EditService } from '../editing/edit.service';
import { isSpanColumn, isCheckboxColumn, isRowReorderColumn } from '../columns/column-base';
import { isColumnComponent } from '../columns/column.component';
import { columnsToRender } from "../columns/column-common";
import { isNullOrEmptyString, extractFormat, isColumnEditable } from '../utils';
import { FocusGroup } from '../navigation/focus-group';
import { LevelItemsPipe } from './common/level-items.pipe';
import { FieldAccessorPipe } from './common/field-accessor.pipe';
import { FocusableDirective } from '../navigation/focusable.directive';
import * as i0 from "@angular/core";
import * as i1 from "../editing/edit.service";
import * as i2 from "@progress/kendo-angular-l10n";
import * as i3 from "../navigation/focus-group";
import * as i4 from "@angular/forms";
/**
* @hidden
*/
export class CellComponent {
editService;
localization;
focusGroup;
get commandCellClass() {
return this.column.isCommand;
}
get isCheckboxColumn() {
return isCheckboxColumn(this.column);
}
get textNoWrapClass() {
return this.column.expandable;
}
get dragHandleCellClass() {
return isRowReorderColumn(this.column);
}
get dragRowHandleLabel() {
return isRowReorderColumn(this.column) ? this.localization.get('dragRowHandleLabel') : undefined;
}
column;
columnIndex;
isNew = false;
level = 0;
hasChildren;
isExpanded;
loading;
expandIcons;
rowIndex;
selected;
dataItem;
set viewItem(value) {
this._viewItem = value;
this.cellContext.viewItem = this.viewItem;
}
get viewItem() {
return this._viewItem;
}
get formGroup() {
return this.viewItem.isNew ? this.editService.newItemGroup :
this.viewItem.editContext ? this.viewItem.editContext.group : null;
}
get isEdited() {
return Boolean((this.viewItem.isNew && isColumnEditable(this.column, this.editService.newItemGroup)) ||
(isColumnEditable(this.column, this.formGroup) &&
this.viewItem.editContext &&
this.editService.isEditedColumn(this.column)));
}
get templateContext() {
return this._templateContext;
}
get editTemplateContext() {
this._editTemplateContext.$implicit = this.formGroup;
this._editTemplateContext.cellContext = this.cellContext;
this._editTemplateContext.column = this.column;
this._editTemplateContext.dataItem = this.dataItem;
this._editTemplateContext.formGroup = this.formGroup;
this._editTemplateContext.isNew = this.isNew;
this._editTemplateContext.rowIndex = this.isNew ? -1 : this.rowIndex;
return this._editTemplateContext;
}
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 isSpanColumn() {
return isSpanColumn(this.column) && !this.column.templateRef;
}
get childColumns() {
return columnsToRender([this.column]);
}
caretAltDownIcon = caretAltDownIcon;
caretAltRightIcon = caretAltRightIcon;
caretAltLeftIcon = caretAltLeftIcon;
reorderIcon = reorderIcon;
noneIcon = {
name: 'none',
content: '',
viewBox: '0 0 24 24'
};
cellContext = {};
_templateContext = {};
_editTemplateContext = {};
_viewItem;
constructor(editService, localization, focusGroup) {
this.editService = editService;
this.localization = localization;
this.focusGroup = focusGroup;
this.templateContext.cellContext = this.cellContext;
this.cellContext.focusGroup = focusGroup;
}
ngDoCheck() {
this.updateTemplateContext();
}
ngAfterContentChecked() {
this.updateTemplateContext();
}
updateTemplateContext() {
if (!this.column.templateRef) {
return;
}
const context = this._templateContext;
context.$implicit = this.dataItem;
context.column = this.column;
context.columnIndex = this.columnIndex;
context.dataItem = this.dataItem;
context.hasChildren = this.hasChildren;
context.isExpanded = this.isExpanded;
context.isNew = this.isNew;
context.level = this.level;
context.loading = this.loading;
context.rowIndex = this.viewItem.rowIndex;
}
get arrowIcon() {
const icon = !this.isExpanded ?
!this.localization.rtl ?
'caret-alt-right' :
'caret-alt-left' :
'caret-alt-down';
return icon;
}
get arrowSVGIcon() {
const icon = !this.isExpanded ?
!this.localization.rtl ?
this.caretAltRightIcon :
this.caretAltLeftIcon :
this.caretAltDownIcon;
return icon;
}
messageFor(token) {
return this.localization.get(token);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellComponent, deps: [{ token: i1.EditService }, { token: i2.LocalizationService }, { token: i3.FocusGroup }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CellComponent, isStandalone: true, selector: "[kendoTreeListCell]", inputs: { column: "column", columnIndex: "columnIndex", isNew: "isNew", level: "level", hasChildren: "hasChildren", isExpanded: "isExpanded", loading: "loading", expandIcons: "expandIcons", rowIndex: "rowIndex", selected: "selected", dataItem: "dataItem", viewItem: "viewItem" }, host: { properties: { "class.k-command-cell": "this.commandCellClass", "class.k-checkbox-cell": "this.isCheckboxColumn", "class.k-text-nowrap": "this.textNoWrapClass", "class.k-drag-cell": "this.dragHandleCellClass", "class.k-touch-action-none": "this.dragHandleCellClass", "attr.aria-label": "this.dragRowHandleLabel" } }, ngImport: i0, template: `
<ng-container [ngSwitch]="isEdited">
<ng-container *ngSwitchCase="false">
<ng-container *ngIf="column.expandable">
<kendo-icon-wrapper name="none" innerCssClass="k-treelist-toggle" [svgIcon]="noneIcon" *ngFor="let item of level | levelItems : hasChildren && expandIcons"></kendo-icon-wrapper>
<kendo-icon-wrapper innerCssClass="k-treelist-toggle"
aria-hidden="true"
*ngIf="hasChildren && expandIcons && !loading"
[name]="arrowIcon"
[svgIcon]="arrowSVGIcon"></kendo-icon-wrapper>
<span class="k-icon k-i-loading" *ngIf="hasChildren && expandIcons && loading"></span>
</ng-container>
<ng-container *ngIf="column.templateRef"
[ngTemplateOutlet]="column.templateRef"
[ngTemplateOutletContext]="templateContext">
</ng-container>
<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-template [ngIf]="column.isCheckboxColumn && !isNew">
<kendo-checkbox
kendoTreeListFocusable
[inputAttributes]="{'aria-label': messageFor('selectRowCheckboxLabel')}"
[checkedState]="selected"
></kendo-checkbox>
</ng-template>
<ng-container *ngIf="column.isRowReorderColumn && !isNew">
<kendo-icon-wrapper
name="reorder"
[svgIcon]="reorderIcon">
</kendo-icon-wrapper>
</ng-container>
</ng-container>
<ng-container *ngSwitchCase="true">
<ng-container
*ngIf="column.editTemplateRef"
[ngTemplateOutlet]="column.editTemplateRef"
[ngTemplateOutletContext]="editTemplateContext">
</ng-container>
<ng-container [ngSwitch]="column.editor" *ngIf="!column.editTemplateRef">
<kendo-numerictextbox
*ngSwitchCase="'numeric'"
[format]="format"
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-numerictextbox>
<kendo-datepicker
*ngSwitchCase="'date'"
[format]="format"
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-datepicker>
<kendo-checkbox
*ngSwitchCase="'boolean'"
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-checkbox>
<kendo-textbox
*ngSwitchDefault
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></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: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: FocusableDirective, selector: "[kendoTreeListFocusable],\n [kendoTreeListAddCommand],\n [kendoTreeListEditCommand],\n [kendoTreeListRemoveCommand],\n [kendoTreeListSaveCommand],\n [kendoTreeListCancelCommand]\n ", inputs: ["kendoTreeListFocusable", "enabled", "kendoTreeListAddCommand", "kendoTreeListEditCommand", "kendoTreeListRemoveCommand", "kendoTreeListSaveCommand", "kendoTreeListCancelCommand"] }, { 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: "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: 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", "adaptiveTitle", "adaptiveSubtitle", "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: "pipe", type: LevelItemsPipe, name: "levelItems" }, { 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: '[kendoTreeListCell]',
template: `
<ng-container [ngSwitch]="isEdited">
<ng-container *ngSwitchCase="false">
<ng-container *ngIf="column.expandable">
<kendo-icon-wrapper name="none" innerCssClass="k-treelist-toggle" [svgIcon]="noneIcon" *ngFor="let item of level | levelItems : hasChildren && expandIcons"></kendo-icon-wrapper>
<kendo-icon-wrapper innerCssClass="k-treelist-toggle"
aria-hidden="true"
*ngIf="hasChildren && expandIcons && !loading"
[name]="arrowIcon"
[svgIcon]="arrowSVGIcon"></kendo-icon-wrapper>
<span class="k-icon k-i-loading" *ngIf="hasChildren && expandIcons && loading"></span>
</ng-container>
<ng-container *ngIf="column.templateRef"
[ngTemplateOutlet]="column.templateRef"
[ngTemplateOutletContext]="templateContext">
</ng-container>
<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-template [ngIf]="column.isCheckboxColumn && !isNew">
<kendo-checkbox
kendoTreeListFocusable
[inputAttributes]="{'aria-label': messageFor('selectRowCheckboxLabel')}"
[checkedState]="selected"
></kendo-checkbox>
</ng-template>
<ng-container *ngIf="column.isRowReorderColumn && !isNew">
<kendo-icon-wrapper
name="reorder"
[svgIcon]="reorderIcon">
</kendo-icon-wrapper>
</ng-container>
</ng-container>
<ng-container *ngSwitchCase="true">
<ng-container
*ngIf="column.editTemplateRef"
[ngTemplateOutlet]="column.editTemplateRef"
[ngTemplateOutletContext]="editTemplateContext">
</ng-container>
<ng-container [ngSwitch]="column.editor" *ngIf="!column.editTemplateRef">
<kendo-numerictextbox
*ngSwitchCase="'numeric'"
[format]="format"
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-numerictextbox>
<kendo-datepicker
*ngSwitchCase="'date'"
[format]="format"
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-datepicker>
<kendo-checkbox
*ngSwitchCase="'boolean'"
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-checkbox>
<kendo-textbox
*ngSwitchDefault
[formControl]="$any(formGroup.get(column.field))"
kendoTreeListFocusable
></kendo-textbox>
</ng-container>
</ng-container>
</ng-container>
`,
standalone: true,
imports: [NgSwitch, NgSwitchCase, NgIf, NgFor, IconWrapperComponent, NgTemplateOutlet, FocusableDirective, NumericTextBoxComponent, ReactiveFormsModule, DatePickerComponent, NgSwitchDefault, FieldAccessorPipe, LevelItemsPipe, CheckBoxComponent, TextBoxComponent]
}]
}], ctorParameters: function () { return [{ type: i1.EditService }, { type: i2.LocalizationService }, { type: i3.FocusGroup }]; }, propDecorators: { commandCellClass: [{
type: HostBinding,
args: ['class.k-command-cell']
}], isCheckboxColumn: [{
type: HostBinding,
args: ['class.k-checkbox-cell']
}], textNoWrapClass: [{
type: HostBinding,
args: ['class.k-text-nowrap']
}], 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
}], level: [{
type: Input
}], hasChildren: [{
type: Input
}], isExpanded: [{
type: Input
}], loading: [{
type: Input
}], expandIcons: [{
type: Input
}], rowIndex: [{
type: Input
}], selected: [{
type: Input
}], dataItem: [{
type: Input
}], viewItem: [{
type: Input
}] } });