Primeng: New Flex mode for Table ScrollHeight

Created on 1 Mar 2018  路  28Comments  路  Source: primefaces/primeng

I'm submitting a ... (check one with "x")

[X] bug report => Search github for a similar issue or PR before submitting

Plunkr Case (Bug Reports)
http://plnkr.co/edit/C42agbDgEgFQ1WPKOXA6?p=preview

Current behavior
Table with scrollHeight=100% does not change it's scroll view if the parent container's height changes. Also, Table does not expose the internal ScrollableView, so there is no way to try and manually trigger the scroll view to resize itself.

Expected behavior
The scroll view's height should update if the container is resized. At minimum, Table should expose a method to manually trigger resize logic for the ScrollableView.

  • Angular version: 5.2

  • PrimeNG version: 5.2

  • Browser: all

enhancement

Most helpful comment

OK, but that's why I asked for some method to be exposed to manually trigger the scrollHeight to recalculate. If the table can't do it automatically, then it seems like there should be a method we can call to have it recalculate the pixels based on either the parent element height, or possibly having an element as an argument that is used to base the height calculation on?

All 28 comments

This is also a problem for us in a SPA type layout where the table must flow to fill the remaining space of the body. We are trying to use scrollHeight="100%" and the layout looks ok when the initial page loads but then if any window resize, the table does not change height as it should when using percent-based scrollHeight.

Related to p-table height: In our table, we have a ui-table-caption which is taller than normal, because it contains some form controls.

p-table does not seem to correctly take into account the height of our custom caption, so the height computation is always about 20 pixels too short.

Yes, I didn't mention the height calculation logic not taking into account other elements (like toolbars), but I've also run into the same problem. I've also seen this affect the computed height of Dialogs. I have to do hacky things like set the height to "calc(100% - 50px)" and so on. When I have time I'll try to open another ticket for that, since I think it's a different issue (since it seems to affect Dialog, and Table, and probably other things that compute height).

Any chance this is going to be address in for the next release. We are having all types of various scroll issues because of this after upgrading from p-datatable

I've worked on this, using the case in plunkr the table has no chance to update itself because scrollHeight changes are listened meaning at on load 100% is converted to pixels. When you change the parent, it is outside the scope of table, so table has no chance to recalculate. In the plunkr, you mauy just go ahead and give the same height of the container to the scrollHeight as well but probably your real case is where scroll height needs to be adjusted according to the viewport, so why not using vh unit e.g. scrollHeight="75vh". % is relative to the parent, vh is relative to the page.

OK, but that's why I asked for some method to be exposed to manually trigger the scrollHeight to recalculate. If the table can't do it automatically, then it seems like there should be a method we can call to have it recalculate the pixels based on either the parent element height, or possibly having an element as an argument that is used to base the height calculation on?

+1 for brian428 suggestion.

PrimeNG Team,
Can we have at least some method,which we can trigger manually to recalculate scroll height & render table according to scroll height variable.

Or any alternative option to recalculate table scrollheight manually & render accordingly.

Note : In 5.2.4, we cant change table scroll height once table got rendered first time.

Do we have any update on when this is going to be resolved?

The Dogger has solved it with CSS:
https://stackblitz.com/edit/github-sbrx4k

Take a look in my styles.css at the table-scroll class

The hardcoded 29px header height might need to be tweaked in individual cases.

ah thats great thanks @hughanderson4

The css in this thread helped me a lot back then: https://github.com/primefaces/primeng/issues/1905

When the TurboTable was released, I tried the same trick in style.css. A small hack in the app.component.ts aligns the header via ResizeObserver (polyfill), so that the alignment should also work when resizing an element or dialog.

https://stackblitz.com/edit/primeng-dynamic-scrollable

@ethnoplex Thx for your solution.
Works well in Chrome for my app but breaks IE and FF (infinite loop as soon as I put any new ResizeObserver inside the prototype).
However it works in your stackblitz example :/
If you have any clue...

@sparqueur:
Sorry sparqueur, currently I have no clue what the problem might be. The approach is quite stable in my project with Chrome, Safari and FF - also for the TreeTable. Another user applies "element-resize-detector" for element listening. Maybe this works for you.

@ethnoplex Excellent solution and works perfectly as far as I can tell! Tested in latest Chrome, FF, and Edge. Hopefully the PrimeNG folks will consider adding this enhancement to the library.

any progress on this? Proposed solutions did not help me. Maybe because im using a lazy loaded table???
Cant be that difficult providing us a function to retrigger height calculation...

I managed to get around this by omitting the scrollHeight param altogether and using css to control height from body down to .ui-table-scrollable-wrapper. Basically, setting body height to 100vh, then using flex boxes to split it at each level, making sure to keep overflow:hidden on extensible elements.

Then I use the following snippet for the table elements:


css


.ui-table {
          height: 100%;
          display: flex;
          flex-direction: column;

          > * {
            flex: 0 0 auto;
          }

          > .ui-table-scrollable-wrapper {
            flex: 1 1 auto;
            overflow: hidden;

            > .ui-table-scrollable-view {
              height: 100%;
              display: flex;
              flex-direction: column;

              > .ui-table-scrollable-header {
                flex: 0 0 auto;
              }

              > .ui-table-scrollable-body {
                flex: 1 1 auto;
              }
            }
          }
        }

The aim was to have a table that fills the available vertical space, with the paginator sticky at the bottom, and the column headers sticky at the top, and with a scrollbar when displayed rows overflow.

@cghislai stackblitz of your example?

Thank you @cghislai. This works for me!

@joschne , do you have a plunker or stackblitz of your example? I've tried the same with no fix. .

@MSCapNG -- if you want to manually trigger a resize calc, try this:

  resize() {
    // 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 += ' ';
    }
    // HACK: force scrollbar show/hide recalc
    setTimeout(() => {
      this.table.tableService.onValueChange(this.table._value);
    }, 1);
  }

This is based on the stackoverflow answer here

I've packaged it in a directive with a ResizeObserver. A stackblitz example with both static and lazy-loaded tables is here.

This works for me in Chrome, FF and IE.

Final task of 9.1.0.

scrollHeight="flex" is a new mode to make the scrollable viewport dynamic relative to the size of the parent's table. We've added two demos, in the first one table is inside a resizable-maximizable Dialog and in the second one table covers the all available space of the page and adjusts to window resizing. All css no javascript so works quite fast. Brand new virtual scrolling is also supported, overall I'm really happy with the latest scrolling enhancements. Will be available next week with 9.1.0. Thank you for all the feedback.

There seems to be a problem with scrollHeight="flex" and lazy loading.

I get errors like this in develop mode, everytime the data changes.

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for 'height': '3200px'. Current value: '288px'

EDIT: And it seems like the lazy loading is called tree times. First with "first: 0" then 100, then 0 again.

@draco2007 I'm getting the same error. Now when I change it to a static number I can't get rid of that error. Help from anyone would be appreciated.

Video: https://twitter.com/cagataycivici/status/1263768334698496000?s=20

Hi - is there a code example for this anywhere?

Is there any possibility to get 100% that actually flex does minus some pixels. In my case flex takes more than necessary (use with dock-spawn)

Binding div parent height via any style (style, [style] and [ngStyle]) is not reflected down to the p-table's scrollHeight flex option. But setting pure value like [ngStyle]="{ height: '1000px' } that is understod by flex.

Was this page helpful?
0 / 5 - 0 ratings