Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Primeng make scrollable datatable height responsive

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!

like image 822
Nikita Marinosyan Avatar asked Nov 22 '17 22:11

Nikita Marinosyan


4 Answers

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

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

like image 141
jvitor83 Avatar answered Oct 04 '22 13:10

jvitor83


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

like image 33
Ivica Buljević Avatar answered Oct 04 '22 11:10

Ivica Buljević


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

like image 27
fabioresner Avatar answered Oct 04 '22 11:10

fabioresner


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.

like image 41
Arthur Cam Avatar answered Oct 04 '22 11:10

Arthur Cam