Angular Bootstrap datatables

Angular Datatables - - Bootstrap 4 & Material Design

Note: This documentation is for an older version of Bootstrap (v.4). A newer version is available for Bootstrap 5. We recommend migrating to the latest version of our product - Material Design for Bootstrap 5.
Go to docs v.5

Angular Bootstrap Datatables are component which mixes tables with advanced options like searching, sorting, pagination and generating CSV file.

Basic example

Live example
        
            
            <div class="container">
              <div class="row">
                <div class="col-md-6 mx-auto">
                  <div class="md-form">
                    <input type="text" class="form-control" [(ngModel)]="searchText" (keyup)="searchItems()" id="search-input"
                          mdbInput>
                    <label for="search-input">Search</label>
                  </div>
                </div>
                <table mdbTable #tableEl="mdbTable" stickyHeader="true" hover="true" striped="true" class="z-depth-1">
                  <thead class="sticky-top">
                  <tr>
                    <th *ngFor="let head of headElements; let i = index" [mdbTableSort]="elements" [sortBy]="headElements[i]"
                        scope="col">{{ head | titlecase }} <mdb-icon fas icon="sort"></mdb-icon>
                    </th>
                  </tr>
                  </thead>
                  <tbody #row>
                  <tr mdbTableCol (rowCreated)="onRowCreate($event)" (rowRemoved)="onRowRemove($event)" *ngFor="let el of elements; let i = index">
                    <th *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex" scope="row">{{ el.id }}</th>
                    <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex" class="red-text">{{ el.first }}</td>
                    <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex">{{ el.last }}</td>
                    <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex">{{ el.handle }}</td>
                  </tr>
                  </tbody>
                  <tfoot class="grey lighten-5 w-100">
                  <tr>
                    <td colspan="4">
                      <mdb-table-pagination [tableEl]="tableEl" paginationAlign="" [searchDataSource]="elements"></mdb-table-pagination>
                    </td>
                  </tr>
                  </tfoot>
                </table>
              </div>
            </div>
          
        
    
        
            
            import { Component, OnInit, ElementRef, HostListener, AfterViewInit, ViewChild, ChangeDetectorRef } from '@angular/core';
            import { MdbTableDirective, MdbTablePaginationComponent } from 'ng-uikit-pro-standard';
            
            @Component({
              selector: 'app-datatables',
              templateUrl: './datatables.component.html',
              styleUrls: ['./datatables.component.scss']
            })
            export class DatatablesComponent implements OnInit, AfterViewInit {
              @ViewChild(MdbTableDirective, { static: true }) mdbTable: MdbTableDirective;
              @ViewChild(MdbTablePaginationComponent, { static: true }) mdbTablePagination: MdbTablePaginationComponent;
              @ViewChild('row', { static: true }) row: ElementRef;
  
              elements: any = [];
              headElements = ['id', 'first', 'last', 'handle'];
  
              searchText: string = '';
              previous: string;
  
              maxVisibleItems: number = 8;
  
              constructor(private cdRef: ChangeDetectorRef) {}
  
              @HostListener('input') oninput() {
                this.mdbTablePagination.searchText = this.searchText;
              }
  
              ngOnInit() {
                for (let i = 1; i <= 25; i++) {
                  this.elements.push({id: i.toString(), first: 'Wpis ' + i, last: 'Last ' + i, handle: 'Handle ' + i});
                }
  
                this.mdbTable.setDataSource(this.elements);
                this.elements = this.mdbTable.getDataSource();
                this.previous = this.mdbTable.getDataSource();
              }
  
              ngAfterViewInit() {
                this.mdbTablePagination.setMaxVisibleItemsNumberTo(this.maxVisibleItems);
  
                this.mdbTablePagination.calculateFirstItemIndex();
                this.mdbTablePagination.calculateLastItemIndex();
                this.cdRef.detectChanges();
              }
  
              addNewRow() {
                this.mdbTable.addRow({
                  id: this.elements.length.toString(),
                  first: 'Wpis ' + this.elements.length,
                  last: 'Last ' + this.elements.length,
                  handle: 'Handle ' + this.elements.length
                });
                this.emitDataSourceChange();
              }
  
              addNewRowAfter() {
                this.mdbTable.addRowAfter(1, {id: '2', first: 'Nowy', last: 'Row', handle: 'Kopytkowy'});
                this.mdbTable.getDataSource().forEach((el: any, index: any) => {
                  el.id = (index + 1).toString();
                });
                this.emitDataSourceChange();
              }
  
              removeLastRow() {
                this.mdbTable.removeLastRow();
                this.emitDataSourceChange();
                this.mdbTable.rowRemoved().subscribe((data: any) => {
                  console.log(data);
                });
              }
  
              removeRow() {
                this.mdbTable.removeRow(1);
                this.mdbTable.getDataSource().forEach((el: any, index: any) => {
                  el.id = (index + 1).toString();
                });
                this.emitDataSourceChange();
                this.mdbTable.rowRemoved().subscribe((data: any) => {
                  console.log(data);
                });
              }
  
              emitDataSourceChange() {
                this.mdbTable.dataSourceChange().subscribe((data: any) => {
                  console.log(data);
                });
              }
  
              searchItems() {
                const prev = this.mdbTable.getDataSource();
  
                if (!this.searchText) {
                  this.mdbTable.setDataSource(this.previous);
                  this.elements = this.mdbTable.getDataSource();
                }
  
                if (this.searchText) {
                  this.elements = this.mdbTable.searchLocalDataBy(this.searchText);
                  this.mdbTable.setDataSource(prev);
                }
  
                this.mdbTablePagination.calculateFirstItemIndex();
                this.mdbTablePagination.calculateLastItemIndex();
  
                this.mdbTable.searchDataObservable(this.searchText).subscribe(() => {
                  this.mdbTablePagination.calculateFirstItemIndex();
                  this.mdbTablePagination.calculateLastItemIndex();
                });
              }
            }
          
        
    

