Primeng make scrollable datatable height responsive
Asked Answered
E

8

14

PrimeNG DataTable provides a [scrollable] property to define vertical and/or horizontal scrolling. This has to be used with a combination of a set scrollHeight and/or scrollWidth.

How can I have a table that will adjust to whatever the height/width of the window along with maintaining the scrollable feature?

Here is the code I've tried:

<div class="ui-g-12">

    <p-dataTable class="ui-g-12" [value]="rows"    [hidden]="this.apiService.spinnerIsVisible"
    [style]="{ height: 'fit-content', 'margin-top': '10px' }"
    [resizableColumns]="false" columnResizeMode="fit" emptyMessage="No records found"
    [responsive]="false"
    [globalFilter]="tableSearch"
    [editable]="true"
    [scrollable]="true" scrollHeight="100%" scrollWidth="100%">

      <p-header>
        <button pButton type="button" icon="fa-refresh" (click)="refresh()" style="float:left"></button>
        <label for="tableSearch">Global search: </label>
        <input id="tableSearch" #tableSearch type="text" placeholder="type here">
      </p-header>

      <p-column
        *ngFor="let col of cols" [header]="col" [field]="col"
        [style]="{'width': '250px', 'min-width': '50px', 'word-wrap': 'break-word'}"
        [sortable]="true"
        [filter]="true" filterPlaceholder="" filterMatchMode="contains"
        [editable]="true">
      </p-column>

    </p-dataTable>
</div>

But it only solves the responsive width problem. On the screenshot you can se the table which is horizontally scrollable: here is the screenshot

Since the height attribute of the p-dataTable is relative to parent in case of percentage value, I've tried to make the parent div to fit content by adding style="height: 100%" to the parent div. Here is the updated code:

<div class="ui-g-12" style="height: 100%">

    <p-dataTable class="ui-g-12" [value]="rows" [hidden]="this.apiService.spinnerIsVisible"
    [style]="{ height: 'fit-content', 'margin-top': '10px' }"
    [resizableColumns]="false" columnResizeMode="fit" emptyMessage="No records found"
    [responsive]="false"
    [globalFilter]="tableSearch"
    [editable]="true"
    [scrollable]="true" scrollHeight="100%" scrollWidth="100%">

      <p-header>
        <button pButton type="button" icon="fa-refresh" (click)="refresh()" style="float:left"></button>
        <label for="tableSearch">Global search: </label>
        <input id="tableSearch" #tableSearch type="text" placeholder="type here">
      </p-header>

      <p-column
        *ngFor="let col of cols" [header]="col" [field]="col"
        [style]="{'width': '250px', 'min-width': '50px', 'word-wrap': 'break-word'}"
        [sortable]="true"
        [filter]="true" filterPlaceholder="" filterMatchMode="contains"
        [editable]="true">
      </p-column>

    </p-dataTable>
</div>

I also applied following changes to my styles.scss file to make it work (found this in some other question on stackoverflow):

html, body {
  height: 100%;
}

But it also didn't work for me:enter image description here On the screenshot the height seems to be right, but it is not. When I scroll down, firstly, it goes as it should, but then when close to the end of the table, the scroll bar comes out of the view so I can't see it while I'm still able to scroll. So seems like the datatable is little bit higher than it should be.

So how do I solve this? Any help would be appreciated!

Elyn answered 22/11, 2017 at 22:34 Comment(1)
Man have you solved this problem? Trying same thing here.Antipodes
A
15

I don't know if this fits exactly your case, but I solved my issue by setting the scrollHeight datatable property to:

scrollHeight="50vh"

vh refers to:

vh Relative to 1% of the height of the viewport

Viewport = the browser window size. If the viewport is 50cm wide, 1vw = 0.5cm.

You can test different values of the vh and see what fits better.

more on: https://www.w3schools.com/cssref/css_units.asp

Antipodes answered 1/3, 2018 at 19:9 Comment(0)
F
24

I use this at p-table (not sure if will work on p-datatable).

[scrollHeight]="'calc(100vh - 204px)'"

Frosty answered 29/8, 2018 at 5:2 Comment(3)
could you please explain why did you subtract vh value by 204px?Dermatologist
Doesn't work : ```Percentage scroll height calculation is removed in favor of the more performant CSS based flex mode, use scrollHeight="flex" instead. ````Thunderclap
@Dermatologist the 204px is the size of your app toolbar + headers + margins on your page. In your case you will have to calculate exactly how much that is yourself. Not all applications have the same layout and toolbar sizes.Labialized
A
15

I don't know if this fits exactly your case, but I solved my issue by setting the scrollHeight datatable property to:

scrollHeight="50vh"

vh refers to:

vh Relative to 1% of the height of the viewport

Viewport = the browser window size. If the viewport is 50cm wide, 1vw = 0.5cm.

You can test different values of the vh and see what fits better.

more on: https://www.w3schools.com/cssref/css_units.asp

Antipodes answered 1/3, 2018 at 19:9 Comment(0)
V
7

Prime NG table introduced flex mode for viewport height adjustment

scrollHeight="flex"

It will take the full height of parent element.

Variole answered 26/8, 2022 at 16:49 Comment(0)
S
2

My story:

Since version 9.1.0, the component is automatically rebuilt depending on the size of the window. But in my case, there were no changes to the window size, but there were changes to the dom tree, since additional elements were removed.

My solution:

scrollHeight='flex';

It didn't help me, because I had a specific pagination that was tied to the scroll, in the end I just, when changing the dom, additionally called the resize event.

setTimeout(() => window.dispatchEvent(new Event('resize')));
Stob answered 19/7, 2022 at 18:1 Comment(0)
I
1

You can get inner height and inner width in ts file like

setInnerWidthHeightParameters()
  {
    this.innerWidth = window.innerWidth;
    this.innerHeight = window.innerHeight * 0.70;
  }

and use it as

[scrollHeight]="innerHeight +'px'"

to set it dynamically, it worked for me.

Inquisition answered 19/8, 2019 at 18:57 Comment(0)
L
1

for other who search similar problems, i solve them this way:

  1. mark PARENT div in template with (for example) #leftSidebar

  2. in component use view child :

    @ViewChild('leftSidebar', { static: true }) leftSidebar: ElementRef;

  3. you can access it and get position and size like this:

    let rect: any = this.leftSidebar.nativeElement.getBoundingClientRect(); let x: number = rect.x; let y: number = rect.y; let width: number = rect.width; let height: number = rect.height;

  4. you can do like Arthur described above and set:

    [scrollHeight]="height+'px'"

Lewls answered 8/10, 2020 at 7:10 Comment(0)
P
0

ScrollHeight needs to be 100%.

Photina answered 10/12, 2018 at 11:32 Comment(0)
D
0

What i achieve by this solution:

  1. dynamic height of the table depending on the available space
  2. If the entries of the table exceed the available height the table shows a scrollbar and the user is able to scroll within the table component.

Steps

  1. Make sure that the direct parent is not able to expand. Either set a constant height or use "flex" with "overflow : hidden" (or something that i don't know of).
  2. Add "display : flex" to the parent
  3. Add the following html and css.

html:

<p-table scrollable="true"
         scrollHeight="flex"
         ...>
...
</p-table>

css:

p-table {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    overflow: hidden;
}

::ng-deep .p-datatable.p-component.p-datatable-hoverable-rows.p-datatable-scrollable.p-datatable-flex-scrollable {
    flex: 1 1 auto;
    min-width: 100%;
    max-width: 100%;
    min-height: 100%;
    max-height: 100%;
}

Hope this helps.

Dx answered 7/8 at 7:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.