1 | import {EventService} from "../eventService";
|
2 | import {
|
3 | AgEvent, Events, RowDataChangedEvent, RowEvent, RowGroupOpenedEvent, RowSelectedEvent,
|
4 | SelectionChangedEvent
|
5 | } from "../events";
|
6 | import {GridOptionsWrapper} from "../gridOptionsWrapper";
|
7 | import {SelectionController} from "../selectionController";
|
8 | import {ColDef} from "./colDef";
|
9 | import {Column} from "./column";
|
10 | import {ValueService} from "../valueService/valueService";
|
11 | import {ColumnController} from "../columnController/columnController";
|
12 | import {ColumnApi} from "../columnController/columnApi";
|
13 | import {Autowired, Context} from "../context/context";
|
14 | import {IRowModel} from "../interfaces/iRowModel";
|
15 | import {Constants} from "../constants";
|
16 | import {Utils as _} from "../utils";
|
17 | import {ClientSideRowModel} from "../rowModels/clientSide/clientSideRowModel";
|
18 | import {RowNodeCache, RowNodeCacheParams} from "../rowModels/cache/rowNodeCache";
|
19 | import {RowNodeBlock} from "../rowModels/cache/rowNodeBlock";
|
20 | import {IEventEmitter} from "../interfaces/iEventEmitter";
|
21 | import {ValueCache} from "../valueService/valueCache";
|
22 | import {DetailGridInfo, GridApi} from "../gridApi";
|
23 |
|
24 | export interface SetSelectedParams {
|
25 |
|
26 | newValue: boolean;
|
27 |
|
28 | clearSelection?: boolean;
|
29 |
|
30 | suppressFinishActions?: boolean;
|
31 |
|
32 | rangeSelect?: boolean;
|
33 |
|
34 | groupSelectsFiltered?: boolean;
|
35 | }
|
36 |
|
37 | export interface RowNodeEvent extends AgEvent {
|
38 | node: RowNode;
|
39 | }
|
40 |
|
41 | export interface DataChangedEvent extends RowNodeEvent {
|
42 | oldData: any;
|
43 | newData: any;
|
44 | update: boolean;
|
45 | }
|
46 |
|
47 | export interface CellChangedEvent extends RowNodeEvent {
|
48 | column: Column;
|
49 | newValue: any;
|
50 | }
|
51 |
|
52 | export class RowNode implements IEventEmitter {
|
53 |
|
54 | public static EVENT_ROW_SELECTED = 'rowSelected';
|
55 | public static EVENT_DATA_CHANGED = 'dataChanged';
|
56 | public static EVENT_CELL_CHANGED = 'cellChanged';
|
57 | public static EVENT_ALL_CHILDREN_COUNT_CHANGED = 'allChildrenCountChanged';
|
58 | public static EVENT_MOUSE_ENTER = 'mouseEnter';
|
59 | public static EVENT_MOUSE_LEAVE = 'mouseLeave';
|
60 | public static EVENT_HEIGHT_CHANGED = 'heightChanged';
|
61 | public static EVENT_TOP_CHANGED = 'topChanged';
|
62 | public static EVENT_FIRST_CHILD_CHANGED = 'firstChildChanged';
|
63 | public static EVENT_LAST_CHILD_CHANGED = 'lastChildChanged';
|
64 | public static EVENT_CHILD_INDEX_CHANGED = 'childIndexChanged';
|
65 | public static EVENT_ROW_INDEX_CHANGED = 'rowIndexChanged';
|
66 | public static EVENT_EXPANDED_CHANGED = 'expandedChanged';
|
67 | public static EVENT_SELECTABLE_CHANGED = 'selectableChanged';
|
68 | public static EVENT_UI_LEVEL_CHANGED = 'uiLevelChanged';
|
69 | public static EVENT_DRAGGING_CHANGED = 'draggingChanged';
|
70 |
|
71 | @Autowired('eventService') private mainEventService: EventService;
|
72 | @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
|
73 | @Autowired('selectionController') private selectionController: SelectionController;
|
74 | @Autowired('columnController') private columnController: ColumnController;
|
75 | @Autowired('valueService') private valueService: ValueService;
|
76 | @Autowired('rowModel') private rowModel: IRowModel;
|
77 | @Autowired('context') private context: Context;
|
78 | @Autowired('valueCache') private valueCache: ValueCache;
|
79 | @Autowired('columnApi') private columnApi: ColumnApi;
|
80 | @Autowired('gridApi') private gridApi: GridApi;
|
81 |
|
82 | |
83 |
|
84 | public id: string;
|
85 |
|
86 | public groupData: any;
|
87 |
|
88 | public aggData: any;
|
89 |
|
90 | public data: any;
|
91 |
|
92 | public parent: RowNode;
|
93 |
|
94 | public level: number;
|
95 |
|
96 | public uiLevel: number;
|
97 | |
98 |
|
99 | public rowGroupIndex: number;
|
100 |
|
101 | public group: boolean;
|
102 |
|
103 | public dragging: boolean;
|
104 |
|
105 |
|
106 | public master: boolean;
|
107 |
|
108 | public detail: boolean;
|
109 |
|
110 | public detailNode: RowNode;
|
111 |
|
112 | public detailGridInfo: DetailGridInfo;
|
113 |
|
114 |
|
115 | public canFlower: boolean;
|
116 |
|
117 | public flower: boolean;
|
118 |
|
119 | public childFlower: RowNode;
|
120 |
|
121 |
|
122 | public leafGroup: boolean;
|
123 |
|
124 | public firstChild: boolean;
|
125 |
|
126 | public lastChild: boolean;
|
127 |
|
128 | public childIndex: number;
|
129 |
|
130 | public rowIndex: number;
|
131 |
|
132 | public rowPinned: string;
|
133 |
|
134 | public quickFilterAggregateText: string;
|
135 |
|
136 | public footer: boolean;
|
137 |
|
138 | public field: string;
|
139 |
|
140 | public rowGroupColumn: Column;
|
141 |
|
142 | public key: any;
|
143 |
|
144 | public stub: boolean;
|
145 |
|
146 |
|
147 | public allLeafChildren: RowNode[];
|
148 |
|
149 |
|
150 | public childrenAfterGroup: RowNode[];
|
151 |
|
152 | public childrenAfterFilter: RowNode[];
|
153 |
|
154 | public childrenAfterSort: RowNode[];
|
155 |
|
156 | public allChildrenCount: number;
|
157 |
|
158 |
|
159 | public childrenMapped: {[key: string]: any} = {};
|
160 |
|
161 |
|
162 | public childrenCache: RowNodeCache<RowNodeBlock,RowNodeCacheParams>;
|
163 |
|
164 |
|
165 | public expanded: boolean;
|
166 |
|
167 | public sibling: RowNode;
|
168 |
|
169 |
|
170 | public rowHeight: number;
|
171 |
|
172 | public rowTop: number;
|
173 | |
174 |
|
175 | public oldRowTop: number;
|
176 | |
177 |
|
178 |
|
179 |
|
180 | public daemon: boolean;
|
181 |
|
182 |
|
183 | public selectable = true;
|
184 |
|
185 |
|
186 | public __cacheData: {[colId: string]: any};
|
187 | public __cacheVersion: number;
|
188 |
|
189 | private selected = false;
|
190 | private eventService: EventService;
|
191 |
|
192 | public setData(data: any): void {
|
193 | let oldData = this.data;
|
194 | this.data = data;
|
195 |
|
196 | this.valueCache.onDataChanged();
|
197 |
|
198 | this.updateDataOnDetailNode();
|
199 |
|
200 | this.checkRowSelectable();
|
201 |
|
202 | let event: DataChangedEvent = this.createDataChangedEvent(data, oldData, false);
|
203 | this.dispatchLocalEvent(event);
|
204 | }
|
205 |
|
206 |
|
207 |
|
208 |
|
209 | private updateDataOnDetailNode(): void {
|
210 | if (this.detailNode) {
|
211 | this.detailNode.data = this.data;
|
212 | }
|
213 | }
|
214 |
|
215 | private createDataChangedEvent(newData: any, oldData: any, update: boolean): DataChangedEvent {
|
216 | return {
|
217 | type: RowNode.EVENT_DATA_CHANGED,
|
218 | node: this,
|
219 | oldData: oldData,
|
220 | newData: newData,
|
221 | update: update
|
222 | };
|
223 | }
|
224 |
|
225 | private createLocalRowEvent(type: string): RowNodeEvent {
|
226 | return {
|
227 | type: type,
|
228 | node: this
|
229 | };
|
230 | }
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 | public updateData(data: any): void {
|
238 | let oldData = this.data;
|
239 | this.data = data;
|
240 |
|
241 | this.updateDataOnDetailNode();
|
242 |
|
243 | this.checkRowSelectable();
|
244 |
|
245 | this.updateDataOnDetailNode();
|
246 |
|
247 | let event: DataChangedEvent = this.createDataChangedEvent(data, oldData, true);
|
248 | this.dispatchLocalEvent(event);
|
249 | }
|
250 |
|
251 | public getRowIndexString(): string {
|
252 | if (this.rowPinned===Constants.PINNED_TOP) {
|
253 | return 't-' + this.rowIndex;
|
254 | } else if (this.rowPinned===Constants.PINNED_BOTTOM) {
|
255 | return 'b-' + this.rowIndex;
|
256 | } else {
|
257 | return this.rowIndex.toString();
|
258 | }
|
259 | }
|
260 |
|
261 | private createDaemonNode(): RowNode {
|
262 | let oldNode = new RowNode();
|
263 | this.context.wireBean(oldNode);
|
264 |
|
265 |
|
266 |
|
267 | oldNode.id = this.id;
|
268 | oldNode.data = this.data;
|
269 | oldNode.daemon = true;
|
270 | oldNode.selected = this.selected;
|
271 | oldNode.level = this.level;
|
272 | return oldNode;
|
273 | }
|
274 |
|
275 | public setDataAndId(data: any, id: string): void {
|
276 | let oldNode = _.exists(this.id) ? this.createDaemonNode() : null;
|
277 |
|
278 | let oldData = this.data;
|
279 | this.data = data;
|
280 | this.updateDataOnDetailNode();
|
281 |
|
282 | this.setId(id);
|
283 |
|
284 | this.selectionController.syncInRowNode(this, oldNode);
|
285 |
|
286 | this.checkRowSelectable();
|
287 |
|
288 | let event: DataChangedEvent = this.createDataChangedEvent(data, oldData, false);
|
289 | this.dispatchLocalEvent(event);
|
290 | }
|
291 |
|
292 | private checkRowSelectable() {
|
293 | let isRowSelectableFunc = this.gridOptionsWrapper.getIsRowSelectableFunc();
|
294 | let shouldInvokeIsRowSelectable = isRowSelectableFunc && _.exists(this);
|
295 | this.setRowSelectable(shouldInvokeIsRowSelectable ? isRowSelectableFunc(this) : true)
|
296 | }
|
297 |
|
298 | public setRowSelectable(newVal: boolean) {
|
299 | if (this.selectable !== newVal) {
|
300 | this.selectable = newVal;
|
301 | if (this.eventService) {
|
302 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_SELECTABLE_CHANGED));
|
303 | }
|
304 | }
|
305 | }
|
306 |
|
307 | public setId(id: string): void {
|
308 |
|
309 | let getRowNodeId = this.gridOptionsWrapper.getRowNodeIdFunc();
|
310 | if (getRowNodeId) {
|
311 |
|
312 |
|
313 | if (this.data) {
|
314 | this.id = getRowNodeId(this.data);
|
315 | } else {
|
316 |
|
317 |
|
318 |
|
319 | this.id = undefined;
|
320 | }
|
321 | } else {
|
322 | this.id = id;
|
323 | }
|
324 | }
|
325 |
|
326 | public isPixelInRange(pixel: number): boolean {
|
327 | return pixel >= this.rowTop && pixel < (this.rowTop + this.rowHeight);
|
328 | }
|
329 |
|
330 | public clearRowTop(): void {
|
331 | this.oldRowTop = this.rowTop;
|
332 | this.setRowTop(null);
|
333 | }
|
334 |
|
335 | public setFirstChild(firstChild: boolean): void {
|
336 | if (this.firstChild === firstChild) { return; }
|
337 | this.firstChild = firstChild;
|
338 | if (this.eventService) {
|
339 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_FIRST_CHILD_CHANGED));
|
340 | }
|
341 | }
|
342 |
|
343 | public setLastChild(lastChild: boolean): void {
|
344 | if (this.lastChild === lastChild) { return; }
|
345 | this.lastChild = lastChild;
|
346 | if (this.eventService) {
|
347 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_LAST_CHILD_CHANGED));
|
348 | }
|
349 | }
|
350 |
|
351 | public setChildIndex(childIndex: number): void {
|
352 | if (this.childIndex === childIndex) { return; }
|
353 | this.childIndex = childIndex;
|
354 | if (this.eventService) {
|
355 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_CHILD_INDEX_CHANGED));
|
356 | }
|
357 | }
|
358 |
|
359 | public setRowTop(rowTop: number): void {
|
360 | if (this.rowTop === rowTop) { return; }
|
361 | this.rowTop = rowTop;
|
362 | if (this.eventService) {
|
363 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_TOP_CHANGED));
|
364 | }
|
365 | }
|
366 |
|
367 | public setDragging(dragging: boolean): void {
|
368 | if (this.dragging === dragging) { return; }
|
369 | this.dragging = dragging;
|
370 | if (this.eventService) {
|
371 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_DRAGGING_CHANGED));
|
372 | }
|
373 | }
|
374 |
|
375 | public setAllChildrenCount(allChildrenCount: number): void {
|
376 | if (this.allChildrenCount === allChildrenCount) { return; }
|
377 | this.allChildrenCount = allChildrenCount;
|
378 | if (this.eventService) {
|
379 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_ALL_CHILDREN_COUNT_CHANGED));
|
380 | }
|
381 | }
|
382 |
|
383 | public setRowHeight(rowHeight: number): void {
|
384 | this.rowHeight = rowHeight;
|
385 | if (this.eventService) {
|
386 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_HEIGHT_CHANGED));
|
387 | }
|
388 | }
|
389 |
|
390 | public setRowIndex(rowIndex: number): void {
|
391 | this.rowIndex = rowIndex;
|
392 | if (this.eventService) {
|
393 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_ROW_INDEX_CHANGED));
|
394 | }
|
395 | }
|
396 |
|
397 | public setUiLevel(uiLevel: number): void {
|
398 | if (this.uiLevel === uiLevel) { return; }
|
399 |
|
400 | this.uiLevel = uiLevel;
|
401 | if (this.eventService) {
|
402 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_UI_LEVEL_CHANGED));
|
403 | }
|
404 | }
|
405 |
|
406 | public setExpanded(expanded: boolean): void {
|
407 | if (this.expanded === expanded) { return; }
|
408 |
|
409 | this.expanded = expanded;
|
410 | if (this.eventService) {
|
411 | this.eventService.dispatchEvent(this.createLocalRowEvent(RowNode.EVENT_EXPANDED_CHANGED));
|
412 | }
|
413 |
|
414 | let event: RowGroupOpenedEvent = this.createGlobalRowEvent(Events.EVENT_ROW_GROUP_OPENED);
|
415 | this.mainEventService.dispatchEvent(event);
|
416 |
|
417 | if (this.gridOptionsWrapper.isGroupIncludeFooter()) {
|
418 | this.gridApi.redrawRows({rowNodes: [this]});
|
419 | }
|
420 | }
|
421 |
|
422 | private createGlobalRowEvent(type: string): RowEvent {
|
423 | let event: RowGroupOpenedEvent = {
|
424 | type: type,
|
425 | node: this,
|
426 | data: this.data,
|
427 | rowIndex: this.rowIndex,
|
428 | rowPinned: this.rowPinned,
|
429 | context: this.gridOptionsWrapper.getContext(),
|
430 | api: this.gridOptionsWrapper.getApi(),
|
431 | columnApi: this.gridOptionsWrapper.getColumnApi()
|
432 | };
|
433 | return event;
|
434 | }
|
435 |
|
436 | private dispatchLocalEvent(event: AgEvent): void {
|
437 | if (this.eventService) {
|
438 | this.eventService.dispatchEvent(event);
|
439 | }
|
440 | }
|
441 |
|
442 |
|
443 |
|
444 |
|
445 |
|
446 |
|
447 | public setDataValue(colKey: string|Column, newValue: any): void {
|
448 | let column = this.columnController.getPrimaryColumn(colKey);
|
449 | this.valueService.setValue(this, column, newValue);
|
450 | this.dispatchCellChangedEvent(column, newValue);
|
451 | }
|
452 |
|
453 | public setGroupValue(colKey: string|Column, newValue: any): void {
|
454 | let column = this.columnController.getGridColumn(colKey);
|
455 |
|
456 | if (_.missing(this.groupData)) {
|
457 | this.groupData = {};
|
458 | }
|
459 |
|
460 | this.groupData[column.getColId()] = newValue;
|
461 | this.dispatchCellChangedEvent(column, newValue);
|
462 | }
|
463 |
|
464 |
|
465 | public setAggData(newAggData: any): void {
|
466 |
|
467 |
|
468 | let colIds = _.getAllKeysInObjects([this.aggData, newAggData]);
|
469 |
|
470 | this.aggData = newAggData;
|
471 |
|
472 |
|
473 | if (this.eventService) {
|
474 | colIds.forEach( colId => {
|
475 | let column = this.columnController.getGridColumn(colId);
|
476 | let value = this.aggData ? this.aggData[colId] : undefined;
|
477 | this.dispatchCellChangedEvent(column, value);
|
478 | });
|
479 | }
|
480 | }
|
481 |
|
482 | public hasChildren(): boolean {
|
483 |
|
484 |
|
485 |
|
486 | return this.group || (this.childrenAfterGroup && this.childrenAfterGroup.length > 0);
|
487 | }
|
488 |
|
489 | public isEmptyFillerNode(): boolean {
|
490 | return this.group && _.missingOrEmpty(this.childrenAfterGroup);
|
491 | }
|
492 |
|
493 | private dispatchCellChangedEvent(column: Column, newValue: any): void {
|
494 | let cellChangedEvent: CellChangedEvent = {
|
495 | type: RowNode.EVENT_CELL_CHANGED,
|
496 | node: this,
|
497 | column: column,
|
498 | newValue: newValue
|
499 | };
|
500 | this.dispatchLocalEvent(cellChangedEvent);
|
501 | }
|
502 |
|
503 | public resetQuickFilterAggregateText(): void {
|
504 | this.quickFilterAggregateText = null;
|
505 | }
|
506 |
|
507 | public isExpandable(): boolean {
|
508 | return this.hasChildren() || this.master;
|
509 | }
|
510 |
|
511 | public isSelected(): boolean {
|
512 |
|
513 | if (this.footer) {
|
514 | return this.sibling.isSelected();
|
515 | }
|
516 |
|
517 | return this.selected;
|
518 | }
|
519 |
|
520 | public depthFirstSearch( callback: (rowNode: RowNode) => void ): void {
|
521 | if (this.childrenAfterGroup) {
|
522 | this.childrenAfterGroup.forEach( child => child.depthFirstSearch(callback) );
|
523 | }
|
524 | callback(this);
|
525 | }
|
526 |
|
527 |
|
528 |
|
529 | public calculateSelectedFromChildren(): void {
|
530 | let atLeastOneSelected = false;
|
531 | let atLeastOneDeSelected = false;
|
532 | let atLeastOneMixed = false;
|
533 |
|
534 | let newSelectedValue: boolean;
|
535 | if (this.childrenAfterGroup) {
|
536 | for (let i = 0; i < this.childrenAfterGroup.length; i++) {
|
537 | let child = this.childrenAfterGroup[i];
|
538 |
|
539 |
|
540 | if (!child.selectable) continue;
|
541 |
|
542 | let childState = child.isSelected();
|
543 | switch (childState) {
|
544 | case true:
|
545 | atLeastOneSelected = true;
|
546 | break;
|
547 | case false:
|
548 | atLeastOneDeSelected = true;
|
549 | break;
|
550 | default:
|
551 | atLeastOneMixed = true;
|
552 | break;
|
553 | }
|
554 | }
|
555 | }
|
556 |
|
557 | if (atLeastOneMixed) {
|
558 | newSelectedValue = undefined;
|
559 | } else if (atLeastOneSelected && !atLeastOneDeSelected) {
|
560 | newSelectedValue = true;
|
561 | } else if (!atLeastOneSelected && atLeastOneDeSelected) {
|
562 | newSelectedValue = false;
|
563 | } else {
|
564 | newSelectedValue = undefined;
|
565 | }
|
566 | this.selectThisNode(newSelectedValue);
|
567 | }
|
568 |
|
569 | public setSelectedInitialValue(selected: boolean): void {
|
570 | this.selected = selected;
|
571 | }
|
572 |
|
573 | public setSelected(newValue: boolean, clearSelection: boolean = false, suppressFinishActions: boolean = false) {
|
574 | this.setSelectedParams({
|
575 | newValue: newValue,
|
576 | clearSelection: clearSelection,
|
577 | suppressFinishActions: suppressFinishActions,
|
578 | rangeSelect: false
|
579 | });
|
580 | }
|
581 |
|
582 | public isRowPinned(): boolean {
|
583 | return this.rowPinned === Constants.PINNED_TOP || this.rowPinned === Constants.PINNED_BOTTOM;
|
584 | }
|
585 |
|
586 |
|
587 | public setSelectedParams(params: SetSelectedParams): number {
|
588 |
|
589 | let groupSelectsChildren = this.gridOptionsWrapper.isGroupSelectsChildren();
|
590 |
|
591 | let newValue = params.newValue === true;
|
592 | let clearSelection = params.clearSelection === true;
|
593 | let suppressFinishActions = params.suppressFinishActions === true;
|
594 | let rangeSelect = params.rangeSelect === true;
|
595 |
|
596 | let groupSelectsFiltered = groupSelectsChildren && (params.groupSelectsFiltered === true);
|
597 |
|
598 | if (this.id===undefined) {
|
599 | console.warn('ag-Grid: cannot select node until id for node is known');
|
600 | return 0;
|
601 | }
|
602 |
|
603 | if (this.rowPinned) {
|
604 | console.log('ag-Grid: cannot select pinned rows');
|
605 | return 0;
|
606 | }
|
607 |
|
608 |
|
609 |
|
610 | if (this.footer) {
|
611 | let count = this.sibling.setSelectedParams(params);
|
612 | return count;
|
613 | }
|
614 |
|
615 | if (rangeSelect) {
|
616 | let newRowClicked = this.selectionController.getLastSelectedNode() !== this;
|
617 | let allowMultiSelect = this.gridOptionsWrapper.isRowSelectionMulti();
|
618 | if (newRowClicked && allowMultiSelect) {
|
619 | return this.doRowRangeSelection();
|
620 | }
|
621 | }
|
622 |
|
623 | let updatedCount = 0;
|
624 |
|
625 |
|
626 |
|
627 |
|
628 |
|
629 | let skipThisNode = groupSelectsFiltered && this.group;
|
630 | if (!skipThisNode) {
|
631 | let thisNodeWasSelected = this.selectThisNode(newValue);
|
632 | if (thisNodeWasSelected) { updatedCount++; }
|
633 | }
|
634 |
|
635 | if (groupSelectsChildren && this.group) {
|
636 | updatedCount += this.selectChildNodes(newValue, groupSelectsFiltered);
|
637 | }
|
638 |
|
639 |
|
640 | if (!suppressFinishActions) {
|
641 |
|
642 | let clearOtherNodes = newValue && (clearSelection || !this.gridOptionsWrapper.isRowSelectionMulti());
|
643 | if (clearOtherNodes) {
|
644 | updatedCount += this.selectionController.clearOtherNodes(this);
|
645 | }
|
646 |
|
647 |
|
648 | if (updatedCount>0) {
|
649 |
|
650 | this.selectionController.updateGroupsFromChildrenSelections();
|
651 |
|
652 |
|
653 |
|
654 | let event: SelectionChangedEvent = {
|
655 | type: Events.EVENT_SELECTION_CHANGED,
|
656 | api: this.gridApi,
|
657 | columnApi: this.columnApi
|
658 | };
|
659 | this.mainEventService.dispatchEvent(event);
|
660 | }
|
661 |
|
662 |
|
663 | if (newValue) {
|
664 | this.selectionController.setLastSelectedNode(this);
|
665 | }
|
666 | }
|
667 |
|
668 | return updatedCount;
|
669 | }
|
670 |
|
671 |
|
672 |
|
673 |
|
674 | private doRowRangeSelection(): number {
|
675 | let updatedCount = 0;
|
676 |
|
677 | let groupsSelectChildren = this.gridOptionsWrapper.isGroupSelectsChildren();
|
678 | let lastSelectedNode = this.selectionController.getLastSelectedNode();
|
679 |
|
680 | let nodesToSelect = this.rowModel.getNodesInRangeForSelection(this, lastSelectedNode);
|
681 |
|
682 | nodesToSelect.forEach( rowNode => {
|
683 | if (rowNode.group && groupsSelectChildren) { return; }
|
684 |
|
685 | let nodeWasSelected = rowNode.selectThisNode(true);
|
686 | if (nodeWasSelected) {
|
687 | updatedCount++;
|
688 | }
|
689 | });
|
690 |
|
691 | this.selectionController.updateGroupsFromChildrenSelections();
|
692 |
|
693 | let event: SelectionChangedEvent = {
|
694 | type: Events.EVENT_SELECTION_CHANGED,
|
695 | api: this.gridApi,
|
696 | columnApi: this.columnApi
|
697 | };
|
698 | this.mainEventService.dispatchEvent(event);
|
699 |
|
700 | return updatedCount;
|
701 | }
|
702 |
|
703 | public isParentOfNode(potentialParent: RowNode): boolean {
|
704 | let parentNode = this.parent;
|
705 | while (parentNode) {
|
706 | if (parentNode === potentialParent) {
|
707 | return true;
|
708 | }
|
709 | parentNode = parentNode.parent;
|
710 | }
|
711 | return false;
|
712 | }
|
713 |
|
714 | public selectThisNode(newValue: boolean): boolean {
|
715 | if(!this.selectable || this.selected === newValue) return false;
|
716 |
|
717 | this.selected = newValue;
|
718 |
|
719 | if (this.eventService) {
|
720 | this.dispatchLocalEvent(this.createLocalRowEvent(RowNode.EVENT_ROW_SELECTED));
|
721 | }
|
722 |
|
723 | let event: RowSelectedEvent = this.createGlobalRowEvent(Events.EVENT_ROW_SELECTED);
|
724 | this.mainEventService.dispatchEvent(event);
|
725 |
|
726 | return true;
|
727 | }
|
728 |
|
729 | private selectChildNodes(newValue: boolean, groupSelectsFiltered: boolean): number {
|
730 | let children = groupSelectsFiltered ? this.childrenAfterFilter : this.childrenAfterGroup;
|
731 |
|
732 | let updatedCount = 0;
|
733 | if (_.missing(children)) { return; }
|
734 | for (let i = 0; i<children.length; i++) {
|
735 | updatedCount += children[i].setSelectedParams({
|
736 | newValue: newValue,
|
737 | clearSelection: false,
|
738 | suppressFinishActions: true,
|
739 | groupSelectsFiltered
|
740 | });
|
741 | }
|
742 | return updatedCount;
|
743 | }
|
744 |
|
745 | public addEventListener(eventType: string, listener: Function): void {
|
746 | if (!this.eventService) { this.eventService = new EventService(); }
|
747 | this.eventService.addEventListener(eventType, listener);
|
748 | }
|
749 |
|
750 | public removeEventListener(eventType: string, listener: Function): void {
|
751 | this.eventService.removeEventListener(eventType, listener);
|
752 | }
|
753 |
|
754 | public onMouseEnter(): void {
|
755 | this.dispatchLocalEvent(this.createLocalRowEvent(RowNode.EVENT_MOUSE_ENTER));
|
756 | }
|
757 |
|
758 | public onMouseLeave(): void {
|
759 | this.dispatchLocalEvent(this.createLocalRowEvent(RowNode.EVENT_MOUSE_LEAVE));
|
760 | }
|
761 |
|
762 | public getFirstChildOfFirstChild(rowGroupColumn: Column): RowNode {
|
763 | let currentRowNode: RowNode = this;
|
764 |
|
765 |
|
766 |
|
767 |
|
768 | let isCandidate = true;
|
769 | let foundFirstChildPath = false;
|
770 | let nodeToSwapIn: RowNode;
|
771 |
|
772 | while (isCandidate && !foundFirstChildPath) {
|
773 |
|
774 | let parentRowNode = currentRowNode.parent;
|
775 | let firstChild = _.exists(parentRowNode) && currentRowNode.firstChild;
|
776 |
|
777 | if (firstChild) {
|
778 | if (parentRowNode.rowGroupColumn === rowGroupColumn) {
|
779 | foundFirstChildPath = true;
|
780 | nodeToSwapIn = parentRowNode;
|
781 | }
|
782 | } else {
|
783 | isCandidate = false;
|
784 | }
|
785 |
|
786 | currentRowNode = parentRowNode;
|
787 | }
|
788 |
|
789 | return foundFirstChildPath ? nodeToSwapIn : null;
|
790 | }
|
791 | } |
\ | No newline at end of file |