UNPKG

6.68 kBPlain TextView Raw
1
2import {AgCheckbox} from "../../widgets/agCheckbox";
3import {BeanStub} from "../../context/beanStub";
4import {PostConstruct, Autowired} from "../../context/context";
5import {ColumnApi} from "../../columnController/columnApi";
6import {GridApi} from "../../gridApi";
7import {Events} from "../../events";
8import {EventService} from "../../eventService";
9import {IRowModel} from "../../interfaces/iRowModel";
10import {Constants} from "../../constants";
11import {Column} from "../../entities/column";
12import {RowNode} from "../../entities/rowNode";
13import {SelectionController} from "../../selectionController";
14import {GridOptionsWrapper} from "../../gridOptionsWrapper";
15
16export class SelectAllFeature extends BeanStub {
17
18 @Autowired('gridApi') private gridApi: GridApi;
19 @Autowired('columnApi') private columnApi: ColumnApi;
20 @Autowired('eventService') private eventService: EventService;
21 @Autowired('rowModel') private rowModel: IRowModel;
22 @Autowired('selectionController') private selectionController: SelectionController;
23 @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
24
25 private cbSelectAllVisible = false;
26 private processingEventFromCheckbox = false;
27 private column: Column;
28
29 private filteredOnly: boolean;
30 private cbSelectAll: AgCheckbox;
31
32 constructor(cbSelectAll: AgCheckbox, column: Column) {
33 super();
34 this.cbSelectAll = cbSelectAll;
35 this.column = column;
36
37 let colDef = column.getColDef();
38 this.filteredOnly = colDef ? !!colDef.headerCheckboxSelectionFilteredOnly : false;
39 }
40
41 @PostConstruct
42 private postConstruct(): void {
43
44 this.showOrHideSelectAll();
45
46 this.addDestroyableEventListener(this.eventService, Events.EVENT_DISPLAYED_COLUMNS_CHANGED, this.showOrHideSelectAll.bind(this));
47
48 this.addDestroyableEventListener(this.eventService, Events.EVENT_SELECTION_CHANGED, this.onSelectionChanged.bind(this));
49 this.addDestroyableEventListener(this.eventService, Events.EVENT_MODEL_UPDATED, this.onModelChanged.bind(this));
50
51 this.addDestroyableEventListener(this.cbSelectAll, AgCheckbox.EVENT_CHANGED, this.onCbSelectAll.bind(this));
52 }
53
54 private showOrHideSelectAll(): void {
55
56 this.cbSelectAllVisible = this.isCheckboxSelection();
57 this.cbSelectAll.setVisible(this.cbSelectAllVisible);
58
59 if (this.cbSelectAllVisible) {
60 // in case user is trying this feature with the wrong model type
61 this.checkRightRowModelType();
62 // make sure checkbox is showing the right state
63 this.updateStateOfCheckbox();
64 }
65 }
66
67 private onModelChanged(): void {
68 if (!this.cbSelectAllVisible) { return; }
69 this.updateStateOfCheckbox();
70 }
71
72 private onSelectionChanged(): void {
73 if (!this.cbSelectAllVisible) { return; }
74 this.updateStateOfCheckbox();
75 }
76
77 private getNextCheckboxState(selectionCount: SelectionCount): boolean {
78 if (selectionCount.selected===0 && selectionCount.notSelected===0) {
79 // if no rows, always have it unselected
80 return false;
81 } else if (selectionCount.selected>0 && selectionCount.notSelected>0) {
82 // if mix of selected and unselected, this is the tri-state
83 return null;
84 } else if (selectionCount.selected>0) {
85 // only selected
86 return true;
87 } else {
88 // nothing selected
89 return false;
90 }
91 }
92
93 private updateStateOfCheckbox(): void {
94
95 if (this.processingEventFromCheckbox) { return; }
96
97 this.processingEventFromCheckbox = true;
98
99 let selectionCount = this.getSelectionCount();
100
101 let allSelected = this.getNextCheckboxState(selectionCount);
102
103 this.cbSelectAll.setSelected(allSelected);
104
105 this.processingEventFromCheckbox = false;
106 }
107
108 private getSelectionCount(): SelectionCount {
109 let selectedCount = 0;
110 let notSelectedCount = 0;
111
112 let callback = (node: RowNode) => {
113 if (node.isSelected()) {
114 selectedCount++;
115 } else if (!node.selectable) {
116 // don't count non-selectable nodes!
117 } else {
118 notSelectedCount++;
119 }
120 };
121
122 if (this.filteredOnly) {
123 this.gridApi.forEachNodeAfterFilter(callback);
124 } else {
125 this.gridApi.forEachNode(callback);
126 }
127
128 return {
129 notSelected: notSelectedCount,
130 selected: selectedCount
131 };
132 }
133
134 private checkRightRowModelType(): void {
135 let rowModelType = this.rowModel.getType();
136 let rowModelMatches = rowModelType===Constants.ROW_MODEL_TYPE_CLIENT_SIDE;
137 if (!rowModelMatches) {
138 console.log(`ag-Grid: selectAllCheckbox is only available if using normal row model, you are using ${rowModelType}`);
139 }
140 }
141
142 private onCbSelectAll(): void {
143 if (this.processingEventFromCheckbox) { return; }
144 if (!this.cbSelectAllVisible) { return; }
145
146 let value = this.cbSelectAll.isSelected();
147 if (value) {
148 this.selectionController.selectAllRowNodes(this.filteredOnly);
149 } else {
150 this.selectionController.deselectAllRowNodes(this.filteredOnly);
151 }
152 }
153
154 private isCheckboxSelection(): boolean {
155 let result = this.column.getColDef().headerCheckboxSelection;
156
157 if (typeof result === 'function') {
158 let func = <(params: any)=>boolean> result;
159 result = func({
160 column: this.column,
161 colDef: this.column.getColDef(),
162 columnApi: this.columnApi,
163 api: this.gridApi
164 });
165 }
166
167 if (result) {
168 if (this.gridOptionsWrapper.isRowModelServerSide()) {
169 console.warn('headerCheckboxSelection is not supported for Server Side Row Model');
170 return false;
171 }
172 if (this.gridOptionsWrapper.isRowModelInfinite()) {
173 console.warn('headerCheckboxSelection is not supported for Infinite Row Model');
174 return false;
175 }
176 if (this.gridOptionsWrapper.isRowModelViewport()) {
177 console.warn('headerCheckboxSelection is not supported for Viewport Row Model');
178 return false;
179 }
180 // otherwise the row model is compatible, so return true
181 return true;
182 } else {
183 return false;
184 }
185 }
186
187}
188
189interface SelectionCount {
190 selected: number;
191 notSelected: number;
192}
\No newline at end of file