UNPKG

7.03 kBPlain TextView Raw
1import {Utils as _} from "../utils";
2import {GridOptionsWrapper} from "../gridOptionsWrapper";
3import {Autowired, Context, PostConstruct} from "../context/context";
4import {DragAndDropService, DropTarget} from "../dragAndDrop/dragAndDropService";
5import {ColumnController} from "../columnController/columnController";
6import {GridPanel} from "../gridPanel/gridPanel";
7import {EventService} from "../eventService";
8import {Events} from "../events";
9import {HeaderRowComp, HeaderRowType} from "./headerRowComp";
10import {BodyDropTarget} from "./bodyDropTarget";
11import {Column} from "../entities/column";
12import {ScrollVisibleService} from "../gridPanel/scrollVisibleService";
13import {Component} from "../widgets/component";
14
15export class HeaderContainer {
16
17 @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
18 @Autowired('context') private context: Context;
19 @Autowired('$scope') private $scope: any;
20 @Autowired('dragAndDropService') private dragAndDropService: DragAndDropService;
21 @Autowired('columnController') private columnController: ColumnController;
22 @Autowired('eventService') private eventService: EventService;
23 @Autowired('scrollVisibleService') private scrollVisibleService: ScrollVisibleService;
24
25 private eContainer: HTMLElement;
26 private eViewport: HTMLElement;
27
28 private headerRowComps: HeaderRowComp[] = [];
29
30 private pinned: string;
31
32 private scrollWidth: number;
33
34 private dropTarget: DropTarget;
35
36 constructor(eContainer: HTMLElement, eViewport: HTMLElement, pinned: string) {
37 this.eContainer = eContainer;
38 this.pinned = pinned;
39 this.eViewport = eViewport;
40 }
41
42 public registerGridComp(gridPanel: GridPanel): void {
43 this.setupDragAndDrop(gridPanel);
44 }
45
46 public forEachHeaderElement(callback: (renderedHeaderElement: Component)=>void): void {
47 this.headerRowComps.forEach( headerRowComp => headerRowComp.forEachHeaderElement(callback) );
48 }
49
50 @PostConstruct
51 private init(): void {
52 this.scrollWidth = this.gridOptionsWrapper.getScrollbarWidth();
53
54 // if value changes, then if not pivoting, we at least need to change the label eg from sum() to avg(),
55 // if pivoting, then the columns have changed
56 this.eventService.addEventListener(Events.EVENT_COLUMN_VALUE_CHANGED, this.onColumnValueChanged.bind(this));
57 this.eventService.addEventListener(Events.EVENT_COLUMN_ROW_GROUP_CHANGED, this.onColumnRowGroupChanged.bind(this));
58 this.eventService.addEventListener(Events.EVENT_GRID_COLUMNS_CHANGED, this.onGridColumnsChanged.bind(this));
59 this.eventService.addEventListener(Events.EVENT_SCROLL_VISIBILITY_CHANGED, this.onScrollVisibilityChanged.bind(this));
60
61 this.eventService.addEventListener(Events.EVENT_COLUMN_RESIZED, this.onColumnResized.bind(this));
62 this.eventService.addEventListener(Events.EVENT_DISPLAYED_COLUMNS_CHANGED, this.onDisplayedColumnsChanged.bind(this));
63 }
64
65 // if row group changes, that means we may need to add aggFunc's to the column headers,
66 // if the grid goes from no aggregation (ie no grouping) to grouping
67 private onColumnRowGroupChanged(): void {
68 this.onGridColumnsChanged();
69 }
70
71 // if the agg func of a column changes, then we may need to update the agg func in columns header
72 private onColumnValueChanged(): void {
73 this.onGridColumnsChanged();
74 }
75
76 private onColumnResized(): void {
77 this.setWidthOfPinnedContainer();
78 }
79
80 private onDisplayedColumnsChanged(): void {
81 this.setWidthOfPinnedContainer();
82 }
83
84 private onScrollVisibilityChanged(): void {
85 this.setWidthOfPinnedContainer();
86 }
87
88 private setWidthOfPinnedContainer(): void {
89
90 let pinningLeft = this.pinned === Column.PINNED_LEFT;
91 let pinningRight = this.pinned === Column.PINNED_RIGHT;
92
93 if (pinningLeft || pinningRight) {
94
95 // size to fit all columns
96 let width = pinningLeft ?
97 this.columnController.getPinnedLeftContainerWidth()
98 : this.columnController.getPinnedRightContainerWidth();
99
100 // if there is a scroll showing (and taking up space, so Windows, and not iOS)
101 // in the body, then we add extra space to keep header aligned with the body,
102 // as body width fits the cols and the scrollbar
103 let addPaddingForScrollbar = pinningLeft ?
104 this.scrollVisibleService.isLeftVerticalScrollShowing()
105 : this.scrollVisibleService.isRightVerticalScrollShowing();
106 if (addPaddingForScrollbar) {
107 width += this.scrollWidth;
108 }
109
110 this.eContainer.style.width = width + 'px';
111 }
112 }
113
114 public destroy(): void {
115 this.removeHeaderRowComps();
116 }
117
118 // grid cols have changed - this also means the number of rows in the header can have
119 // changed. so we remove all the old rows and insert new ones for a complete refresh
120 private onGridColumnsChanged() {
121 this.removeHeaderRowComps();
122 this.createHeaderRowComps();
123 }
124
125 // we expose this for gridOptions.api.refreshHeader() to call
126 public refresh(): void {
127 this.onGridColumnsChanged();
128 }
129
130 private setupDragAndDrop(gridComp: GridPanel): void {
131 let dropContainer = this.eViewport ? this.eViewport : this.eContainer;
132 let bodyDropTarget = new BodyDropTarget(this.pinned, dropContainer);
133 this.context.wireBean(bodyDropTarget);
134 bodyDropTarget.registerGridComp(gridComp);
135 }
136
137 private removeHeaderRowComps(): void {
138 this.headerRowComps.forEach( headerRowComp => {
139 headerRowComp.destroy();
140 });
141 this.headerRowComps.length = 0;
142 _.removeAllChildren(this.eContainer);
143 }
144
145 private createHeaderRowComps(): void {
146 // if we are displaying header groups, then we have many rows here.
147 // go through each row of the header, one by one.
148 let rowCount = this.columnController.getHeaderRowCount();
149
150 for (let dept = 0; dept<rowCount; dept++) {
151 let groupRow = dept !== (rowCount - 1);
152 let type = groupRow ? HeaderRowType.COLUMN_GROUP : HeaderRowType.COLUMN;
153 let headerRowComp = new HeaderRowComp(dept, type, this.pinned, this.dropTarget);
154 this.context.wireBean(headerRowComp);
155 this.headerRowComps.push(headerRowComp);
156 this.eContainer.appendChild(headerRowComp.getGui());
157 }
158
159 let includeFloatingFilterRow = this.gridOptionsWrapper.isFloatingFilter() && !this.columnController.isPivotMode();
160
161 if (includeFloatingFilterRow) {
162 let headerRowComp = new HeaderRowComp(rowCount, HeaderRowType.FLOATING_FILTER, this.pinned, this.dropTarget);
163 this.context.wireBean(headerRowComp);
164 this.headerRowComps.push(headerRowComp);
165 this.eContainer.appendChild(headerRowComp.getGui());
166 }
167 }
168
169}
\No newline at end of file