0
votes

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.

3

3 Answers

2
votes

In CSS, you set padding: 100px so you need to set scrollHeight="calc(100% - 200px)"

If you want to update height when resize, you need to handle more. I suggest a demo here

2
votes

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.

0
votes

There's a problem with the turboTable component.

The two hacks correct the problem, but they only work well in Chrome. I tried to use it in Firefox and Edge, and both browsers froze. I think it's because ResizeObserver is a feature not supported by these two browsers at the moment.