UNPKG

6.03 kBPlain TextView Raw
1import {GridOptionsWrapper} from "../gridOptionsWrapper";
2import {ColumnController} from "../columnController/columnController";
3import {GridPanel} from "../gridPanel/gridPanel";
4import {Column} from "../entities/column";
5import {Bean, Autowired, Context, PostConstruct, PreDestroy} from "../context/context";
6import {HeaderContainer} from "./headerContainer";
7import {EventService} from "../eventService";
8import {Events} from "../events";
9import {ScrollVisibleService} from "../gridPanel/scrollVisibleService";
10import {Component} from "../widgets/component";
11import {RefSelector} from "../widgets/componentAnnotations";
12import {Utils as _} from "../utils";
13import {GridApi} from "../gridApi";
14import {AutoWidthCalculator} from "../rendering/autoWidthCalculator";
15
16export class HeaderRootComp extends Component {
17
18 private static TEMPLATE =
19 `<div class="ag-header" role="row">
20 <div class="ag-pinned-left-header" ref="ePinnedLeftHeader" role="presentation"></div>
21 <div class="ag-header-viewport" ref="eHeaderViewport" role="presentation">
22 <div class="ag-header-container" ref="eHeaderContainer" role="presentation"></div>
23 </div>
24 <div class="ag-pinned-right-header" ref="ePinnedRightHeader" role="presentation"></div>
25 </div>`;
26
27 @RefSelector('ePinnedLeftHeader') private ePinnedLeftHeader: HTMLElement;
28 @RefSelector('ePinnedRightHeader') private ePinnedRightHeader: HTMLElement;
29 @RefSelector('eHeaderContainer') private eHeaderContainer: HTMLElement;
30 @RefSelector('eHeaderViewport') private eHeaderViewport: HTMLElement;
31
32 @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper;
33 @Autowired('columnController') private columnController: ColumnController;
34 @Autowired('context') private context: Context;
35 @Autowired('eventService') private eventService: EventService;
36 @Autowired('scrollVisibleService') private scrollVisibleService: ScrollVisibleService;
37 @Autowired('gridApi') private gridApi: GridApi;
38 @Autowired('autoWidthCalculator') private autoWidthCalculator: AutoWidthCalculator;
39
40 private pinnedLeftContainer: HeaderContainer;
41 private pinnedRightContainer: HeaderContainer;
42 private centerContainer: HeaderContainer;
43
44 private childContainers: HeaderContainer[];
45
46 private gridPanel: GridPanel;
47
48 constructor() {
49 super(HeaderRootComp.TEMPLATE);
50 }
51
52 public registerGridComp(gridPanel: GridPanel): void {
53 this.gridPanel = gridPanel;
54 this.centerContainer.registerGridComp(gridPanel);
55 this.pinnedLeftContainer.registerGridComp(gridPanel);
56 this.pinnedRightContainer.registerGridComp(gridPanel);
57 }
58
59 @PostConstruct
60 private postConstruct(): void {
61
62 this.gridApi.registerHeaderRootComp(this);
63 this.autoWidthCalculator.registerHeaderRootComp(this);
64
65 this.centerContainer = new HeaderContainer(this.eHeaderContainer, this.eHeaderViewport, null);
66 this.childContainers = [this.centerContainer];
67
68 this.pinnedLeftContainer = new HeaderContainer(this.ePinnedLeftHeader, null, Column.PINNED_LEFT);
69 this.pinnedRightContainer = new HeaderContainer(this.ePinnedRightHeader, null, Column.PINNED_RIGHT);
70 this.childContainers.push(this.pinnedLeftContainer);
71 this.childContainers.push(this.pinnedRightContainer);
72
73 this.childContainers.forEach( container => this.context.wireBean(container) );
74
75 // shotgun way to get labels to change, eg from sum(amount) to avg(amount)
76 this.eventService.addEventListener(Events.EVENT_COLUMN_VALUE_CHANGED, this.refreshHeader.bind(this));
77
78 // for setting ag-pivot-on / ag-pivot-off CSS classes
79 this.eventService.addEventListener(Events.EVENT_COLUMN_PIVOT_MODE_CHANGED, this.onPivotModeChanged.bind(this));
80
81 this.addPreventHeaderScroll();
82
83 if (this.columnController.isReady()) {
84 this.refreshHeader();
85 }
86 }
87
88 public setHorizontalScroll(offset: number): void {
89 this.eHeaderContainer.style.left = offset + 'px';
90 }
91
92 public forEachHeaderElement(callback: (renderedHeaderElement: Component)=>void): void {
93 this.childContainers.forEach( childContainer => childContainer.forEachHeaderElement(callback) );
94 }
95
96 @PreDestroy
97 public destroy(): void {
98 this.childContainers.forEach( container => container.destroy() );
99 }
100
101 public refreshHeader() {
102 this.childContainers.forEach( container => container.refresh() );
103 }
104
105 private onPivotModeChanged(): void {
106 let pivotMode = this.columnController.isPivotMode();
107 _.addOrRemoveCssClass(this.getGui(),'ag-pivot-on', pivotMode);
108 _.addOrRemoveCssClass(this.getGui(),'ag-pivot-off', !pivotMode);
109 }
110
111 public setHeight(height: number): void {
112 this.getGui().style.height = height + 'px';
113 this.getGui().style.minHeight = height + 'px';
114 }
115
116 // if the user is in floating filter and hits tab a few times, the header can
117 // end up scrolling to show items off the screen, leaving the grid and header
118 // and the grid columns no longer in sync.
119 private addPreventHeaderScroll() {
120 this.addDestroyableEventListener(this.eHeaderViewport, 'scroll', ()=> {
121 // if the header scrolls, the header will be out of sync. so we reset the
122 // header scroll, and then scroll the body, which will in turn set the offset
123 // on the header, giving the impression that the header scrolled as expected.
124 let scrollLeft = this.eHeaderViewport.scrollLeft;
125 if (scrollLeft!==0) {
126 this.gridPanel.scrollHorizontally(scrollLeft);
127 this.eHeaderViewport.scrollLeft = 0;
128 }
129 });
130 }
131
132 public setLeftVisible(visible: boolean): void {
133 _.setVisible(this.ePinnedLeftHeader, visible);
134 }
135
136 public setRightVisible(visible: boolean): void {
137 _.setVisible(this.ePinnedRightHeader, visible);
138 }
139}