I want a TurboTable to occupy the whole parent's height (and resize when the parent is resized), so only the content of the table is scrollable and no scrollbars are added to the parents component.
I've tried setting scrollHeight="100%", but that does not work as expected: https://stackblitz.com/edit/angular-d9narm.
Any ideas?
UPDATE: As @phucnh corrected, i should have used scrollHeight="calc(100% - 200px)" to compensate for the padding I have. I've now updated my stackblitz to reflect this. This works just perfectly when a window first loads, but if you try to change it's height, the height of the table would not change.
So, after some help from @phucnh and some googling i was able to produce the code which allows the TurboTable to take all its parent size and show/hide scrollbars properly:
https://stackblitz.com/edit/primeng-scrollable-table-fit-parent
Basically, it contains two hacks:
1) We need to observe parent size changes and force Angular to re-evaluate "scrollHeight" by this code:
ngAfterViewInit(): void {
new ResizeObserver(() => this.zone.run(() => this.onResize()))
.observe(this.container.nativeElement);
}
private onResize(): void {
// HACK: mark "scrollHeight" dirty, so it's re-evaluated.
if (this.table.scrollHeight.endsWith(' ')) {
this.table.scrollHeight = this.table.scrollHeight.slice(0, -1);
} else {
this.table.scrollHeight += ' ';
}
}
2) In order to work around the header cell becoming misaligned when scrollbar appears/disappears we need to do some dirty hacking (inspired by https://stackblitz.com/edit/primeng-dynamic-scrollable):
// HACK: automatically re-align table header when resized. Borrowed the idea from https://stackblitz.com/edit/primeng-dynamic-scrollable
const scrollableViewNgAfterViewInit = ScrollableView.prototype.ngAfterViewInit;
ScrollableView.prototype.ngAfterViewInit = function() {
scrollableViewNgAfterViewInit.call(this);
new ResizeObserver(() => {
this.alignScrollBar();
}).observe(this.scrollBodyViewChild.nativeElement);
};
That did the trick.
UPDATE (June 6th 2020):
recently, part 2 of this workaround stopped working. I assume that happened because Angular now caches pointers to life-cycle events. Thus, overriding them does nothing and the overridden method does not get fired.
// HACK: automatically re-align table header when resized. Borrowed the idea from https://stackblitz.com/edit/primeng-dynamic-scrollable
const bindEventsOriginal = ScrollableView.prototype.bindEvents;
ScrollableView.prototype.bindEvents = function (): void {
bindEventsOriginal.call(this);
new ResizeObserver(() => {
this.alignScrollBar();
}).observe(this.scrollBodyViewChild.nativeElement);
};
Also, PrimeNG release 9.1.0, added scrollHeight="flex" which, essentially makes part 1 of this workaround unnecessary.