UNPKG

@progress/kendo-angular-grid

Version:

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

208 lines (207 loc) 8.05 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { Input, EventEmitter, Output, ChangeDetectorRef, Directive } from '@angular/core'; import { isPresent } from "../utils"; import { PairSet } from './pair-set'; import { ContextService } from '../common/provider.service'; import * as i0 from "@angular/core"; import * as i1 from "../common/provider.service"; /** * @hidden */ export class Selection { ctx; cd; /** * Defines the collection that will store the selected item keys. * @default [] */ selectedKeys = []; /** * Defines the initial shift-click range selection starting row index. * * @default 0 */ rangeSelectionStartRow; /** * Defines the initial shift-click range selection starting column index when cell selection is enabled. * * @default 0 */ rangeSelectionStartColumnIndex = 0; /** * Defines the item key that will be stored in the `selectedKeys` collection. [See example](slug:grid_selection_persistence#by-a-custom-key). */ selectionKey; /** * Defines a function that determines the column key of a data cell. * * The function should return an unique value for each column. * By default, the Grid uses the column index as a column key. */ columnKey; /** * Fires when the `selectedKeys` collection has been updated. */ selectedKeysChange = new EventEmitter(); rowSelectionState = new Set(); cellSelectionState = new PairSet(); /** * @hidden */ get isCellSelectionMode() { return isPresent(this.ctx.grid.selectable) && this.ctx.grid.selectable['cell']; } lastSelectionState; selectionChangeSubscription; constructor(ctx, cd) { this.ctx = ctx; this.cd = cd; this.init(); } ngOnChanges(changes) { // skip reinitialization if the user data is the same as the last state change if (isPresent(changes['selectedKeys']) && this.lastSelectionState !== this.selectedKeys) { this.setState(this.selectedKeys); } } init() { if (!isPresent(this.ctx.grid.rowSelected)) { this.ctx.grid.rowSelected = (row) => this.rowSelectionState.has(this.getItemKey(row)); } if (!isPresent(this.ctx.grid.isRowSelectable)) { this.ctx.grid.isRowSelectable = () => Boolean(this.ctx.grid.selectable); } if (!isPresent(this.ctx.grid.cellSelected)) { this.ctx.grid.cellSelected = (row, column, colIndex) => { const contender = this.getSelectionItem(row, column, colIndex); return { selected: this.cellSelectionState.has(contender.itemKey, contender.columnKey), item: contender }; }; } this.selectionChangeSubscription = this.ctx.grid .selectionChange .subscribe(this.onSelectionChange.bind(this)); } /** * @hidden */ destroy() { this.selectionChangeSubscription.unsubscribe(); } /** * @hidden */ reset() { this.rowSelectionState.clear(); this.cellSelectionState.clear(); } /** * @hidden */ getItemKey(row) { if (this.selectionKey) { if (typeof this.selectionKey === "string") { return row.dataItem[this.selectionKey]; } if (typeof this.selectionKey === "function") { return this.selectionKey(row); } } return row.index; } /** * @hidden */ stateToArray() { return this.isCellSelectionMode ? this.cellSelectionState.toArray('itemKey', 'columnKey') : Array.from(this.rowSelectionState); } getSelectionItem(row, col, colIndex) { const itemIdentifiers = {}; itemIdentifiers.itemKey = this.getItemKey(row); if (!isPresent(col) && !isPresent(colIndex)) { return itemIdentifiers; } if (this.columnKey) { if (typeof this.columnKey === "string") { itemIdentifiers.columnKey = row.dataItem[this.columnKey]; } if (typeof this.columnKey === "function") { itemIdentifiers.columnKey = this.columnKey(col, colIndex); } } return { itemKey: itemIdentifiers.itemKey, columnKey: itemIdentifiers.columnKey ? itemIdentifiers.columnKey : colIndex }; } onSelectionChange(selection) { if (selection.selectedRows) { selection.deselectedRows.forEach((item) => { const itemKey = this.getItemKey(item); this.rowSelectionState.delete(itemKey); }); if (this.ctx.grid.selectableSettings.mode === "single" && this.rowSelectionState.size > 0) { this.reset(); } selection.selectedRows.forEach((item) => { const itemKey = this.getItemKey(item); this.rowSelectionState.add(itemKey); }); } else { selection.deselectedCells.forEach(({ itemKey, columnKey }) => { this.cellSelectionState.delete(itemKey, columnKey); }); if (this.ctx.grid.selectableSettings.mode === "single" && this.cellSelectionState.size > 0) { this.reset(); } selection.selectedCells.forEach(({ itemKey, columnKey }) => { this.cellSelectionState.add(itemKey, columnKey); }); } this.cd.markForCheck(); this.notifyChange(); } notifyChange() { this.lastSelectionState = this.stateToArray(); this.selectedKeysChange.emit(this.lastSelectionState); } setState(selectedKeys) { this.reset(); if (this.isCellSelectionMode) { this.cellSelectionState = new PairSet(selectedKeys, 'itemKey', 'columnKey'); } else { this.rowSelectionState = new Set(selectedKeys); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Selection, deps: [{ token: i1.ContextService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Selection, selector: "kendo-grid-selection-base", inputs: { selectedKeys: "selectedKeys", rangeSelectionStartRow: "rangeSelectionStartRow", rangeSelectionStartColumnIndex: "rangeSelectionStartColumnIndex", selectionKey: ["kendoGridSelectBy", "selectionKey"], columnKey: "columnKey" }, outputs: { selectedKeysChange: "selectedKeysChange" }, usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Selection, decorators: [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: 'kendo-grid-selection-base' }] }], ctorParameters: function () { return [{ type: i1.ContextService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { selectedKeys: [{ type: Input }], rangeSelectionStartRow: [{ type: Input }], rangeSelectionStartColumnIndex: [{ type: Input }], selectionKey: [{ type: Input, args: ["kendoGridSelectBy"] }], columnKey: [{ type: Input }], selectedKeysChange: [{ type: Output }] } });