13

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!

Nikita Marinosyan
  • 747
  • 2
  • 8
  • 26

7 Answers7

21

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

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

jvitor83
  • 220
  • 8
  • 20
  • 5
    could you please explain why did you subtract vh value by 204px? – coder Apr 09 '19 at 12:03
  • Doesn't work : ```Percentage scroll height calculation is removed in favor of the more performant CSS based flex mode, use scrollHeight="flex" instead. ```` – Cocorico Aug 31 '21 at 13:18
  • 2
    @coder 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. – AsGoodAsItGets Jul 11 '22 at 12:33
12

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

fabioresner
  • 915
  • 14
  • 21
4

Prime NG table introduced flex mode for viewport height adjustment

scrollHeight="flex"

It will take the full height of parent element.

Atanu Mallick
  • 266
  • 4
  • 7
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.

Arthur Cam
  • 549
  • 6
  • 18
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'"

Ivica Buljević
  • 150
  • 1
  • 8
1

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')));
Viktor Ivliiev
  • 1,015
  • 4
  • 14
  • 21
0

ScrollHeight needs to be 100%.

Tejashree
  • 750
  • 12
  • 14