UNPKG

@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.

224 lines (223 loc) 8.72 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Directive, Input, Output, EventEmitter } from '@angular/core'; import { TreeListComponent } from '../treelist.component'; import { getter } from '@progress/kendo-common'; import { isString } from '../utils'; import { createState, RowSelectionState } from './selection-state'; import { SelectionService } from './selection.service'; import * as i0 from "@angular/core"; import * as i1 from "../treelist.component"; import * as i2 from "./selection.service"; const defaultColumnKeyGetter = (_column, columnIndex) => columnIndex; /** * A directive which controls the selection state. [See example](slug:selection_treelist). * * @example * ```html * <kendo-treelist * [kendoTreeListSelectable]="{ mode: 'row' }" * [selectedItems]="selectedItems"> * <kendo-treelist-column field="name" title="Name"></kendo-treelist-column> * <kendo-treelist-column field="age" title="Age"></kendo-treelist-column> * </kendo-treelist> * ``` * @remarks * Applied to: {@link TreeListComponent}. */ export class SelectableDirective { treelist; selectionService; /** * @hidden */ set selectable(value) { if (typeof value === 'object') { // add method to normalize this this._settings = value; } else { this._settings = { enabled: value }; } this.state = createState(this._settings); this.state.fromArray(this._selectedItems || []); if (this._settings.enabled !== false) { this.treelist.isSelected = this._settings.mode === 'cell' ? this.cellSelected : this.rowSelected; this.subscribeSelection(); } else { this.treelist.isSelected = () => false; this.unsubscribeSelection(); } this.treelist.updateView(); } /** * Specifies the selected items. */ set selectedItems(value) { if (!value) { this.state.clear(); } else if (value !== this.lastChange) { this.state.fromArray(value); this.treelist.updateView(); } this._selectedItems = value; const currentValue = value || []; const previousState = this.selectionService.selectAllCheckedState; if (currentValue.length > 0 && currentValue.length === this.treelist.view.total) { this.selectionService.selectAllCheckedState = true; } else if (currentValue.length === 0) { this.selectionService.selectAllCheckedState = false; } else { this.selectionService.selectAllCheckedState = 'indeterminate'; } if (previousState !== this.selectionService.selectAllCheckedState) { this.selectionService.selectAllCheckedStateChange.next(this.selectionService.selectAllCheckedState); } } /** * Fires when the selected items are changed. */ selectedItemsChange = new EventEmitter(); /** * The field name or a function that specify the dataItems key. */ set itemKey(value) { if (isString(value)) { this._keyGetter = getter(String(value)); } else { this._keyGetter = value; } } /** * The field name or a function that specify the columns key. */ set columnKey(value) { if (isString(value)) { this._columnKeyGetter = getter(String(value)); } else if (value) { this._columnKeyGetter = value; } } get keyGetter() { return this._keyGetter || this.treelist.idGetter; } get columnKeyGetter() { return this._columnKeyGetter || defaultColumnKeyGetter; } subscriptions; state = new RowSelectionState(); _settings; lastChange; _columnKeyGetter; _keyGetter; _selectedItems = []; constructor(treelist, selectionService) { this.treelist = treelist; this.selectionService = selectionService; this.cellSelected = this.cellSelected.bind(this); this.rowSelected = this.rowSelected.bind(this); this.selectionChange = this.selectionChange.bind(this); this.updateColumnIndices = this.updateColumnIndices.bind(this); this.treelist.selectable = this.selectable = true; } ngOnDestroy() { this.unsubscribeSelection(); } /** * @hidden */ cellSelected(dataItem, column, columnIndex) { return this.state.has(this.keyGetter(dataItem), this.columnKeyGetter(column, columnIndex)); } /** * @hidden */ rowSelected(dataItem) { return this.state.has(this.keyGetter(dataItem)); } selectionChange({ action, items }) { if (action === 'select' || action === 'add') { if (action === 'select') { this.state.clear(); } items.forEach(item => { this.state.add(this.keyGetter(item.dataItem), this.columnKeyGetter(item.column, item.columnIndex)); }); } else { items.forEach(item => { this.state.remove(this.keyGetter(item.dataItem), this.columnKeyGetter(item.column, item.columnIndex)); }); } this.emitSelectedItemsChange(); } emitSelectedItemsChange() { this.selectionService.state = this.lastChange = this.state.toArray(); this.selectedItemsChange.emit(this.lastChange); } subscribeSelection() { this.unsubscribeSelection(); this.subscriptions = this.treelist.selectionChange.subscribe(this.selectionChange); if (this._settings.mode === 'cell') { this.subscriptions.add(this.treelist.columnOrderChange.subscribe(this.updateColumnIndices)); this.subscriptions.add(this.treelist.columnLockedChange.subscribe(this.updateColumnIndices)); } } unsubscribeSelection() { if (this.subscriptions) { this.subscriptions.unsubscribe(); this.subscriptions = null; } } updateColumnIndices() { if (!this._columnKeyGetter) { const changes = new Map(); const currentIndices = []; this.leafColumns.forEach((column) => { currentIndices.push(column); }); this.treelist.columnsContainer.refresh(); const leafColumns = this.leafColumns; currentIndices.forEach((column, index) => { if (column !== leafColumns[index]) { changes.set(index, leafColumns.indexOf(column)); } }); if (changes.size && this.state.updateColumKeys(changes)) { this.emitSelectedItemsChange(); } } } get leafColumns() { return this.treelist.lockedLeafColumns.toArray().concat(this.treelist.nonLockedLeafColumns.toArray()); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectableDirective, deps: [{ token: i1.TreeListComponent }, { token: i2.SelectionService }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SelectableDirective, isStandalone: true, selector: "[kendoTreeListSelectable]", inputs: { selectable: "selectable", selectedItems: "selectedItems", itemKey: "itemKey", columnKey: "columnKey" }, outputs: { selectedItemsChange: "selectedItemsChange" }, exportAs: ["kendoTreeListSelectable"], ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectableDirective, decorators: [{ type: Directive, args: [{ exportAs: 'kendoTreeListSelectable', selector: '[kendoTreeListSelectable]', standalone: true }] }], ctorParameters: function () { return [{ type: i1.TreeListComponent }, { type: i2.SelectionService }]; }, propDecorators: { selectable: [{ type: Input }], selectedItems: [{ type: Input }], selectedItemsChange: [{ type: Output }], itemKey: [{ type: Input }], columnKey: [{ type: Input }] } });