Expandable table rows in angular 4 with angular material

angular material table expand row on button click
angular 7 table example
angular material table responsive
angular material table expand multiple rows
angular material table multiple header rows
angular material table remove row
angular material table click row
angular material nested table

How would you make rows expandable in angular material tables? One requirement is that I need to be using the angular material table. I would also prefer to use the material accordion to the information provided here.

I want to click on row and show different information for each column. Im looking for something like below. If you click on row 1, rows 2 and 3 appear with different data.

As mentioned here by Andrew Seguin this is already feasible out of the box: using the when predicate.

See this example: https://stackblitz.com/edit/angular-material-expandable-table-rows (thx to Lakston)

Inside of the mat-table tag you have to use the mat-row component with a matRipple directive. When you click on a row the row element will be assigned to the expandedElement variable:

<mat-row *matRowDef="let row; columns: displayedColumns;"
        matRipple 
        class="element-row" 
        [class.expanded]="expandedElement == row"
        (click)="expandedElement = row">
</mat-row>

But now we have to add our expanded row, that is hidden by default and will be shown if the user clicks on the row above:

<mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpansionDetailRow"
        [@detailExpand]="row.element == expandedElement ? 'expanded' : 'collapsed'"
        style="overflow: hidden"> 
</mat-row>

Important is here the already mentioned when predicate. This calls a isExpansionDetailRow function that is defined in the component itself and checks if the row has a detailRow property:

isExpansionDetailRow = (row: any) => row.hasOwnProperty('detailRow');

Since RC0 the first param is the index:

isExpansionDetailRow = (i: number, row: any) => row.hasOwnProperty('detailRow');

If you want to have an expanded view for every row, you have to add an "ExpansionDetailRow" identified by the detailRow property for every row like this:

connect(): Observable<Element[]> {
    const rows = [];
    data.forEach(element => rows.push(element, { detailRow: true, element }));
    return Observable.of(rows);
}

If you would log the rows variable to the console output, it will look like this:

EDIT: COMPLETE EXAMPLE USING DIRECTIVE

Mat Table expandable rows (sorting, pagination and filtering)

Table, 4, Beryllium, 9.0122, Be Table dynamically changing the columns displayed Table with expandable rows Table with multiple header and footer rows. Im using angular material table expandable rows. I need to show a different component depending in what im getting from the backend, but every time i click a row it try to show the first element. T…

It is not possible out of the box, but you can solve it with a little custom code. Take a look at this discussion and this solution (not from me, but the basis for this answer).

In short: Use the material table and add a click-method to the rows:

<md-row *mdRowDef="let row; columns: displayedColumns; let index=index" (click)="expandRow(index, row)" #myRow></md-row>

Add a component for the expanded area. The row_detail.html contains the html which is in the expanded area.

@Component({
  selector: 'app-inline-message',
  templateUrl: 'row_detail.html',
  styles: [`
    :host {
      display: block;
      padding: 24px;
      background: rgba(0,0,0,0.03);
    }
  `]
})
export class InlineMessageComponent {
  @Input() content1: string;
  @Input() content2: string;
}

In your component where the table lives you need the method to expand the row. First, add this to your component...

expandedRow: number;
@ViewChildren('myRow', { read: ViewContainerRef }) containers;

... and then add the method:

/**
   * Shows the detail view of the row
   * @param {number} index
   */
expandRow(index: number, row: DataFromRowFormat) {

    if (this.expandedRow != null) {
      // clear old message
      this.containers.toArray()[this.expandedRow].clear();
    }

    if (this.expandedRow === index) {
      this.expandedRow = null;
    } else {
      const container = this.containers.toArray()[index];
      const factory: ComponentFactory<InlineMessageComponent> = this.resolver.resolveComponentFactory(InlineMessageComponent);
      const messageComponent = container.createComponent(factory);

      messageComponent.instance.content1= "some text";
      messageComponent.instance.content2 = "some more text";
    }
}

