28

I have a PrimeNg turbotable with row expansion feature.

How can I expand the rows by default.

Here is my Code :

HTML

<p-table [columns]="cols" [value]="cars" dataKey="vin">
<ng-template pTemplate="header" let-columns>
    <tr>
        <th style="width: 2.25em"></th>
        <th *ngFor="let col of columns">
            {{col.header}}
        </th>
    </tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-expanded="expanded" let-columns="columns">
    <tr>
        <td>
            <a href="#" [pRowToggler]="rowData">
                <i [ngClass]="expanded ? 'fa fa-fw fa-chevron-circle-down' : 'fa fa-fw fa-chevron-circle-right'"></i>
            </a>
        </td>
        <td *ngFor="let col of columns">
            {{rowData[col.field]}}
        </td>
    </tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-rowData let-columns="columns">
    <tr>
        <td [attr.colspan]="columns.length + 1">
            <div class="ui-g ui-fluid" style="font-size:16px;padding:20px">
                <div class="ui-g-12 ui-md-3" style="text-align:center">
                    <img [attr.alt]="rowData.brand" src="assets/showcase/images/demo/car/{{rowData.brand}}.png">
                </div>
                <div class="ui-g-12 ui-md-9">
                    <div class="ui-g">
                        <div class="ui-g-12">
                            <b>Vin:</b> {{rowData.vin}}
                        </div>
                        <div class="ui-g-12">
                            <b>Vin:</b> {{rowData.color}}
                        </div>
                        <div class="ui-g-12">
                            <b>Brand:</b> {{rowData.brand}}
                        </div>
                        <div class="ui-g-12">
                            <b>Color:</b> {{rowData.color}}
                        </div>
                    </div>
                </div>
            </div>
        </td>
    </tr>
  </ng-template>
</p-table>

Ts

export class TableRowExpansionDemo implements OnInit {

    cars: Car[];

    cols: any[];

    constructor(private carService: CarService) { }

    ngOnInit() {
        this.carService.getCarsSmall().then(cars => this.cars = cars);

        this.cols = [
            { field: 'vin', header: 'Vin' },
            { field: 'year', header: 'Year' },
            { field: 'brand', header: 'Brand' },
            { field: 'color', header: 'Color' }
        ];
        }
    }
}

I tried using expandedRowKeys attribute, but it is not working for me.

What am I missing here?

Thanks

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Mak
  • 584
  • 1
  • 13
  • 33

3 Answers3

42

Update: For Version >7.x

Setting value to 1 won't work on version 7+ use boolean(true/false)

const thisRef = this;
 this.cars.forEach(function(car) {
   thisRef.expandedRows[car.vin] = true;
 });

Working StackBlitz

For Version <7.x

I tried using expandedRowKeys attribute

Yes you're right. So add [expandedRowKeys]="expandedRows"> to p-table element :

<p-table [columns]="cols" [value]="cars" dataKey="vin" [expandedRowKeys]="expandedRows">

and then, you just need to fill expandedRows object with vin values of the rows you want to expand (because dataKey is vin).

Because you want all rows to be expanded, you can fill it like that :

    const thisRef = this;
    this.cars.forEach(function(car) {
      thisRef.expandedRows[car.vin] = 1;
    });

in order to have something like expandedRows = {"dsad231ff": 1, "gwregre345": 1, ...}

See working Plunker

Rishi0405
  • 354
  • 1
  • 11
Antikhippe
  • 6,316
  • 2
  • 28
  • 43
  • Thanks @Antikhippe. What is the use if 1 in the expandedRows = {"dsad231ff": 1, "gwregre345": 1, ...} ? – Mak Feb 28 '18 at 07:48
  • 2
    I guess it means that corresponding row will be expanded if 1, collapsed if not. – Antikhippe Feb 28 '18 at 07:53
  • @Antikhippe why if we directly assign this.expandedRows[car.vin] = 1; is not working. – Vignesh Feb 28 '18 at 09:27
  • What do you mean by "directly" ? – Antikhippe Feb 28 '18 at 09:29
  • why you are assigning 'this' property to constant. // const thisRef = this; this.cars.forEach(function(car) { this.expandedRows[car.vin] = 1; }); – Vignesh Feb 28 '18 at 09:40
  • 1
    It's because *this* is undefined inside a forEach loop when using `strict mode` (https://stackoverflow.com/questions/19445599/accessing-this-in-a-foreach-loop-results-in-undefined) – Antikhippe Feb 28 '18 at 10:00
  • @Antikhippe I tried with same configuration but seems not working. Can you please help? https://stackblitz.com/edit/angular-qccqg8 – Vijay Chauhan Apr 16 '19 at 09:59
  • 1
    @VijayChauhan set to true not 1, see https://stackblitz.com/edit/angular-3y2hkn?file=src/app/app.component.ts – Rishi0405 Aug 13 '19 at 10:11
  • @Rishi0405 When I used `thisRef.expandedRows[car.vin] = false;` then I need to **click two times** to expand any row. Why? Is there any solution for it? – Abhijeet Giram Sep 24 '20 at 20:17
  • @AbhijeetGiram Expanded rows(expandedRows) is to expand particular rows initally, so set to true to the rows you want to expand, and you dont want to set to false for other rows. But if you want to close the rows manually, then set the row to null, because from the code, primeNg doesnt care about the negative type(false), it is just true/null so setting to null seems to work :) – Rishi0405 Sep 28 '20 at 15:00
3

In the accepted answer, the expandedRows mapping to the turbo table expandedRowKeys is one way i.e. it can set the state of rows at the time of loading only. If someone want to collapse or expand it after the table is loaded, you can directly edit the 'expandedRowKeys' variable by passing the table reference from the html.

Define Your table with a reference variable #dt

<p-table #dt [columns]="cols" [value]="cars" dataKey="vin">

Edit your table body like this to get a on click function trigger

<ng-template pTemplate="body" let-rowData let-expanded="expanded" let-columns="columns">
    <tr>
        <td>
            <a href="#" [pRowToggler]="rowData">
                <i [ngClass]="expanded ? 'fa fa-fw fa-chevron-circle-down' : 'fa fa-fw fa-chevron-circle-right'"></i>
            </a>
        </td>
        <td *ngFor="let col of columns">
           <a >
              <span (click)="onItemClick(rowData, dt)">
                    {{rowData[col.field]}}    
              </span>
           </a>
        </td>
    </tr>
</ng-template>

in your TS file add the function as

onItemClick(rowData:any, dt:any) {
   if(dt.expandedRowKeys[rowData._id]){
     dt.expandedRowKeys[rowData._id] = 0;
   }
   else {
    dt.expandedRowKeys[rowData._id] = 1;
   }
}

This approach gives you more freedom in changing state of table on a trigger of event from outside of table and expanding or collapsing multiple rows at once.

himanshu goyal
  • 363
  • 2
  • 9
2

After hitting many solution i tried and found easiest way to resolve

<p-table [columns]="cols" [value]="cars" dataKey="vin" [expandedRowKeys]="expandedRows">

Replace datakey value to your unique id key from list of objects fetched from service or http calls.

<p-table [columns]="cols" [value]="repaymentsList" dataKey="id" expandableRows="true" rowExpandMode="single" [responsive]="true">