Search code examples
angularprimeng-datatable

p-splitter & p-table with horizontal scroll


I need split page vertically (e.g. 60%:40%) to the two areas and splitter must be draggable. So I chose PrimeNG p-splitter. Right area contains p-table with horizontal scrollbar (based on doc: https://www.primefaces.org/primeng/showcase/#/table/scroll part: "Horizontal and Vertical"):

<p-splitter [panelSizes]="[60,40]" [style]="{'height': '400px'}">
  <ng-template pTemplate>

    <p-table [value]="cars" [scrollable]="true" [style]="{width:'600px'}" scrollHeight="200px">
    ...
    </p-table>

  </ng-template>
  <ng-template pTemplate>
    Panel 2
  </ng-template>
</p-splitter>

enter image description here

Problem is that table width is bound to 600px and:

  1. it is not possible to drag splitter to the right (table does not allow it)
  2. when splitter is dragged to the left, table width stays 600px (so there is useless blank space between table and splitter).

Project on StackBlitz

https://stackblitz.com/edit/primeng-splitter-and-datatable

Complete code

<p-splitter [panelSizes]="[60,40]" [style]="{'height': '400px'}">
  <ng-template pTemplate>

    <p-table [value]="cars" [scrollable]="true" [style]="{width:'600px'}" scrollHeight="200px">

      <ng-template pTemplate="colgroup" let-columns>
        <colgroup>
          <col style="width:250px">
          <col style="width:250px">
          <col style="width:250px">
          <col style="width:250px">
        </colgroup>
      </ng-template>

      <ng-template pTemplate="header">
        <tr>
          <th>Vin</th>
          <th>Year</th>
          <th>Brand</th>
          <th>Color</th>
        </tr>
      </ng-template>

      <ng-template pTemplate="body" let-car>
        <tr>
          <td>{{car.vin}}</td>
          <td>{{car.year}}</td>
          <td>{{car.brand}}</td>
          <td>{{car.color}}</td>
        </tr>
      </ng-template>
    </p-table>

  </ng-template>
  <ng-template pTemplate>
    Panel 2
  </ng-template>
</p-splitter>
import {Component, OnInit} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  cars: any[] = [];

  ngOnInit(): void {
    this.cars = [
      {
        vin: 1001,
        year: '2021',
        brand: 'VW',
        color: 'red',
        country: 'Algeria'
      },
      {
        vin: 1002,
        year: '2021',
        brand: 'VW',
        color: 'red',
        country: 'Algeria'
      },
      {
        vin: 1003,
        year: '2021',
        brand: 'VW',
        color: 'red',
        country: 'Algeria'
      },
      {
        vin: 1004,
        year: '2021',
        brand: 'VW',
        color: 'red',
        country: 'Algeria'
      },
      {
        vin: 1005,
        year: '2021',
        brand: 'VW',
        color: 'red',
        country: 'Algeria'
      }
    ];
  }
}

Solution

  • I had the same problem and was able to find a workaround. It's not perfect, but works ok-ish for me for now.

    You can give the table a max-width attribute and recalculate it when the Splitter Module emits the onResizeEnd Event. For me it looks something like this:

    import { Component, ViewChild } from '@angular/core';
    import { PrimeNGConfig } from 'primeng/api';
    import { Splitter } from 'primeng/splitter';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
      cars: any[] = [];
    
      @ViewChild('pSplitter') pSplitter: Splitter;
      public widthHelper = '300px';
    
      ngOnInit(): void {
        this.cars = [
          {
            vin: 1001,
            year: '2021',
            brand: 'VW',
            color: 'red',
            country: 'Algeria'
          },
          {
            vin: 1002,
            year: '2021',
            brand: 'VW',
            color: 'red',
            country: 'Algeria'
          },
          {
            vin: 1003,
            year: '2021',
            brand: 'VW',
            color: 'red',
            country: 'Algeria'
          },
          {
            vin: 1004,
            year: '2021',
            brand: 'VW',
            color: 'red',
            country: 'Algeria'
          },
          {
            vin: 1005,
            year: '2021',
            brand: 'VW',
            color: 'red',
            country: 'Algeria'
          }
        ];
      }
    
      public recalculateSlider(event) {
        this.widthHelper =  0.01 * this.pSplitter._panelSizes[0] /*percent of the panel width*/ * 600 * /*width of the panel component*/ - 4 /*width of the splitter*/+ 'px';
      }
    }
    <p-splitter #pSplitter [style]="{'height': '400px', 'width': '600px'}" [panelSizes]="[50,50]"
      (onResizeEnd)="recalculateSlider($event)">
    
      <ng-template pTemplate>
        <p-table [value]="cars" [scrollable]="true" [ngStyle]="{'max-width': widthHelper}" scrollHeight="400px">
    
          <ng-template pTemplate="colgroup" let-columns>
            <colgroup>
              <col style="width:250px">
              <col style="width:250px">
              <col style="width:250px">
              <col style="width:250px">
            </colgroup>
          </ng-template>
    
          <ng-template pTemplate="header">
            <tr>
              <th>Vin</th>
              <th>Year</th>
              <th>Brand</th>
              <th>Color</th>
            </tr>
          </ng-template>
    
          <ng-template pTemplate="body" let-car>
            <tr>
              <td>{{car.vin}}</td>
              <td>{{car.year}}</td>
              <td>{{car.brand}}</td>
              <td>{{car.color}}</td>
            </tr>
          </ng-template>
        </p-table>
    
      </ng-template>
      <ng-template pTemplate>
        Panel 2
      </ng-template>
    </p-splitter>

    The width of the table is only updated when you let go of the Splitter, but at least the functionality is there.

    Here is a link to the project on StackBlitz https://stackblitz.com/edit/primeng-splitter-and-datatable-hq9qeo