angular-material-expandable-table-rows, Starter project for Angular Material apps that exports to the Angular CLI. 46.5k. 433. Files. app. New File. New Folder. Angular Generator. data:image/svg+xml  There's a good example of an Angular Material table with an expandable row in this stackoverflow answer. I can plug the example into my app, and it works correctly. I can plug the example into my app, and it works correctly.

When CDK was the only way to get something close to a Material Table, using md-row's in a regular table was a viable alternative, but since @angular/material 2.0.0-beta.12 ditched CDK tables and now have their own Data Tables that might fit your needs. See documentation below:

https://material.angular.io/components/table/overview

Table with expandable rows, Toggle light/dark theme. Toggle Zen Mode. Project. Download Project. Info. Table with expandable rows. 0. 0. Files. app. New File. New Folder. Angular  An Angular 5 data table, with pagination, sorting, expandable rows, row selection, etc. with basic accessibility support. - brunano21/angular-4-data-table

Here is how you can do it with Angular Material. This example includes pagination and one example with mat-sort-header on the 'name' column. I had to override mat paginator and do a custom sort to make sure the expandable row was still by its parent when it was sorted. This example also allows you to open multiple rows at a time and to close all rows

https://stackblitz.com/edit/angular-material2-issue-zs6rfz

Expandable Rows in Mat-Table programmed with Angular , Expandable Rows in Mat-Table programmed with Angular. With Material package using Mat-Table, it is rather easy to program tables with expandable rows. We have used Expandable Rows in Mat-Tables when we wanted to provide extra information about the data in the row. The expandable row feature (also the example on the material web site) is also not working in EDGE and IE11. Was working ok in Material 7.3.3 Copy link Quote reply

Angular Material Table (mat-sort-header + expandable rows) · Issue , I created an angular material table with expandable rows and added mat-sort-​header to the columns. When I click on a column it sorts, but  Basic use of `<mat-table>` (uses display flex) No. Name Weight Symbol 1 Hydrogen 1.0079 H 2 Helium 4.0026 He 3 Lithium 6.941 Li 4 Beryllium 9.0122 Be 5 Boron 10.811 B 6 Carbon 12.0107 C 7 Nitrogen 14.0067 N 8 Oxygen 15.9994 O 9 Fluorine 18.9984 F 10 Neon 20.1797 Ne

Material table with expandable rows, I am trying to create an expandable table, like in the docs, but where a particular How to Improve your Angular application's performance 4 comments. share. I am using Material table with expandable row I would like to have multiple rows expanded on row clicks. The default behavior is to close the previously expanded row upon a new row click.

Basic table, As mentioned here by Andrew Seguin this is already feasible out of the box: using the when predicate. See this example:  With Material package using Mat-Table, it is rather easy to program tables with expandable rows. We have used Expandable Rows in Mat-Tables when we wanted to provide extra information about the data in the row. Mat-Table without Expandable Rows. We first look at how to create a Table which shows only one type of Data. Provided below is an example.

Comments
  • Where do you want to show the information?
  • Is there a way to grab the index in an individual cell so that only that cell is clickable? Also, this when solution is very nice! I'm injecting a details component that retrieves additional data from the API, so I'm not sure that would make sense here.
  • Nevermind. I see that you can do let row; let index = index right in the cell definition to receive the row properties.
  • @David Here's an example with pagination, sorting and filtering: stackblitz.com/edit/… (thx to shlomiassaf). It uses another approach that is better for this case than in the example above.
  • This solution unfortunately does not support pagination and sorting!
  • I'm getting the following error: TypeError: Cannot read property 'sticky' of undefined
  • This is the one that worked for me, I think because I'm working with a custom datasource, thanks very much
  • this is the thing i was searching and this suits my needs . Thanks :)
  • I like this solution, creating a dynamic component better than the solution shown by @Philipp Kief above (let's call that one dynamic row). The dynamic row solution starts to cause some grief around pagination and sorting as it is messing with the rows of the table. This solution, dynamic component, also gives you the ability to easily do everything else with the component that you would normally do.
  • add this.expandedRow = index at the end of the else block in the expandRow method
  • Check out this stackblitz to implement animation when the dynamic component is created and destroyed with each click