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