Advanced table options

For advanced options of the tables have a look at specific documentation pages listed below.

Table sort

This functionality lets you sort the table data according to any specific columns.

Table editable

Table editable allows you to edit existing data within the table and add new data to the table.

Table Responsive

Table responsive allows you to use tables on mobile devices.

Table styles

Table styles shows how you can customize your tables.

Angular Datatables - API

In this section you will find advanced information about the Table component. You will find out which modules are required in this component, what are the possibilities of configuring the component, and what events and methods you can use in working with it.

Modules used

In order to speed up your application, you can choose to import only the modules you actually need, instead of importing the entire MDB Angular library. Remember that importing the entire library, and immediately afterwards a specific module, is bad practice, and can cause application errors.

        
            
          import { WavesModule } from 'ng-uikit-pro-standard';
        
        
    
        
            
          import { FormsModule } from '@angular/forms';
        
        
    
        
            
          import { HttpModule } from '@angular/http';
        
        
    

Exporting table data to CSV requires external library called Angular5-csv. Install it by typing following command into your console.

        
            
          npm install angular5-csv --save
        
        
    

angular5-csv plugin

The table shows the configuration options of the angular5-csv library.

Name Type Default Description Example
fieldSeparator string ' , ' Defines a character that separates fields in the generated .csv file fieldSeparator: ','
quoteStrings string ' , ' If provided, will use this characters to "escape" fields, otherwise will use double quotes as deafult quoteStrings: '"'
decimalseparator string ' . ' Defines the decimal separator character (default is .). If set to "locale", it uses the language sensitive representation of the number. decimalseparator: '.'
showLabels boolean false If provided, would use this attribute to create a header row showLabels: true
showTitle boolean false If provided, would use this attribute to create a title showTitle: true
useBom boolean true If true, adds a BOM character at the start of the CSV useBom: true
noDownload boolean false If true, disables automatic download and returns only formatted CSV noDownload: true,
headers Array<string> [''] If provided, defines the column headers in CSV headers: ['Post ID', 'Post title', 'Post body']

Properties

The table shows the available properties in component.

Name Type Default Description Example
maxVisibleItems number 10 If provided, defines the max visible items at one time. maxVisibleItems: number = 10

Methods

The table shows the available methods in component.

Name Parameters Description Example
generateCsv() searchData: any, title: string, options: Object Generates a .csv file from the currently displayed table. It uses the source, file name, and configuration options as arguments. generateCsv() { new Angular5Csv(this.search(), 'data-table', this.options); }

Directive

MdbTableDirective

Selector: mdbTable

Export as: mdbTable

Type: MdbTableDirective


Methods

