Primeng make scrollable datatable height responsive

Viewed 34955

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!

7 Answers

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

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

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.

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'"

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')));

Prime NG table introduced flex mode for viewport height adjustment

scrollHeight="flex"

It will take the full height of parent element.

Related