0

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.

Dmytro Gokun
  • 405
  • 3
  • 24

3 Answers3

2

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

phucnh
  • 1,020
  • 6
  • 14
  • Wow! That was brilliant (and really stupid of me). Thanks a lot, man! – Dmytro Gokun Jan 15 '19 at 14:08
  • Okay, so that was a bit premature :(. It works perfectly initially, but when parent is resized, this table remains of the same size. I've updated my stackblitz. – Dmytro Gokun Jan 15 '19 at 15:05
  • 1
    I added a demo for you – phucnh Jan 15 '19 at 16:27
  • Thanks a lot. You've pushed me to the right direction and after adding 'resize' to my search terms, I've found this: https://github.com/primefaces/primeng/issues/5235 and there i found this reference: https://stackblitz.com/edit/primeng-dynamic-scrollable. Combining it with the idea from your sample I was able to produce this solution: https://stackblitz.com/edit/primeng-scrollable-table-fit-parent which works pretty smoothly. – Dmytro Gokun Jan 16 '19 at 13:57
2

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.

Dmytro Gokun
  • 405
  • 3
  • 24
0

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.

  • Sorry for the late reply. I've just tested this with Chrome & Edge and it works just fine. I use "resize-observer-polyfill" library and then: import ResizeObserver from 'resize-observer-polyfill'; Let me know if this helps or not. – Dmytro Gokun Jun 27 '19 at 09:15