Name Description Example
setDataSource(source: Array<any>) It is used to indicate service an array that stores the data contained in the table. The use of this method is required for the use of results filtering. this.tableService.setDataSource(this.elements)
getDataSource() The method returns an array that has been indicated as the data source of the table. The use of this method is required to filter the results. this.elements = this.tableService.getDataSource()
searchLocalDataBy(searchText: string) The method starts filtering the source array by the character provided as its parameter. The use of this method is required to be able to filter the results. this.elements = this.tableService.searchLocalDataBy(this.searchText)

Inputs

Name Type Default Description Example
striped boolean false Adds a striped effect to the table. Striped is an effect similar to zebra - every second row is colored. striped="true"
bordered boolean false Adds a border to the entire table. bordered="true"
borderless boolean false Removes all borders from the table. borderless="true"
hover boolean false Adds a highlighting effect to the line on which the mouse cursor is located. hover="true"
small boolean false Changes the size of the table. Reduces row spacing to make the table narrower. small="true"
responsive boolean false Adds responsiveness to the table so that the table behaves correctly at lower resolutions. responsive="true"
stickyHeader boolean false Adds the ability to stick the header to the top edge of the table so that the header moves with the scrolling of the table. stickyHeader="true"
stickyHeaderBgColor string ' ' Adds the ability to change the background color of the table header. The default background color is #f2f2f2f2. stickyHeaderBgColor="#303030"
stickyHeaderTextColor string ' ' Adds the ability to change the text color of the table header. The default text color is #f000000. stickyHeaderTextColor="#ffffff"

Angular Datatables examples & customization

Here you can find a more advanced examples of Datatables component.


Datatables with data from remote API

Live example

Datatables with data fetching from real online API.

        
            
            <div class="container">
              <div class="row">
                <div class="col-md-6 mx-auto">
                  <div class="md-form">
                    <input type="text" class="form-control" [(ngModel)]="searchText" (keyup)="searchItems()"
                          id="search-input"
                          mdbInput>
                    <label for="search-input">Search</label>
                  </div>
                </div>
                <table mdbTable #tableEl="mdbTable" stickyHeader="true" hover="true" striped="true" class="z-depth-1">
                  <thead class="sticky-top">
                  <tr>
                    <th *ngFor="let head of headElements; let i = index" [mdbTableSort]="elements"
                        [sortBy]="headElements[i]"
                        scope="col">{{ head | titlecase }}
                      <mdb-icon fas icon="sort"></mdb-icon>
                    </th>
                  </tr>
                  </thead>
                  <tbody #row>
                  <tr mdbTableCol (rowCreated)="onRowCreate($event)" (rowRemoved)="onRowRemove($event)"
                      *ngFor="let el of elements; let i = index">
                    <th *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i <  mdbTablePagination.lastItemIndex"
                        scope="row">{{ el.id }}
                    </th>
                    <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i <  mdbTablePagination.lastItemIndex"
                        class="red-text">{{ el.first }}
                    </td>
                    <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i <  mdbTablePagination.lastItemIndex">
                      {{ el.last }}
                    </td>
                    <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i <  mdbTablePagination.lastItemIndex">
                      {{ el.handle }}
                    </td>
                  </tr>
                  </tbody>
                  <tfoot class="grey lighten-5 w-100">
    
                  <tr>
                    <td colspan="4">
                      <mdb-table-pagination [tableEl]="tableEl" paginationAlign=""
                                            [searchDataSource]="elements"></mdb-table-pagination>
                    </td>
                  </tr>
                  </tfoot>
                </table>
              </div>
            </div>
          
        
    
        
            
            import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
            import { MdbTableDirective, MdbTablePaginationComponent } from "ng-uikit-pro-standard";
            import { HttpClient } from "@angular/common/http";
      
            @Component({
              selector: 'remote-tables',
              templateUrl: './remote-tables.component.html',
              styleUrls: ['./remote-tables.component.scss']
            })
            export class RemoteTables implements OnInit, AfterViewInit {
              @ViewChild(MdbTableDirective, { static: true }) mdbTable: MdbTableDirective;
              @ViewChild(MdbTablePaginationComponent, { static: true }) mdbTablePagination: MdbTablePaginationComponent;
              @ViewChild('row', { static: true }) row: ElementRef;
      
              elements: any = [];
              headElements = ['id', 'first', 'last', 'handle'];
      
              searchText: string = '';
              previous: string;
      
              maxVisibleItems: number = 5;
      
              url = 'https://jsonplaceholder.typicode.com/posts';
      
              constructor(private cdRef: ChangeDetectorRef, private http: HttpClient) { }
      
              @HostListener('input') oninput() {
                this.mdbTablePagination.searchText = this.searchText;
              }
      
              ngOnInit() {
                this.http.get(this.url).subscribe((data: any) => {
                  data.forEach((el: any) => {
                    this.elements.push({
                      id: el.id.toString(),
                      first: el.title,
                      last: el.body,
                      handle: 'Handle ' + el.id.toString()
                    });
                  });
                  this.mdbTable.setDataSource(this.elements);
                });

                this.elements = this.mdbTable.getDataSource();
                this.previous = this.mdbTable.getDataSource();
              }
      
              ngAfterViewInit() {
                this.mdbTablePagination.setMaxVisibleItemsNumberTo(this.maxVisibleItems);
        
                this.mdbTablePagination.calculateFirstItemIndex();
                this.mdbTablePagination.calculateLastItemIndex();
        
                this.cdRef.detectChanges();
              }
      
              searchItems() {
                const prev = this.mdbTable.getDataSource();
        
                if (!this.searchText) {
                  this.mdbTable.setDataSource(this.previous);
                  this.elements = this.mdbTable.getDataSource();
                }
        
                if (this.searchText) {
                  this.elements = this.mdbTable.searchLocalDataBy(this.searchText);
                  this.mdbTable.setDataSource(prev);
                }
      
                this.mdbTablePagination.calculateFirstItemIndex();
                this.mdbTablePagination.calculateLastItemIndex();
        
                this.mdbTable.searchDataObservable(this.searchText).subscribe(() => {
                  this.mdbTablePagination.calculateFirstItemIndex();
                  this.mdbTablePagination.calculateLastItemIndex();
                });
              }
            }
          
        
    

