Primeng: TurboTable - Toggleable Row Groups

Created on 23 Jan 2018  路  2Comments  路  Source: primefaces/primeng

I'm submitting a ... (check one with "x")

[ ] bug report => Search github for a similar issue or PR before submitting
[x] feature request => Please check if request is not on the roadmap already https://github.com/primefaces/primeng/wiki/Roadmap
[ ] support request => Please do not submit support request here, instead see http://forum.primefaces.org/viewforum.php?f=35

Please consider bringing back the toggleable row group feature from p-dataTable for p-table. Thanks!

Most helpful comment

@adama357 With recent turbo table, this could be done on templating.

if each rowGroupMetadata[rowGroup] is object that contains toggle status like
{ index: 0, size: 1, toggle: false }

template can hide <tr> with
<tr [hidden]="!rowGroupMetadata[rowData[rowGroupKey]].toggle">

then all you need is click event handler which will update the toggle status of the rowGroup

toggleRowGroup(rowGroup) {
    this.rowGroupMetadata[rowGroup].toggle = !this.rowGroupMetadata[rowGroup].toggle
}

Component Template

.
.
.
<ng-template pTemplate="body" let-rowData let-columns="columns" let-rowIndex="rowIndex">
  <tr class="ui-widget-header grid-row-group" *ngIf="rowGroupMetadata[rowData[rowGroupKey]].index === rowIndex" 
 (click)="toggleRowGroup(rowData[rowGroupKey])">
    <td [attr.colspan]="cols.length">
      <div>
        <span style="font-weight:bold">{{rowData[rowGroupKey]}}</span>
        <span>{{rowGroupMetadata[rowData[rowGroupKey]].size}} items</span>
      </div>
    </td>
  </tr>
  <tr [hidden]="!rowGroupMetadata[rowData[rowGroupKey]].toggle">
    <td *ngFor="let col of columns">
      {{rowData[col.field]}}
    </td>
  </tr>
</ng-template>
.
.
.

Component TS file

  .
  .
  .
  rowGroupKey = 'facility_type';

  cols = [
    { field: 'col1', header: 'Column 1' },
    { field: 'col2', header: 'Column 2' },
    { field: 'col3', header: 'Column 3' },
    { field: 'col4', header: 'Column 4' },
    { field: 'col5', header: 'Column 5' }
  ];

  toggleRowGroup(rowGroup) {
    this.rowGroupMetadata[rowGroup].toggle = !this.rowGroupMetadata[rowGroup].toggle
  }

  updateRowGroupMetaData(data) {

    // Todo: make this function part of GridService;
    this.rowGroupMetadata = {};

    if (!this.rowGroupKey) {
      throw new Error('Must have rowGroupKey')
    }
    if (data) {
      for (let i = 0; i < data.length; i++) {
        const rowData = data[i];
        const rowGroup = rowData[this.rowGroupKey];
        if (i === 0) {
          this.rowGroupMetadata[rowGroup] = { index: 0, size: 1, toggle: false };
        } else {
          const previousRowData = data[i - 1];
          const previousRowGroup = previousRowData[this.rowGroupKey];
          if (rowGroup === previousRowGroup) {
            this.rowGroupMetadata[rowGroup].size++;
          } else {
            this.rowGroupMetadata[rowGroup] = { index: i, size: 1, toggle: false };
          }
        }
      }
    }
  }

All 2 comments

Technically there is no built-in row groups as it is easy to do with templating;

https://www.primefaces.org/primeng/#/table/rowgroup

So sorting could be done on your side, I guess we can add this to demo but neither of these are built-in features rather extensions.

@adama357 With recent turbo table, this could be done on templating.

if each rowGroupMetadata[rowGroup] is object that contains toggle status like
{ index: 0, size: 1, toggle: false }

template can hide <tr> with
<tr [hidden]="!rowGroupMetadata[rowData[rowGroupKey]].toggle">

then all you need is click event handler which will update the toggle status of the rowGroup

toggleRowGroup(rowGroup) {
    this.rowGroupMetadata[rowGroup].toggle = !this.rowGroupMetadata[rowGroup].toggle
}

Component Template

.
.
.
<ng-template pTemplate="body" let-rowData let-columns="columns" let-rowIndex="rowIndex">
  <tr class="ui-widget-header grid-row-group" *ngIf="rowGroupMetadata[rowData[rowGroupKey]].index === rowIndex" 
 (click)="toggleRowGroup(rowData[rowGroupKey])">
    <td [attr.colspan]="cols.length">
      <div>
        <span style="font-weight:bold">{{rowData[rowGroupKey]}}</span>
        <span>{{rowGroupMetadata[rowData[rowGroupKey]].size}} items</span>
      </div>
    </td>
  </tr>
  <tr [hidden]="!rowGroupMetadata[rowData[rowGroupKey]].toggle">
    <td *ngFor="let col of columns">
      {{rowData[col.field]}}
    </td>
  </tr>
</ng-template>
.
.
.

Component TS file

  .
  .
  .
  rowGroupKey = 'facility_type';

  cols = [
    { field: 'col1', header: 'Column 1' },
    { field: 'col2', header: 'Column 2' },
    { field: 'col3', header: 'Column 3' },
    { field: 'col4', header: 'Column 4' },
    { field: 'col5', header: 'Column 5' }
  ];

  toggleRowGroup(rowGroup) {
    this.rowGroupMetadata[rowGroup].toggle = !this.rowGroupMetadata[rowGroup].toggle
  }

  updateRowGroupMetaData(data) {

    // Todo: make this function part of GridService;
    this.rowGroupMetadata = {};

    if (!this.rowGroupKey) {
      throw new Error('Must have rowGroupKey')
    }
    if (data) {
      for (let i = 0; i < data.length; i++) {
        const rowData = data[i];
        const rowGroup = rowData[this.rowGroupKey];
        if (i === 0) {
          this.rowGroupMetadata[rowGroup] = { index: 0, size: 1, toggle: false };
        } else {
          const previousRowData = data[i - 1];
          const previousRowGroup = previousRowData[this.rowGroupKey];
          if (rowGroup === previousRowGroup) {
            this.rowGroupMetadata[rowGroup].size++;
          } else {
            this.rowGroupMetadata[rowGroup] = { index: i, size: 1, toggle: false };
          }
        }
      }
    }
  }
Was this page helpful?
0 / 5 - 0 ratings