@progress/kendo-angular-grid 5.5.1 → 6.0.0-dev.202201191529
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/NOTICE.txt +119 -79
- package/README.md +1 -1
- package/dist/cdn/js/kendo-angular-grid.js +2 -2
- package/dist/cdn/main.js +1 -1
- package/dist/es/column-menu/column-chooser.component.js +1 -1
- package/dist/es/column-menu/column-list.component.js +1 -1
- package/dist/es/dragdrop/draggable-column.directive.js +3 -3
- package/dist/es/filtering/cell/filter-cell-operators.component.js +1 -1
- package/dist/es/filtering/cell/string-filter-cell.component.js +1 -1
- package/dist/es/filtering/filter-input.directive.js +2 -1
- package/dist/es/filtering/menu/boolean-filter-menu.component.js +1 -1
- package/dist/es/filtering/menu/filter-menu-container.component.js +1 -1
- package/dist/es/filtering/menu/filter-menu-input-wrapper.component.js +2 -2
- package/dist/es/filtering/menu/string-filter-menu-input.component.js +1 -1
- package/dist/es/grid.component.js +4 -5
- package/dist/es/grouping/group-indicator.component.js +1 -1
- package/dist/es/navigation/focusable.directive.js +5 -5
- package/dist/es/package-metadata.js +1 -1
- package/dist/es/pager/pager-numeric-buttons.component.js +1 -1
- package/dist/es/pager/pager.component.js +0 -5
- package/dist/es/pdf/export-element.js +1 -1
- package/dist/es/rendering/cell.component.js +1 -1
- package/dist/es/rendering/constants.js +1 -1
- package/dist/es/rendering/details-expand.directive.js +20 -6
- package/dist/es/rendering/header/header.component.js +1 -1
- package/dist/es/rendering/toolbar/toolbar-template.directive.js +4 -4
- package/dist/es/selection/pair-set.js +91 -0
- package/dist/es/selection/selection-default.js +48 -30
- package/dist/es/utils.js +1 -3
- package/dist/es2015/column-menu/column-chooser.component.js +2 -2
- package/dist/es2015/column-menu/column-list.component.js +3 -3
- package/dist/es2015/dragdrop/draggable-column.directive.js +3 -3
- package/dist/es2015/filtering/cell/filter-cell-operators.component.js +3 -3
- package/dist/es2015/filtering/cell/string-filter-cell.component.js +1 -1
- package/dist/es2015/filtering/filter-input.directive.js +2 -1
- package/dist/es2015/filtering/menu/boolean-filter-menu.component.js +1 -1
- package/dist/es2015/filtering/menu/filter-menu-container.component.js +2 -2
- package/dist/es2015/filtering/menu/filter-menu-input-wrapper.component.d.ts +2 -2
- package/dist/es2015/filtering/menu/filter-menu-input-wrapper.component.js +2 -2
- package/dist/es2015/filtering/menu/string-filter-menu-input.component.js +1 -1
- package/dist/es2015/grid.component.d.ts +4 -4
- package/dist/es2015/grid.component.js +4 -5
- package/dist/es2015/grouping/group-indicator.component.js +2 -2
- package/dist/es2015/index.metadata.json +1 -1
- package/dist/es2015/navigation/focusable.directive.d.ts +5 -5
- package/dist/es2015/navigation/focusable.directive.js +5 -5
- package/dist/es2015/package-metadata.js +1 -1
- package/dist/es2015/pager/pager-numeric-buttons.component.js +1 -1
- package/dist/es2015/pager/pager.component.d.ts +0 -1
- package/dist/es2015/pager/pager.component.js +0 -5
- package/dist/es2015/pdf/export-element.js +1 -1
- package/dist/es2015/rendering/cell.component.js +3 -3
- package/dist/es2015/rendering/constants.d.ts +1 -1
- package/dist/es2015/rendering/constants.js +1 -1
- package/dist/es2015/rendering/details-expand.directive.d.ts +8 -2
- package/dist/es2015/rendering/details-expand.directive.js +20 -6
- package/dist/es2015/rendering/header/header.component.js +1 -1
- package/dist/es2015/rendering/toolbar/toolbar-template.directive.d.ts +4 -4
- package/dist/es2015/rendering/toolbar/toolbar-template.directive.js +4 -4
- package/dist/es2015/selection/pair-set.d.ts +50 -0
- package/dist/es2015/selection/pair-set.js +81 -0
- package/dist/es2015/selection/selection-default.d.ts +10 -2
- package/dist/es2015/selection/selection-default.js +42 -28
- package/dist/es2015/utils.d.ts +2 -2
- package/dist/fesm2015/index.js +179 -78
- package/dist/fesm5/index.js +186 -74
- package/dist/npm/column-menu/column-chooser.component.js +1 -1
- package/dist/npm/column-menu/column-list.component.js +1 -1
- package/dist/npm/dragdrop/draggable-column.directive.js +3 -3
- package/dist/npm/filtering/cell/filter-cell-operators.component.js +1 -1
- package/dist/npm/filtering/cell/string-filter-cell.component.js +1 -1
- package/dist/npm/filtering/filter-input.directive.js +2 -1
- package/dist/npm/filtering/menu/boolean-filter-menu.component.js +1 -1
- package/dist/npm/filtering/menu/filter-menu-container.component.js +1 -1
- package/dist/npm/filtering/menu/filter-menu-input-wrapper.component.js +2 -2
- package/dist/npm/filtering/menu/string-filter-menu-input.component.js +1 -1
- package/dist/npm/grid.component.js +4 -5
- package/dist/npm/grouping/group-indicator.component.js +1 -1
- package/dist/npm/navigation/focusable.directive.js +5 -5
- package/dist/npm/package-metadata.js +1 -1
- package/dist/npm/pager/pager-numeric-buttons.component.js +1 -1
- package/dist/npm/pager/pager.component.js +0 -5
- package/dist/npm/pdf/export-element.js +1 -1
- package/dist/npm/rendering/cell.component.js +1 -1
- package/dist/npm/rendering/constants.js +1 -1
- package/dist/npm/rendering/details-expand.directive.js +19 -5
- package/dist/npm/rendering/header/header.component.js +1 -1
- package/dist/npm/rendering/toolbar/toolbar-template.directive.js +4 -4
- package/dist/npm/selection/pair-set.js +93 -0
- package/dist/npm/selection/selection-default.js +48 -30
- package/dist/npm/utils.js +1 -3
- package/dist/systemjs/kendo-angular-grid.js +1 -1
- package/package.json +16 -16
|
@@ -14,7 +14,7 @@ import { CellContext } from '../rendering/common/cell-context';
|
|
|
14
14
|
* _@Component({
|
|
15
15
|
* selector: 'my-app',
|
|
16
16
|
* template: `
|
|
17
|
-
* <input type="text"
|
|
17
|
+
* <input type="text" placeholder="Tab stop #0" style="margin-bottom: 8px;" />
|
|
18
18
|
* <kendo-grid [data]="data" [navigable]="true">
|
|
19
19
|
* <kendo-grid-column field="ProductID" title="Product ID" width="100">
|
|
20
20
|
* </kendo-grid-column>
|
|
@@ -23,18 +23,18 @@ import { CellContext } from '../rendering/common/cell-context';
|
|
|
23
23
|
* <kendo-grid-column>
|
|
24
24
|
* <ng-template kendoGridCellTemplate let-dataItem>
|
|
25
25
|
* <!-- The first focusable element will be focused when pressing Enter on the cell -->
|
|
26
|
-
* <input type="text"
|
|
27
|
-
* <button
|
|
26
|
+
* <input type="text" kendoGridFocusable [value]="dataItem.ProductName" style="margin-right: 8px;" />
|
|
27
|
+
* <button kendoGridFocusable>Update</button>
|
|
28
28
|
* </ng-template>
|
|
29
29
|
* </kendo-grid-column>
|
|
30
30
|
* <kendo-grid-column width="100">
|
|
31
31
|
* <ng-template kendoGridCellTemplate>
|
|
32
32
|
* <!-- A single focusable element will be focused during navigation -->
|
|
33
|
-
* <button
|
|
33
|
+
* <button kendoGridFocusable>Delete</button>
|
|
34
34
|
* </ng-template>
|
|
35
35
|
* </kendo-grid-column>
|
|
36
36
|
* </kendo-grid>
|
|
37
|
-
* <input type="text"
|
|
37
|
+
* <input type="text" placeholder="Tab stop #2" style="margin-top: 8px;" />
|
|
38
38
|
* `
|
|
39
39
|
* })
|
|
40
40
|
*
|
|
@@ -15,7 +15,7 @@ import { CELL_CONTEXT } from '../rendering/common/cell-context';
|
|
|
15
15
|
* _@Component({
|
|
16
16
|
* selector: 'my-app',
|
|
17
17
|
* template: `
|
|
18
|
-
* <input type="text"
|
|
18
|
+
* <input type="text" placeholder="Tab stop #0" style="margin-bottom: 8px;" />
|
|
19
19
|
* <kendo-grid [data]="data" [navigable]="true">
|
|
20
20
|
* <kendo-grid-column field="ProductID" title="Product ID" width="100">
|
|
21
21
|
* </kendo-grid-column>
|
|
@@ -24,18 +24,18 @@ import { CELL_CONTEXT } from '../rendering/common/cell-context';
|
|
|
24
24
|
* <kendo-grid-column>
|
|
25
25
|
* <ng-template kendoGridCellTemplate let-dataItem>
|
|
26
26
|
* <!-- The first focusable element will be focused when pressing Enter on the cell -->
|
|
27
|
-
* <input type="text"
|
|
28
|
-
* <button
|
|
27
|
+
* <input type="text" kendoGridFocusable [value]="dataItem.ProductName" style="margin-right: 8px;" />
|
|
28
|
+
* <button kendoGridFocusable>Update</button>
|
|
29
29
|
* </ng-template>
|
|
30
30
|
* </kendo-grid-column>
|
|
31
31
|
* <kendo-grid-column width="100">
|
|
32
32
|
* <ng-template kendoGridCellTemplate>
|
|
33
33
|
* <!-- A single focusable element will be focused during navigation -->
|
|
34
|
-
* <button
|
|
34
|
+
* <button kendoGridFocusable>Delete</button>
|
|
35
35
|
* </ng-template>
|
|
36
36
|
* </kendo-grid-column>
|
|
37
37
|
* </kendo-grid>
|
|
38
|
-
* <input type="text"
|
|
38
|
+
* <input type="text" placeholder="Tab stop #2" style="margin-top: 8px;" />
|
|
39
39
|
* `
|
|
40
40
|
* })
|
|
41
41
|
*
|
|
@@ -9,7 +9,7 @@ export const packageMetadata = {
|
|
|
9
9
|
name: '@progress/kendo-angular-grid',
|
|
10
10
|
productName: 'Kendo UI for Angular',
|
|
11
11
|
productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
|
|
12
|
-
publishDate:
|
|
12
|
+
publishDate: 1642605543,
|
|
13
13
|
version: '',
|
|
14
14
|
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
|
|
15
15
|
};
|
|
@@ -97,7 +97,7 @@ PagerNumericButtonsComponent = tslib_1.__decorate([
|
|
|
97
97
|
selector: 'kendo-pager-numeric-buttons',
|
|
98
98
|
template: `
|
|
99
99
|
<select
|
|
100
|
-
class="k-
|
|
100
|
+
class="k-dropdownlist k-pager-nav"
|
|
101
101
|
kendoGridFocusable
|
|
102
102
|
tabindex="0"
|
|
103
103
|
[value]="(currentPage).toString()"
|
|
@@ -33,7 +33,6 @@ export declare class PagerComponent implements OnChanges, OnInit, OnDestroy {
|
|
|
33
33
|
pageChange: EventEmitter<PageChangeEvent>;
|
|
34
34
|
pagerWrapClass: boolean;
|
|
35
35
|
gridPagerClass: boolean;
|
|
36
|
-
widgetClass: boolean;
|
|
37
36
|
settings: PagerSettings;
|
|
38
37
|
private subscriptions;
|
|
39
38
|
private _templateContext;
|
|
@@ -36,7 +36,6 @@ let PagerComponent = class PagerComponent {
|
|
|
36
36
|
this.pageChange = new EventEmitter();
|
|
37
37
|
this.pagerWrapClass = true;
|
|
38
38
|
this.gridPagerClass = true;
|
|
39
|
-
this.widgetClass = true;
|
|
40
39
|
this.settings = normalize({});
|
|
41
40
|
this.subscriptions = new Subscription();
|
|
42
41
|
this._templateContext = {};
|
|
@@ -251,10 +250,6 @@ tslib_1.__decorate([
|
|
|
251
250
|
HostBinding('class.k-grid-pager'),
|
|
252
251
|
tslib_1.__metadata("design:type", Boolean)
|
|
253
252
|
], PagerComponent.prototype, "gridPagerClass", void 0);
|
|
254
|
-
tslib_1.__decorate([
|
|
255
|
-
HostBinding('class.k-widget'),
|
|
256
|
-
tslib_1.__metadata("design:type", Boolean)
|
|
257
|
-
], PagerComponent.prototype, "widgetClass", void 0);
|
|
258
253
|
tslib_1.__decorate([
|
|
259
254
|
HostBinding('class.k-state-focused'),
|
|
260
255
|
tslib_1.__metadata("design:type", Boolean),
|
|
@@ -34,7 +34,7 @@ const appendNodes = (element, nodes) => {
|
|
|
34
34
|
const ɵ0 = appendNodes;
|
|
35
35
|
const wrapTable = (table) => {
|
|
36
36
|
const wrapper = document.createElement('div');
|
|
37
|
-
wrapper.className = 'k-
|
|
37
|
+
wrapper.className = 'k-grid';
|
|
38
38
|
wrapper.appendChild(table);
|
|
39
39
|
return wrapper;
|
|
40
40
|
};
|
|
@@ -189,7 +189,7 @@ CellComponent = tslib_1.__decorate([
|
|
|
189
189
|
<ng-template [ngIf]="isBoundColumn">{{ dataItem | valueOf: column.field: column.format}}</ng-template>
|
|
190
190
|
<ng-template [ngIf]="isCheckboxColumn && !isNew">
|
|
191
191
|
<input
|
|
192
|
-
class="k-checkbox"
|
|
192
|
+
class="k-checkbox k-checkbox-md k-rounded-md"
|
|
193
193
|
[kendoGridSelectionCheckbox]="rowIndex"
|
|
194
194
|
[attr.id]="selectionCheckboxId"
|
|
195
195
|
[attr.aria-label]="selectionCheckboxLabel" />
|
|
@@ -228,7 +228,7 @@ CellComponent = tslib_1.__decorate([
|
|
|
228
228
|
<input
|
|
229
229
|
*ngSwitchCase="'boolean'"
|
|
230
230
|
type="checkbox"
|
|
231
|
-
class="k-checkbox"
|
|
231
|
+
class="k-checkbox k-checkbox-md k-rounded-md"
|
|
232
232
|
[formControl]="formGroup.get(column.field)"
|
|
233
233
|
kendoGridFocusable
|
|
234
234
|
/>
|
|
@@ -236,7 +236,7 @@ CellComponent = tslib_1.__decorate([
|
|
|
236
236
|
<input
|
|
237
237
|
*ngSwitchDefault
|
|
238
238
|
type="text"
|
|
239
|
-
class="k-textbox"
|
|
239
|
+
class="k-textbox k-input k-rounded-md"
|
|
240
240
|
[formControl]="formGroup.get(column.field)"
|
|
241
241
|
kendoGridFocusable
|
|
242
242
|
/>
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { EventEmitter, OnDestroy } from '@angular/core';
|
|
5
|
+
import { EventEmitter, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
|
|
6
6
|
import { GridComponent } from '../grid.component';
|
|
7
7
|
import { Subscription } from 'rxjs';
|
|
8
8
|
import { RowArgs } from './common/row-args';
|
|
9
9
|
/**
|
|
10
10
|
* A directive which controls the expanded state of the master detail rows.
|
|
11
11
|
*/
|
|
12
|
-
export declare class ExpandDetailsDirective implements OnDestroy {
|
|
12
|
+
export declare class ExpandDetailsDirective implements OnChanges, OnDestroy {
|
|
13
13
|
protected grid: GridComponent;
|
|
14
14
|
/**
|
|
15
15
|
* Fires when the expandedDetailKeys are changed.
|
|
@@ -31,12 +31,17 @@ export declare class ExpandDetailsDirective implements OnDestroy {
|
|
|
31
31
|
expandedDetailKeys: any[];
|
|
32
32
|
/**
|
|
33
33
|
* Specifies if the items should be initially expanded.
|
|
34
|
+
* When set to `true` items added to the `expandedDetailKeys` collection will be collapsed, and items that are not present in it will be expanded.
|
|
35
|
+
*
|
|
34
36
|
* @default false
|
|
35
37
|
*/
|
|
36
38
|
initiallyExpanded: boolean;
|
|
39
|
+
protected expandedState: Set<any>;
|
|
40
|
+
protected lastExpandedState: any[];
|
|
37
41
|
protected _expandBy: any;
|
|
38
42
|
protected subscriptions: Subscription;
|
|
39
43
|
constructor(grid: GridComponent);
|
|
44
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
40
45
|
ngOnDestroy(): void;
|
|
41
46
|
protected readonly keyGetter: any;
|
|
42
47
|
/**
|
|
@@ -44,4 +49,5 @@ export declare class ExpandDetailsDirective implements OnDestroy {
|
|
|
44
49
|
*/
|
|
45
50
|
isExpanded(args: RowArgs): boolean;
|
|
46
51
|
private toggleState;
|
|
52
|
+
private notifyChange;
|
|
47
53
|
}
|
|
@@ -8,7 +8,7 @@ import { GridComponent } from '../grid.component';
|
|
|
8
8
|
import { Subscription, merge } from 'rxjs';
|
|
9
9
|
import { map } from 'rxjs/operators';
|
|
10
10
|
import { getter } from '@progress/kendo-common';
|
|
11
|
-
import { isString } from '../utils';
|
|
11
|
+
import { isPresent, isString } from '../utils';
|
|
12
12
|
/**
|
|
13
13
|
* A directive which controls the expanded state of the master detail rows.
|
|
14
14
|
*/
|
|
@@ -25,9 +25,12 @@ let ExpandDetailsDirective = class ExpandDetailsDirective {
|
|
|
25
25
|
this.expandedDetailKeys = [];
|
|
26
26
|
/**
|
|
27
27
|
* Specifies if the items should be initially expanded.
|
|
28
|
+
* When set to `true` items added to the `expandedDetailKeys` collection will be collapsed, and items that are not present in it will be expanded.
|
|
29
|
+
*
|
|
28
30
|
* @default false
|
|
29
31
|
*/
|
|
30
32
|
this.initiallyExpanded = false;
|
|
33
|
+
this.expandedState = new Set();
|
|
31
34
|
this.subscriptions = new Subscription();
|
|
32
35
|
this.grid.isDetailExpanded = this.isExpanded.bind(this);
|
|
33
36
|
this.subscriptions.add(merge(this.grid.detailExpand.pipe(map(e => (Object.assign({ expand: true }, e)))), this.grid.detailCollapse.pipe(map(e => (Object.assign({ expand: false }, e))))).subscribe(this.toggleState.bind(this)));
|
|
@@ -57,6 +60,12 @@ let ExpandDetailsDirective = class ExpandDetailsDirective {
|
|
|
57
60
|
set expandDetailBy(key) {
|
|
58
61
|
this.expandDetailsKey = key;
|
|
59
62
|
}
|
|
63
|
+
ngOnChanges(changes) {
|
|
64
|
+
// skip reinitialization if the user data is the same as the last state change
|
|
65
|
+
if (isPresent(changes.expandedDetailKeys) && this.lastExpandedState !== this.expandedDetailKeys) {
|
|
66
|
+
this.expandedState = new Set(this.expandedDetailKeys);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
60
69
|
ngOnDestroy() {
|
|
61
70
|
this.subscriptions.unsubscribe();
|
|
62
71
|
}
|
|
@@ -68,18 +77,23 @@ let ExpandDetailsDirective = class ExpandDetailsDirective {
|
|
|
68
77
|
*/
|
|
69
78
|
isExpanded(args) {
|
|
70
79
|
const key = this.keyGetter(args.dataItem);
|
|
71
|
-
|
|
80
|
+
const hasKey = this.expandedState.has(key);
|
|
81
|
+
// when [initiallyExpanded]="true" a present key means the corresponding detail row is collapsed
|
|
82
|
+
return this.initiallyExpanded ? !hasKey : hasKey;
|
|
72
83
|
}
|
|
73
84
|
toggleState(args) {
|
|
74
85
|
const key = this.keyGetter(args.dataItem);
|
|
75
86
|
if (Boolean(this.initiallyExpanded) !== args.expand) {
|
|
76
|
-
this.
|
|
87
|
+
this.expandedState.add(key);
|
|
77
88
|
}
|
|
78
89
|
else {
|
|
79
|
-
|
|
80
|
-
this.expandedDetailKeys.splice(index, 1);
|
|
90
|
+
this.expandedState.delete(key);
|
|
81
91
|
}
|
|
82
|
-
this.
|
|
92
|
+
this.notifyChange();
|
|
93
|
+
}
|
|
94
|
+
notifyChange() {
|
|
95
|
+
this.lastExpandedState = Array.from(this.expandedState);
|
|
96
|
+
this.expandedDetailKeysChange.emit(this.lastExpandedState);
|
|
83
97
|
}
|
|
84
98
|
};
|
|
85
99
|
tslib_1.__decorate([
|
|
@@ -603,7 +603,7 @@ HeaderComponent = tslib_1.__decorate([
|
|
|
603
603
|
|
|
604
604
|
<ng-template [ngIf]="isCheckboxColumn(column) && !column.headerTemplateRef && column.showSelectAll">
|
|
605
605
|
<input
|
|
606
|
-
class="k-checkbox"
|
|
606
|
+
class="k-checkbox k-checkbox-md k-rounded-md"
|
|
607
607
|
[attr.id]="selectAllCheckboxId()"
|
|
608
608
|
[attr.aria-label]="selectAllCheckboxLabel"
|
|
609
609
|
kendoGridSelectAllCheckbox
|
|
@@ -16,16 +16,16 @@ import { TemplateRef } from '@angular/core';
|
|
|
16
16
|
* selector: 'my-app',
|
|
17
17
|
* template: `
|
|
18
18
|
* <div class="example-config">
|
|
19
|
-
* <input type="radio" id="top" name="position"
|
|
19
|
+
* <input type="radio" id="top" name="position" value="top" checked (click)="positionChange($event)"/>
|
|
20
20
|
* <label class="k-radio-label" for="top">Top</label><br/>
|
|
21
|
-
* <input type="radio" id="bottom" name="position"
|
|
21
|
+
* <input type="radio" id="bottom" name="position" value="bottom" (click)="positionChange($event)"/>
|
|
22
22
|
* <label class="k-radio-label" for="bottom">Bottom</label><br/>
|
|
23
|
-
* <input type="radio" id="both" name="position" value="both"
|
|
23
|
+
* <input type="radio" id="both" name="position" value="both" (click)="positionChange($event)"/>
|
|
24
24
|
* <label class="k-radio-label" for="both">Both</label><br/>
|
|
25
25
|
* </div>
|
|
26
26
|
* <kendo-grid [data]="gridData" style="height: 200px">
|
|
27
27
|
* <ng-template kendoGridToolbarTemplate [position]="position" let-position="position">
|
|
28
|
-
* <button (click)="onClick()"
|
|
28
|
+
* <button (click)="onClick()">Custom action</button>
|
|
29
29
|
* </ng-template>
|
|
30
30
|
* <kendo-grid-column field="ProductName">
|
|
31
31
|
* </kendo-grid-column>
|
|
@@ -17,16 +17,16 @@ import { Directive, TemplateRef, Optional, Input } from '@angular/core';
|
|
|
17
17
|
* selector: 'my-app',
|
|
18
18
|
* template: `
|
|
19
19
|
* <div class="example-config">
|
|
20
|
-
* <input type="radio" id="top" name="position"
|
|
20
|
+
* <input type="radio" id="top" name="position" value="top" checked (click)="positionChange($event)"/>
|
|
21
21
|
* <label class="k-radio-label" for="top">Top</label><br/>
|
|
22
|
-
* <input type="radio" id="bottom" name="position"
|
|
22
|
+
* <input type="radio" id="bottom" name="position" value="bottom" (click)="positionChange($event)"/>
|
|
23
23
|
* <label class="k-radio-label" for="bottom">Bottom</label><br/>
|
|
24
|
-
* <input type="radio" id="both" name="position" value="both"
|
|
24
|
+
* <input type="radio" id="both" name="position" value="both" (click)="positionChange($event)"/>
|
|
25
25
|
* <label class="k-radio-label" for="both">Both</label><br/>
|
|
26
26
|
* </div>
|
|
27
27
|
* <kendo-grid [data]="gridData" style="height: 200px">
|
|
28
28
|
* <ng-template kendoGridToolbarTemplate [position]="position" let-position="position">
|
|
29
|
-
* <button (click)="onClick()"
|
|
29
|
+
* <button (click)="onClick()">Custom action</button>
|
|
30
30
|
* </ng-template>
|
|
31
31
|
* <kendo-grid-column field="ProductName">
|
|
32
32
|
* </kendo-grid-column>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* @hidden
|
|
7
|
+
*
|
|
8
|
+
* Quick look-up structure for combinations of keys.
|
|
9
|
+
* Similar to the native JS Set, however, working with a couple of keys instead of with a single key.
|
|
10
|
+
* Supports both primitive keys and object keys (compared by reference).
|
|
11
|
+
*/
|
|
12
|
+
export declare class PairSet {
|
|
13
|
+
/**
|
|
14
|
+
* Gets the total number of X/Y key pairs.
|
|
15
|
+
*/
|
|
16
|
+
readonly size: number;
|
|
17
|
+
/**
|
|
18
|
+
* Holds a set of Y keys for each defined X key.
|
|
19
|
+
* Each X key creates a map which holds a set of Y keys.
|
|
20
|
+
*
|
|
21
|
+
* Map { 1 => Set { 1, 2, 3 } } // pairs: [1, 1], [1, 2], [1, 3]
|
|
22
|
+
*/
|
|
23
|
+
private keysX;
|
|
24
|
+
/**
|
|
25
|
+
* Count the each added or deleted key manually to avoid iterating over all items when calling `this.size`.
|
|
26
|
+
*/
|
|
27
|
+
private totalKeysCount;
|
|
28
|
+
constructor(items?: any[], keyXField?: string, keyYField?: string);
|
|
29
|
+
/**
|
|
30
|
+
* Adds a couple of items identified as a combination.
|
|
31
|
+
*/
|
|
32
|
+
add(keyX: any, keyY: any): void;
|
|
33
|
+
/**
|
|
34
|
+
* Adds a combination of a couple of items identified together.
|
|
35
|
+
*/
|
|
36
|
+
delete(keyX: any, keyY: any): void;
|
|
37
|
+
/**
|
|
38
|
+
* Checks whether the defined combination is stored.
|
|
39
|
+
*/
|
|
40
|
+
has(keyX: any, keyY: any): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Clears all key combinations.
|
|
43
|
+
*/
|
|
44
|
+
clear(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Converts the persisted data structure to an array of objects,
|
|
47
|
+
* using the provided field names for the object props.
|
|
48
|
+
*/
|
|
49
|
+
toArray(keyXField: string, keyYField: string): any[];
|
|
50
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* @hidden
|
|
7
|
+
*
|
|
8
|
+
* Quick look-up structure for combinations of keys.
|
|
9
|
+
* Similar to the native JS Set, however, working with a couple of keys instead of with a single key.
|
|
10
|
+
* Supports both primitive keys and object keys (compared by reference).
|
|
11
|
+
*/
|
|
12
|
+
export class PairSet {
|
|
13
|
+
constructor(items, keyXField, keyYField) {
|
|
14
|
+
/**
|
|
15
|
+
* Holds a set of Y keys for each defined X key.
|
|
16
|
+
* Each X key creates a map which holds a set of Y keys.
|
|
17
|
+
*
|
|
18
|
+
* Map { 1 => Set { 1, 2, 3 } } // pairs: [1, 1], [1, 2], [1, 3]
|
|
19
|
+
*/
|
|
20
|
+
this.keysX = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Count the each added or deleted key manually to avoid iterating over all items when calling `this.size`.
|
|
23
|
+
*/
|
|
24
|
+
this.totalKeysCount = 0;
|
|
25
|
+
if (items && keyXField && keyYField) {
|
|
26
|
+
items.forEach(item => this.add(item[keyXField], item[keyYField]));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Gets the total number of X/Y key pairs.
|
|
31
|
+
*/
|
|
32
|
+
get size() {
|
|
33
|
+
return this.totalKeysCount;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Adds a couple of items identified as a combination.
|
|
37
|
+
*/
|
|
38
|
+
add(keyX, keyY) {
|
|
39
|
+
if (!this.keysX.has(keyX)) {
|
|
40
|
+
this.keysX.set(keyX, new Set());
|
|
41
|
+
}
|
|
42
|
+
if (!this.has(keyX, keyY)) {
|
|
43
|
+
this.keysX.get(keyX).add(keyY);
|
|
44
|
+
this.totalKeysCount += 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Adds a combination of a couple of items identified together.
|
|
49
|
+
*/
|
|
50
|
+
delete(keyX, keyY) {
|
|
51
|
+
if (this.has(keyX, keyY)) {
|
|
52
|
+
this.keysX.get(keyX).delete(keyY);
|
|
53
|
+
this.totalKeysCount -= 1;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Checks whether the defined combination is stored.
|
|
58
|
+
*/
|
|
59
|
+
has(keyX, keyY) {
|
|
60
|
+
return this.keysX.has(keyX) && this.keysX.get(keyX).has(keyY);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Clears all key combinations.
|
|
64
|
+
*/
|
|
65
|
+
clear() {
|
|
66
|
+
this.keysX.clear();
|
|
67
|
+
this.totalKeysCount = 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Converts the persisted data structure to an array of objects,
|
|
71
|
+
* using the provided field names for the object props.
|
|
72
|
+
*/
|
|
73
|
+
toArray(keyXField, keyYField) {
|
|
74
|
+
return Array.from(this.keysX).reduce((pairs, pair) => {
|
|
75
|
+
// Array.from(mapInstance) returns an array of arrays [[itemKey1, columnKeysSet1], [itemKey2, columnKeysSet2]]
|
|
76
|
+
const [keyX, keysY] = pair;
|
|
77
|
+
Array.from(keysY).forEach(keyY => pairs.push({ [keyXField]: keyX, [keyYField]: keyY }));
|
|
78
|
+
return pairs;
|
|
79
|
+
}, []);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { EventEmitter, ChangeDetectorRef } from '@angular/core';
|
|
5
|
+
import { EventEmitter, ChangeDetectorRef, SimpleChanges } from '@angular/core';
|
|
6
6
|
import { GridComponent } from "../grid.component";
|
|
7
7
|
import { Subscription } from "rxjs";
|
|
8
8
|
import { RowArgs } from "../rendering/common/row-args";
|
|
9
9
|
import { SelectionEvent, CellSelectionItem } from "./types";
|
|
10
10
|
import { ColumnComponent } from '../columns/column.component';
|
|
11
|
+
import { PairSet } from './pair-set';
|
|
11
12
|
/**
|
|
12
13
|
* @hidden
|
|
13
14
|
*/
|
|
@@ -33,8 +34,13 @@ export declare class Selection {
|
|
|
33
34
|
* Fires when the `selectedKeys` collection has been updated.
|
|
34
35
|
*/
|
|
35
36
|
selectedKeysChange: EventEmitter<any[]>;
|
|
37
|
+
protected rowSelectionState: Set<any>;
|
|
38
|
+
protected cellSelectionState: PairSet;
|
|
39
|
+
protected lastSelectionState: any[];
|
|
36
40
|
protected selectionChangeSubscription: Subscription;
|
|
41
|
+
private readonly isCellSelectionMode;
|
|
37
42
|
constructor(grid: GridComponent, cd: ChangeDetectorRef);
|
|
43
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
38
44
|
protected init(): void;
|
|
39
45
|
/**
|
|
40
46
|
* @hidden
|
|
@@ -47,5 +53,7 @@ export declare class Selection {
|
|
|
47
53
|
protected getItemKey(row: RowArgs): any;
|
|
48
54
|
protected getSelectionItem(row: RowArgs, col: ColumnComponent, colIndex: number): CellSelectionItem;
|
|
49
55
|
protected onSelectionChange(selection: SelectionEvent): void;
|
|
50
|
-
private
|
|
56
|
+
private notifyChange;
|
|
57
|
+
private setState;
|
|
58
|
+
private stateToArray;
|
|
51
59
|
}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as tslib_1 from "tslib";
|
|
6
|
-
/* tslint:disable:no-input-rename */
|
|
7
6
|
import { Input, EventEmitter, Output } from '@angular/core';
|
|
8
7
|
import { isPresent } from "../utils";
|
|
8
|
+
import { PairSet } from './pair-set';
|
|
9
9
|
/**
|
|
10
10
|
* @hidden
|
|
11
11
|
*/
|
|
@@ -21,19 +21,28 @@ export class Selection {
|
|
|
21
21
|
* Fires when the `selectedKeys` collection has been updated.
|
|
22
22
|
*/
|
|
23
23
|
this.selectedKeysChange = new EventEmitter();
|
|
24
|
+
this.rowSelectionState = new Set();
|
|
25
|
+
this.cellSelectionState = new PairSet();
|
|
24
26
|
this.init();
|
|
25
27
|
}
|
|
28
|
+
get isCellSelectionMode() {
|
|
29
|
+
return isPresent(this.grid.selectable) && this.grid.selectable['cell'];
|
|
30
|
+
}
|
|
31
|
+
ngOnChanges(changes) {
|
|
32
|
+
// skip reinitialization if the user data is the same as the last state change
|
|
33
|
+
if (isPresent(changes.selectedKeys) && this.lastSelectionState !== this.selectedKeys) {
|
|
34
|
+
this.setState(this.selectedKeys);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
26
37
|
init() {
|
|
27
38
|
if (!isPresent(this.grid.rowSelected)) {
|
|
28
|
-
this.grid.rowSelected = (row) =>
|
|
29
|
-
return this.selectedKeys.indexOf(this.getItemKey(row)) >= 0;
|
|
30
|
-
};
|
|
39
|
+
this.grid.rowSelected = (row) => this.rowSelectionState.has(this.getItemKey(row));
|
|
31
40
|
}
|
|
32
41
|
if (!isPresent(this.grid.cellSelected)) {
|
|
33
42
|
this.grid.cellSelected = (row, column, colIndex) => {
|
|
34
43
|
const contender = this.getSelectionItem(row, column, colIndex);
|
|
35
44
|
return {
|
|
36
|
-
selected: this.
|
|
45
|
+
selected: this.cellSelectionState.has(contender.itemKey, contender.columnKey),
|
|
37
46
|
item: contender
|
|
38
47
|
};
|
|
39
48
|
};
|
|
@@ -52,7 +61,8 @@ export class Selection {
|
|
|
52
61
|
* @hidden
|
|
53
62
|
*/
|
|
54
63
|
reset() {
|
|
55
|
-
this.
|
|
64
|
+
this.rowSelectionState.clear();
|
|
65
|
+
this.cellSelectionState.clear();
|
|
56
66
|
}
|
|
57
67
|
getItemKey(row) {
|
|
58
68
|
if (this.selectionKey) {
|
|
@@ -88,43 +98,47 @@ export class Selection {
|
|
|
88
98
|
if (selection.selectedRows) {
|
|
89
99
|
selection.deselectedRows.forEach((item) => {
|
|
90
100
|
const itemKey = this.getItemKey(item);
|
|
91
|
-
|
|
92
|
-
if (itemIndex >= 0) {
|
|
93
|
-
this.selectedKeys.splice(itemIndex, 1);
|
|
94
|
-
}
|
|
101
|
+
this.rowSelectionState.delete(itemKey);
|
|
95
102
|
});
|
|
96
|
-
if (this.grid.selectableSettings.mode === "single" && this.
|
|
103
|
+
if (this.grid.selectableSettings.mode === "single" && this.rowSelectionState.size > 0) {
|
|
97
104
|
this.reset();
|
|
98
105
|
}
|
|
99
106
|
selection.selectedRows.forEach((item) => {
|
|
100
107
|
const itemKey = this.getItemKey(item);
|
|
101
|
-
|
|
102
|
-
this.selectedKeys.push(itemKey);
|
|
103
|
-
}
|
|
108
|
+
this.rowSelectionState.add(itemKey);
|
|
104
109
|
});
|
|
105
110
|
}
|
|
106
111
|
else {
|
|
107
|
-
selection.deselectedCells.forEach((
|
|
108
|
-
|
|
109
|
-
if (itemIndex >= 0) {
|
|
110
|
-
this.selectedKeys.splice(itemIndex, 1);
|
|
111
|
-
}
|
|
112
|
+
selection.deselectedCells.forEach(({ itemKey, columnKey }) => {
|
|
113
|
+
this.cellSelectionState.delete(itemKey, columnKey);
|
|
112
114
|
});
|
|
113
|
-
if (this.grid.selectableSettings.mode === "single" && this.
|
|
115
|
+
if (this.grid.selectableSettings.mode === "single" && this.cellSelectionState.size > 0) {
|
|
114
116
|
this.reset();
|
|
115
117
|
}
|
|
116
|
-
selection.selectedCells.forEach((
|
|
117
|
-
|
|
118
|
-
if (itemIndex < 0) {
|
|
119
|
-
this.selectedKeys.push(item);
|
|
120
|
-
}
|
|
118
|
+
selection.selectedCells.forEach(({ itemKey, columnKey }) => {
|
|
119
|
+
this.cellSelectionState.add(itemKey, columnKey);
|
|
121
120
|
});
|
|
122
121
|
}
|
|
123
122
|
this.cd.markForCheck();
|
|
124
|
-
this.
|
|
123
|
+
this.notifyChange();
|
|
124
|
+
}
|
|
125
|
+
notifyChange() {
|
|
126
|
+
this.lastSelectionState = this.stateToArray();
|
|
127
|
+
this.selectedKeysChange.emit(this.lastSelectionState);
|
|
128
|
+
}
|
|
129
|
+
setState(selectedKeys) {
|
|
130
|
+
this.reset();
|
|
131
|
+
if (this.isCellSelectionMode) {
|
|
132
|
+
this.cellSelectionState = new PairSet(selectedKeys, 'itemKey', 'columnKey');
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.rowSelectionState = new Set(selectedKeys);
|
|
136
|
+
}
|
|
125
137
|
}
|
|
126
|
-
|
|
127
|
-
return this.
|
|
138
|
+
stateToArray() {
|
|
139
|
+
return this.isCellSelectionMode ?
|
|
140
|
+
this.cellSelectionState.toArray('itemKey', 'columnKey') :
|
|
141
|
+
Array.from(this.rowSelectionState);
|
|
128
142
|
}
|
|
129
143
|
}
|
|
130
144
|
tslib_1.__decorate([
|
package/dist/es2015/utils.d.ts
CHANGED
|
@@ -36,11 +36,11 @@ export declare const isUniversal: () => boolean;
|
|
|
36
36
|
/**
|
|
37
37
|
* @hidden
|
|
38
38
|
*/
|
|
39
|
-
export declare const isString: (value: any) =>
|
|
39
|
+
export declare const isString: (value: any) => value is string;
|
|
40
40
|
/**
|
|
41
41
|
* @hidden
|
|
42
42
|
*/
|
|
43
|
-
export declare const isNumber: (value: any) =>
|
|
43
|
+
export declare const isNumber: (value: any) => value is number;
|
|
44
44
|
/**
|
|
45
45
|
* @hidden
|
|
46
46
|
*/
|