Datatable with dynamic modal edit

Live example

Combine Datatables with dynamic modal to create a table which will be able to edit rows with modals.

You can read more about dynamic modals here.

For proper working of below example you have to import FormsModule, ReactiveFormsModule to the app.module.ts file, and add there a entryComponents: [ModalEditComponent].

        
            
          <div class="container">
            <div class="row">
              <table mdbTable #tableEl="mdbTable" stickyHeader="true" hover="true" striped="true" class="z-depth-1">
                <thead class="sticky-top">
                <tr>
                  <th *ngFor="let head of headElements; let i = index" [mdbTableSort]="elements"
                      [sortBy]="headElements[i]"
                      scope="col">{{ head | titlecase }}
                    <mdb-icon fas icon="sort"></mdb-icon>
                  </th>
                </tr>
                </thead>
                <tbody #row>
                <tr *ngFor="let el of elements; let i = index">
                  <th *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex"
                      scope="row">{{ el.id }}
                  </th>
                  <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex">
                    {{ el.first }}
                  </td>
                  <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex">
                    {{ el.last }}
                  </td>
                  <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex">
                    {{ el.handle }}
                  </td>
                  <td *ngIf="i+1 >= mdbTablePagination.firstItemIndex && i < mdbTablePagination.lastItemIndex">
                    <button mdbBtn color="warning" size="sm" mdbWavesEffect (click)="editRow(el)">Edit</button>
                    <button mdbBtn color="danger" size="sm" mdbWavesEffect (click)="removeRow(el)">Remove</button>
                  </td>
                </tr>
                </tbody>
                <tfoot class="grey lighten-5 w-100">
                <tr>
                  <td colspan="5">
                    <mdb-table-pagination [tableEl]="tableEl" paginationAlign=""
                                          [searchDataSource]="elements"></mdb-table-pagination>
                  </td>
                </tr>
                </tfoot>
              </table>
            </div>
          </div>
        
        
    
        
            
          import {ChangeDetectorRef, Component, ElementRef, ViewChild} from '@angular/core';
          import {MdbTableDirective, MdbTablePaginationComponent} from "path-to-mdb-angular";
          import {MDBModalRef, MDBModalService} from "path-to-mdb-angular";
          import {ModalEditComponent} from "./modal-edit/modal-edit.component";

          @Component({
            selector: 'app-root',
            templateUrl: './dynamic-modal-table.component.html',
            styleUrls: ['./dynamic-modal-table.component.scss']
          })
          export class DynamicModalTableComponent {
            @ViewChild(MdbTableDirective, { static: true }) mdbTable: MdbTableDirective;
            @ViewChild(MdbTablePaginationComponent, { static: true }) mdbTablePagination: MdbTablePaginationComponent;
            @ViewChild('row', { static: true }) row: ElementRef;

            elements: any = [];
            headElements = ['id', 'first', 'last', 'handle', 'command'];

            modalRef: MDBModalRef;

            constructor(
            private cdRef: ChangeDetectorRef,
            private modalService: MDBModalService) { }

            ngOnInit() {
              for (let i = 1; i <= 25; i++) {
                this.elements.push({id: i.toString(), first: 'User ' + i, last: 'Last ' + i, handle: 'Handle ' + i});
              }

              this.mdbTable.setDataSource(this.elements);
              this.elements = this.mdbTable.getDataSource();
            }

            ngAfterViewInit() {
              this.mdbTablePagination.setMaxVisibleItemsNumberTo(8);

              this.mdbTablePagination.calculateFirstItemIndex();
              this.mdbTablePagination.calculateLastItemIndex();
              this.cdRef.detectChanges();
            }

            editRow(el: any) {
              const elementIndex = this.elements.findIndex((elem: any) => el === elem);
              const modalOptions = {
                data: {
                  editableRow: el
                }
              };
              this.modalRef = this.modalService.show(ModalEditComponent, modalOptions);
              this.modalRef.content.saveButtonClicked.subscribe((newElement: any) => {
                this.elements[elementIndex] = newElement;
              });
              this.mdbTable.setDataSource(this.elements);
            }

            removeRow(el: any) {
              const elementIndex = this.elements.findIndex((elem: any) => el === elem);
              this.mdbTable.removeRow(elementIndex);
              this.mdbTable.getDataSource().forEach((el: any, index: any) => {
                el.id = (index + 1).toString();
              });
              this.mdbTable.setDataSource(this.elements);
            }
          }
        
        
    
        
            
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
                  <span aria-hidden="true">×</span>
                </button>
                <h4 class="modal-title w-100" id="myModalLabel">Edit user: {{ editableRow.first }}</h4>
              </div>
              <div class="modal-body">
                <form [formGroup]="form">
                  <div class="md-form">
                    <input id="id" type="text" class="form-control grey-text" formControlName="id" mdbInput>
                    <label for="id">ID</label>
                  </div>
                  <div class="md-form">
                    <input id="first" type="text" class="form-control" formControlName="first" mdbInput mdbValidate
                          [validateSuccess]="false">
                    <label for="first">First</label>
                    <mdb-error *ngIf="first.invalid && (first.dirty || first.touched)">Input is required</mdb-error>
                  </div>
                  <div class="md-form">
                    <input id="last" type="text" class="form-control" formControlName="last" mdbInput mdbValidate
                          [validateSuccess]="false">
                    <label for="last">Last</label>
                    <mdb-error *ngIf="last.invalid && (last.dirty || last.touched)">Input is required</mdb-error>
                  </div>
                  <div class="md-form">
                    <input id="handle" type="text" class="form-control" formControlName="handle" mdbInput mdbValidate
                          [validateSuccess]="false">
                    <label for="handle">Handle</label>
                    <mdb-error *ngIf="handle.invalid && (handle.dirty || handle.touched)">Input is required</mdb-error>
                  </div>
                </form>
              </div>
              <div class="modal-footer">
                <button type="button" mdbBtn color="secondary" class="waves-light" aria-label="Close"
                        (click)="modalRef.hide()" mdbWavesEffect>Close
                </button>
                <button type="button" mdbBtn color="primary" class="relative waves-light" mdbWavesEffect
                        [disabled]="form.invalid" (click)="editRow()">Save!
                </button>
              </div>
            </div>
          
        
    
        
            
            import {Component} from '@angular/core';
            import {MDBModalRef} from "path-to-mdb-angular";
            import {FormControl, FormGroup, Validators} from "@angular/forms";
            import {Subject} from "rxjs";
  
            @Component({
              selector: 'app-modal-edit',
              templateUrl: './modal-edit.component.html',
              styleUrls: ['./modal-edit.component.scss']
            })
            export class ModalEditComponent {
  
              public editableRow: { id: string, first: string, last: string, handle: string };
              public saveButtonClicked: Subject&lt;any&gt; = new Subject&lt;any&gt;();
  
              public form: FormGroup = new FormGroup({
                id: new FormControl({value: '', disabled: true}),
                first: new FormControl('', Validators.required),
                last: new FormControl('', Validators.required),
                handle: new FormControl('', Validators.required)
              });
  
              constructor(public modalRef: MDBModalRef) { }
  
              ngOnInit() {
                this.form.controls['id'].patchValue(this.editableRow.id);
                this.form.controls['first'].patchValue(this.editableRow.first);
                this.form.controls['last'].patchValue(this.editableRow.last);
                this.form.controls['handle'].patchValue(this.editableRow.handle);
              }
  
              editRow() {
                this.editableRow = this.form.getRawValue();
                this.saveButtonClicked.next(this.editableRow);
                this.modalRef.hide();
              }
  
              get first() { 
                return this.form.get('first');
              }
  
              get last() { 
                return this.form.get('last');
              }
  
              get handle() {
                return this.form.get('handle');
              }
            }
          
        
    

Master Detail Table

Live example

Create and additional row and use the ngIf directive to display it when the certain condition is met.

        
            
          <div class="container">
            <div class="row">
              <table mdbTable striped="true">
                <thead>
                  <tr>
                    <th *ngFor="let head of headElements" scope="col">{{ head }}</th>
                  </tr>
                </thead>
                <tbody mdbTableCol *ngFor="let el of elements">
                  <tr>
                    <td scope="row">
                      <button
                        type="button"
                        mdbBtn
                        color="danger"
                        class="master-button"
                        mdbWavesEffect
                        *ngIf="el.collapsed"
                        (click)="el.collapsed = !el.collapsed"
                      >
                        <mdb-icon fas icon="angle-down"></mdb-icon>
                      </button>
                      <button
                        type="button"
                        mdbBtn
                        color="success"
                        class="master-button"
                        mdbWavesEffect
                        *ngIf="!el.collapsed"
                        (click)="el.collapsed = !el.collapsed"
                      >
                        <mdb-icon fas icon="angle-right"></mdb-icon>
                      </button>
                      <span class="ml-1">{{ el.id }}</span>
                    </td>
                    <td>{{ el.first }}</td>
                    <td>{{ el.last }}</td>
                    <td>{{ el.handle }}</td>
                  </tr>
                  <tr
                    *ngIf="el.collapsed"
                    style="text-align: center; background-color: rgba(0, 0, 0,  0.015)"
                  >
                    <td colspan="100%" style="border: 0 !important">
                      <table mdbTable>
                        <thead class="black white-text">
                          <tr>
                            <th *ngFor="let head of masterHeadElements" scope="col">{{ head }}</th>
                          </tr>
                        </thead>
                        <tbody *ngFor="let detail of el.masterDetail">
                          <tr>
                            <td>{{ detail.orderId }}</td>
                            <td>{{ detail.orderDate }}</td>
                            <td>{{ detail.adress }}</td>
                          </tr>
                        </tbody>
                      </table>
                    </td>
                  </tr>
                </tbody>
              </table>
        
            </div>
          </div>
        
        
    
        
            
          import { Component } from '@angular/core';
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
            styleUrls: ['./app.component.scss'],
          })
          export class AppComponent {
            elements: any = [
              {
                id: 1,
                first: 'Mark',
                last: 'Otto',
                handle: '@mdo',
                collapsed: true,
                masterDetail: [{ orderId: 1, orderDate: '24-07-1996', adress: '35 King George' }],
              },
              {
                id: 2,
                first: 'Jacob',
                last: 'Thornton',
                handle: '@fat',
                collapsed: false,
                masterDetail: [{ orderId: 2, orderDate: '04-01-1992', adress: 'Obere Str. 57' }],
              },
              {
                id: 3,
                first: 'Larry',
                last: 'the Bird',
                handle: '@twitter',
                collapsed: false,
                masterDetail: [{ orderId: 3, orderDate: '15-01-1994', adress: 'Kirchgasse 6' }],
              },
            ];
          
            headElements = ['ID', 'First', 'Last', 'Handle'];
            masterHeadElements = ['Order Id', 'Order Date', 'Adress'];
          }
        
        
    
        
            
          .master-button {
            padding: 0.25rem 0.7rem !important;
            font-size: 0.9rem !important;
          }