Table editor

Angular Bootstrap 5 Table editor plugin

Table Editor is a useful tool for displaying and managing data. The component works similarly to the Datatable (docs) with an additional column for action buttons.

Responsive interactive built with Bootstrap 5, Angular and Material Design. Creates editable tables. Delete or edit rows directly or via modal editor.

Note: Examples use additional components such as Datatables, Modal, Alerts and Popconfirm. Remember to import them.


Basic example


Company Address Employees
Smith & Johnson Park Lane 2, London 30
P.J. Company Oak Street 7, Aberdeen 80
Food & Wine Netherhall Gardens 3, Hampstead 12
IT Service Warwick Road 14, London 17
A. Jonson Gallery Oaklands Avenue 2, London 4
F.A. Architects Frognal Way 7, Hampstead 4
        
            
          <div class="d-flex justify-content-end mb-4">
            <mdb-form-control>
              <input
                mdbInput
                type="text"
                class="form-control"
                id="search-input"
                [disabled]="addRow || editElementIndex !== -1"
                (keyup)="search($event)"
              />
              <label mdbLabel class="form-label" for="search-input">Search</label>
            </mdb-form-control>
            <button
              mdbRipple
              class="btn btn-primary btn-sm ms-3"
              [disabled]="addRow || editElementIndex !== -1"
              (click)="addRow = true"
            >
              <i class="fa fa-plus"></i>
            </button>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{ 'edited-table': addRow || editElementIndex !== -1 }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
              [pagination]="pagination"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr
                  *ngIf="addRow"
                  [ngClass]="{ 'edited-row': addRow }"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.address"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="number"
                        class="form-control"
                        [(ngModel)]="newRow.employees"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{ 'edited-row': editElementIndex === index }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.address }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.address"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.employees }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="number"
                          class="form-control"
                          [(ngModel)]="data.employees"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="onEditClick(index)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        (click)="onDeleteClick(data)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="onDiscardEdit(index)"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
            <mdb-table-pagination
              #pagination
              [entries]="5"
              [disabled]="addRow || editElementIndex !== -1"
            ></mdb-table-pagination>
          </div>          
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          
          export interface Person {
            company: string;
            address: string;
            employees: number | null;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            editElementIndex = -1;
            addRow = false;
          
            newRow: Person = {
              company: '',
              address: '',
              employees: null,
            };
          
            editRow: Person = {
              company: '',
              address: '',
              employees: null,
            };
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Address', field: 'address', disableSort: true },
              { label: 'Employees', field: 'employees', disableSort: true },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                address: 'Park Lane 2, London',
                employees: 30,
              },
              {
                company: 'P.J. Company',
                address: 'Oak Street 7, Aberdeen',
                employees: 80,
              },
              {
                company: 'Food & Wine',
                address: 'Netherhall Gardens 3, Hampstead',
                employees: 12,
              },
              {
                company: 'IT Service',
                address: 'Warwick Road 14, London',
                employees: 17,
              },
              {
                company: 'A. Jonson Gallery',
                address: 'Oaklands Avenue 2, London',
                employees: 4,
              },
              {
                company: 'F.A. Architects',
                address: 'Frognal Way 7, Hampsteadn',
                employees: 4,
              },
            ];
          
            constructor() {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow(): void {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.newRow.company = '';
              this.newRow.address = '';
              this.newRow.employees = null;
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.address = '';
              this.newRow.employees = null;
              this.addRow = false;
            }
          
            onEditClick(index: number): void {
              this.editElementIndex = index;
              this.editRow = { ...this.table.data[index] };
            }
          
            onDiscardEdit(index: number): void {
              this.editElementIndex = -1;
              this.table.data[index] = { ...this.editRow };
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          }          
          
        
    

Modal

Note: This example use Modal. Remember to import them.

        
            
          <div class="d-flex justify-content-end mb-4">
            <mdb-form-control>
              <input
                mdbInput
                type="text"
                class="form-control"
                id="search-input"
                (keyup)="search($event)"
              />
              <label mdbLabel class="form-label" for="search-input">Search</label>
            </mdb-form-control>
            <button
              mdbRipple
              class="btn btn-primary btn-sm ms-3"
              (click)="openModal('add')"
            >
              <i class="fa fa-plus"></i>
            </button>
          </div>
          <hr />
          <div class="datatable table-editor mt-4">
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
              [pagination]="pagination"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr *ngFor="let data of table.data; let index = index" scope="row">
                  <td style="min-width: 250px; max-width: 250px">
                    {{ data.company }}
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    {{ data.office }}
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    {{ data.employees }}
                  </td>
                  <td style="min-width: 100px; max-width: 100px">
                    {{ data.international }}
                  </td>
          
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                      (click)="openModal('edit', data)"
                    >
                      <i class="far fa-edit"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                      (click)="onDeleteClick(data)"
                    >
                      <i class="far fa-trash-alt"></i>
                    </button>
                  </td>
                </tr>
              </tbody>
            </table>
            <mdb-table-pagination #pagination [entries]="5"></mdb-table-pagination>
          </div>         
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import { MdbModalRef, MdbModalService } from 'mdb-angular-ui-kit/modal';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          import { ModalComponent } from './modal.component';
          
          export interface Person {
            company: string;
            office: string;
            employees: number | null;
            international: boolean;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            modalRef: MdbModalRef<ModalComponent> | null = null;
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Office', field: 'office', disableSort: true },
              { label: 'Employees', field: 'employees', disableSort: false },
              { label: 'International', field: 'international', disableSort: false },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                office: 'London',
                employees: 30,
                international: true,
              },
              {
                company: 'P.J. Company',
                office: 'London',
                employees: 80,
                international: false,
              },
              {
                company: 'Food & Wine',
                office: 'London',
                employees: 12,
                international: false,
              },
              {
                company: 'IT Service',
                office: 'London',
                employees: 17,
                international: false,
              },
              {
                company: 'A. Jonson Gallery',
                office: 'London',
                employees: 4,
                international: false,
              },
              {
                company: 'F.A. Architects',
                office: 'London',
                employees: 4,
                international: false,
              },
            ];
          
            constructor(private modalService: MdbModalService) {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            openModal(mode: 'add' | 'edit', data?: Person): void {
              this.modalRef = this.modalService.open(ModalComponent, {
                data: {
                  modalTitle: mode === 'edit' ? 'Edit item' : 'New item',
                  company: data ? data.company : '',
                  office: data ? data.office : 'Warsaw',
                  employees: data ? data.employees : 1,
                  international: data ? data.international : false,
                },
                ignoreBackdropClick: true,
              });
              this.modalRef.onClose.subscribe((modalData: Person) => {
                if (!modalData) {
                  return;
                }
                if (mode === 'add') {
                  this.dataSource = [...this.dataSource, { ...modalData }];
                } else if (mode === 'edit' && data) {
                  const index = this.dataSource.indexOf(data);
                  this.dataSource[index] = modalData;
                  this.dataSource = [...this.dataSource];
                }
              });
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          }          
          
        
    
        
            
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">{{ modalTitle }}</h5>
          </div>
          <div class="modal-body">
            <div class="my-4 table-editor_input-wrapper">
              <mdb-form-control>
                <input
                  mdbInput
                  type="text"
                  id="company-input"
                  class="form-control"
                  [(ngModel)]="company"
                />
                <label mdbLabel class="form-label" for="company-input">Company</label>
              </mdb-form-control>
            </div>
            <div class="my-4 table-editor_input-wrapper">
              <mdb-form-control>
                <mdb-select [(ngModel)]="office">
                  <mdb-option *ngFor="let option of options" [value]="option.value">{{
                    option.label
                  }}</mdb-option>
                </mdb-select>
                <label mdbLabel class="form-label">Office</label>
              </mdb-form-control>
            </div>
            <div class="my-4 table-editor_input-wrapper">
              <mdb-form-control>
                <input
                  mdbInput
                  type="number"
                  id="employees-input"
                  class="form-control"
                  [(ngModel)]="employees"
                />
                <label mdbLabel class="form-label" for="employees-input">Employees</label>
              </mdb-form-control>
            </div>
            <div class="my-4 table-editor_input-wrapper">
              <div class="form-check ms-1 mt-1">
                <input
                  mdbCheckbox
                  class="form-check-input"
                  type="checkbox"
                  value=""
                  id="international-checkbox"
                  [(ngModel)]="international"
                />
                <label class="form-check-label" for="flexCheckDefault">
                  International
                </label>
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button
              type="button"
              class="shadow-0 btn btn-md btn-outline-primary"
              (click)="modalRef.close()"
            >
              Cancel
            </button>
            <button
              type="button"
              class="shadow-0 btn btn-md btn-primary"
              (click)="saveData()"
            >
              Save
            </button>
          </div>          
          
        
    
        
            
          import { Component } from '@angular/core';
          import { MdbModalRef } from 'mdb-angular-ui-kit/modal';
          
          @Component({
            selector: 'app-modal',
            templateUrl: './modal.component.html',
          })
          export class ModalComponent {
            modalTitle: string | null = null;
            company: string | null = null;
            office: string | null = null;
            employees: string | null = null;
            international: string | null = null;
          
            options = [
              { value: 'London', label: 'London' },
              { value: 'Warsaw', label: 'Warsaw' },
              { value: 'New York', label: 'New York' },
            ];
          
            constructor(public modalRef: MdbModalRef<ModalComponent>) {}
          
            saveData(): void {
              const closeMessage = {
                company: this.company,
                office: this.office,
                employees: this.employees,
                international: this.international,
              };
          
              this.modalRef.close(closeMessage);
            }
          }          
          
        
    

Inputs example

        
            
          <div class="d-flex justify-content-end mb-4">
            <mdb-form-control>
              <input
                mdbInput
                type="text"
                class="form-control"
                id="search-input"
                [disabled]="addRow || editElementIndex !== -1"
                (keyup)="search($event)"
              />
              <label mdbLabel class="form-label" for="search-input">Search</label>
            </mdb-form-control>
            <button
              mdbRipple
              class="btn btn-primary btn-sm ms-3"
              [disabled]="addRow || editElementIndex !== -1"
              (click)="addRow = true"
            >
              <i class="fa fa-plus"></i>
            </button>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{
              'edited-table': addRow || editElementIndex !== -1
            }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
              [pagination]="pagination"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr
                  *ngIf="addRow"
                  [ngClass]="{ 'edited-row': addRow }"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <mdb-select [(ngModel)]="newRow.office">
                        <mdb-option
                          *ngFor="let option of options"
                          [value]="option.value"
                          >{{ option.label }}</mdb-option
                        >
                      </mdb-select>
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="number"
                        class="form-control"
                        [(ngModel)]="newRow.employees"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <div class="form-check ms-1 mt-1">
                      <input
                        mdbCheckbox
                        class="form-check-input"
                        type="checkbox"
                        [(ngModel)]="newRow.international"
                      />
                    </div>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{ 'edited-row': editElementIndex === index }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.office }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <mdb-select [(ngModel)]="data.office">
                          <mdb-option
                            *ngFor="let option of options"
                            [value]="option.value"
                            >{{ option.label }}</mdb-option
                          >
                        </mdb-select>
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.employees }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="number"
                          class="form-control"
                          [(ngModel)]="data.employees"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.international }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <div class="form-check ms-1 mt-1">
                        <input
                          mdbCheckbox
                          class="form-check-input"
                          type="checkbox"
                          [(ngModel)]="data.international"
                        />
                      </div>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="onEditClick(index)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        (click)="onDeleteClick(data)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="onDiscardEdit(index)"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
            <mdb-table-pagination
              #pagination
              [entries]="5"
              [disabled]="addRow || editElementIndex !== -1"
            ></mdb-table-pagination>
          </div>          
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          
          export interface Person {
            company: string;
            office: string;
            employees: number | null;
            international: boolean;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            editElementIndex = -1;
            addRow = false;
          
            newRow: Person = {
              company: '',
              office: 'Warsaw',
              employees: 1,
              international: false,
            };
          
            editRow: Person = {
              company: '',
              office: '',
              employees: null,
              international: false,
            };
          
            options = [
              { value: 'London', label: 'London' },
              { value: 'Warsaw', label: 'Warsaw' },
              { value: 'New York', label: 'New York' },
            ];
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Office', field: 'office', disableSort: true },
              { label: 'Employees', field: 'employees', disableSort: false },
              { label: 'International', field: 'international', disableSort: false },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                office: 'London',
                employees: 30,
                international: true,
              },
              {
                company: 'P.J. Company',
                office: 'London',
                employees: 80,
                international: false,
              },
              {
                company: 'Food & Wine',
                office: 'London',
                employees: 12,
                international: false,
              },
              {
                company: 'IT Service',
                office: 'London',
                employees: 17,
                international: false,
              },
              {
                company: 'A. Jonson Gallery',
                office: 'London',
                employees: 4,
                international: false,
              },
              {
                company: 'F.A. Architects',
                office: 'London',
                employees: 4,
                international: false,
              },
            ];
          
            constructor() {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow(): void {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            onEditClick(index: number): void {
              this.editElementIndex = index;
              this.editRow = { ...this.table.data[index] };
            }
          
            onDiscardEdit(index: number): void {
              this.editElementIndex = -1;
              this.table.data[index] = { ...this.editRow };
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          }          
          
        
    

Disable edit

        
            
          <div class="d-flex justify-content-end mb-4">
            <mdb-form-control>
              <input
                mdbInput
                type="text"
                class="form-control"
                id="search-input"
                [disabled]="addRow || editElementIndex !== -1"
                (keyup)="search($event)"
              />
              <label mdbLabel class="form-label" for="search-input">Search</label>
            </mdb-form-control>
            <button
              mdbRipple
              class="btn btn-primary btn-sm ms-3"
              [disabled]="addRow || editElementIndex !== -1"
              (click)="addRow = true"
            >
              <i class="fa fa-plus"></i>
            </button>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{
              'edited-table': addRow || editElementIndex !== -1
            }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
              [pagination]="pagination"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr
                  *ngIf="addRow"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                  [ngClass]="{ 'edited-row': addRow }"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                        disabled
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <mdb-select [(ngModel)]="newRow.office" disabled>
                        <mdb-option
                          *ngFor="let option of options"
                          [value]="option.value"
                          >{{ option.label }}</mdb-option
                        >
                      </mdb-select>
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="number"
                        class="form-control"
                        [(ngModel)]="newRow.employees"
                        disabled
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <div class="form-check ms-1 mt-1">
                      <input
                        mdbCheckbox
                        class="form-check-input"
                        type="checkbox"
                        [(ngModel)]="newRow.international"
                        disabled
                      />
                    </div>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{
                    'edited-row': editElementIndex === index
                  }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                          disabled
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.office }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <mdb-select [(ngModel)]="data.office" [disabled]="true">
                          <mdb-option
                            *ngFor="let option of options"
                            [value]="option.value"
                            >{{ option.label }}</mdb-option
                          >
                        </mdb-select>
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.employees }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="number"
                          class="form-control"
                          [(ngModel)]="data.employees"
                          disabled
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.international }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <div class="form-check ms-1 mt-1">
                        <input
                          mdbCheckbox
                          class="form-check-input"
                          type="checkbox"
                          [(ngModel)]="data.international"
                          disabled
                        />
                      </div>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="editElementIndex = index"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        (click)="onDeleteClick(data)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
            <mdb-table-pagination
              #pagination
              [entries]="5"
              [disabled]="addRow || editElementIndex !== -1"
            ></mdb-table-pagination>
          </div>          
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          
          export interface Person {
            company: string;
            office: string;
            employees: number | null;
            international: boolean;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            editElementIndex = -1;
            addRow = false;
          
            newRow: Person = {
              company: '',
              office: 'Warsaw',
              employees: 1,
              international: false,
            };
          
            options = [
              { value: 'London', label: 'London' },
              { value: 'Warsaw', label: 'Warsaw' },
              { value: 'New York', label: 'New York' },
            ];
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Office', field: 'office', disableSort: true },
              { label: 'Employees', field: 'employees', disableSort: false },
              { label: 'International', field: 'international', disableSort: false },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                office: 'London',
                employees: 30,
                international: true,
              },
              {
                company: 'P.J. Company',
                office: 'London',
                employees: 80,
                international: false,
              },
              {
                company: 'Food & Wine',
                office: 'London',
                employees: 12,
                international: false,
              },
              {
                company: 'IT Service',
                office: 'London',
                employees: 17,
                international: false,
              },
              {
                company: 'A. Jonson Gallery',
                office: 'London',
                employees: 4,
                international: false,
              },
              {
                company: 'F.A. Architects',
                office: 'London',
                employees: 4,
                international: false,
              },
            ];
          
            constructor() {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow(): void {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          }          
          
        
    

Confirm delete

Note: This example use Popconfirm. Remember to import them.

        
            
          <div class="d-flex justify-content-end mb-4">
            <mdb-form-control>
              <input
                mdbInput
                type="text"
                class="form-control"
                id="search-input"
                [disabled]="addRow || editElementIndex !== -1"
                (keyup)="search($event)"
              />
              <label mdbLabel class="form-label" for="search-input">Search</label>
            </mdb-form-control>
            <button
              mdbRipple
              class="btn btn-primary btn-sm ms-3"
              [disabled]="addRow || editElementIndex !== -1"
              (click)="addRow = true"
            >
              <i class="fa fa-plus"></i>
            </button>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{
              'edited-table': addRow || editElementIndex !== -1
            }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
              [pagination]="pagination"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr
                  *ngIf="addRow"
                  [ngClass]="{ 'edited-row': addRow }"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <mdb-select [(ngModel)]="newRow.office">
                        <mdb-option
                          *ngFor="let option of options"
                          [value]="option.value"
                          >{{ option.label }}</mdb-option
                        >
                      </mdb-select>
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="number"
                        class="form-control"
                        [(ngModel)]="newRow.employees"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <div class="form-check ms-1 mt-1">
                      <input
                        mdbCheckbox
                        class="form-check-input"
                        type="checkbox"
                        [(ngModel)]="newRow.international"
                      />
                    </div>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{ 'edited-row': editElementIndex === index }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.office }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <mdb-select [(ngModel)]="data.office">
                          <mdb-option
                            *ngFor="let option of options"
                            [value]="option.value"
                            >{{ option.label }}</mdb-option
                          >
                        </mdb-select>
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.employees }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="number"
                          class="form-control"
                          [(ngModel)]="data.employees"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.international }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <div class="form-check ms-1 mt-1">
                        <input
                          mdbCheckbox
                          class="form-check-input"
                          type="checkbox"
                          [(ngModel)]="data.international"
                        />
                      </div>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="onEditClick(index)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        #target
                        (click)="openPopconfirm(target, data)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="onDiscardEdit(index)"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
            <mdb-table-pagination
              #pagination
              [entries]="5"
              [disabled]="addRow || editElementIndex !== -1"
            ></mdb-table-pagination>
          </div>          
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import {
            MdbPopconfirmRef,
            MdbPopconfirmService,
          } from 'mdb-angular-ui-kit/popconfirm';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          import { PopconfirmComponent } from './popconfirm.component';
          
          export interface Person {
            company: string;
            office: string;
            employees: number | null;
            international: boolean;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            popconfirmRef: MdbPopconfirmRef<PopconfirmComponent> | null = null;
            editElementIndex = -1;
            addRow = false;
          
            newRow: Person = {
              company: '',
              office: 'Warsaw',
              employees: 1,
              international: false,
            };
          
            editRow: Person = {
              company: '',
              office: '',
              employees: null,
              international: false,
            };
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Office', field: 'office', disableSort: true },
              { label: 'Employees', field: 'employees', disableSort: false },
              { label: 'International', field: 'international', disableSort: false },
            ];
          
            options = [
              { value: 'London', label: 'London' },
              { value: 'Warsaw', label: 'Warsaw' },
              { value: 'New York', label: 'New York' },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                office: 'London',
                employees: 30,
                international: true,
              },
              {
                company: 'P.J. Company',
                office: 'London',
                employees: 80,
                international: false,
              },
              {
                company: 'Food & Wine',
                office: 'London',
                employees: 12,
                international: false,
              },
              {
                company: 'IT Service',
                office: 'London',
                employees: 17,
                international: false,
              },
              {
                company: 'A. Jonson Gallery',
                office: 'London',
                employees: 4,
                international: false,
              },
              {
                company: 'F.A. Architects',
                office: 'London',
                employees: 4,
                international: false,
              },
            ];
          
            constructor(private popconfirmService: MdbPopconfirmService) {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow() {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            onEditClick(index: number): void {
              this.editElementIndex = index;
              this.editRow = { ...this.table.data[index] };
            }
          
            onDiscardEdit(index: number): void {
              this.editElementIndex = -1;
              this.table.data[index] = { ...this.editRow };
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          
            openPopconfirm(target: HTMLElement, data: Person): void {
              this.popconfirmRef = this.popconfirmService.open(
                PopconfirmComponent,
                target,
                { data: { data: data } }
              );
              this.popconfirmRef.onClose.subscribe(() => {
                this.editElementIndex = -1;
              });
              this.popconfirmRef.onConfirm.subscribe((data) => {
                this.onDeleteClick(data);
              });
            }
          }          
          
        
    
        
            
          <div class="popconfirm-popover shadow-4">
            <div class="popconfirm">
              <p class="popconfirm-message">
                <span class="popconfirm-message-text"
                  >Are you sure you want to delete this entry?</span
                >
              </p>
              <div class="popconfirm-buttons-container">
                <button
                  (click)="popconfirmRef.close()"
                  type="button"
                  aria-label="Cancel"
                  class="btn btn-flat btn-sm"
                >
                  Cancel
                </button>
                <button
                  (click)="popconfirmRef.confirm(data)"
                  type="button"
                  aria-label="Confirm"
                  class="btn btn-primary btn-sm"
                >
                  Delete
                </button>
              </div>
            </div>
          </div>          
          
        
    
        
            
          import { Component, OnInit } from '@angular/core';
          import { MdbPopconfirmRef } from 'mdb-angular-ui-kit/popconfirm';
          
          @Component({
            selector: 'app-popconfirm',
            templateUrl: './popconfirm.component.html',
          })
          export class PopconfirmComponent implements OnInit {
            data: any = null;
          
            constructor(public popconfirmRef: MdbPopconfirmRef<PopconfirmComponent>) {}
          
            ngOnInit(): void {}
          }
          
          
        
    


Async data


        
            
          <div class="d-flex justify-content-between mb-4">
            <button class="btn btn-primary btn-sm" (click)="loadData()">Load data</button>
            <div class="d-flex">
              <mdb-form-control>
                <input
                  mdbInput
                  type="text"
                  class="form-control"
                  id="search-input"
                  [disabled]="addRow || editElementIndex !== -1 || loading"
                  (keyup)="search($event)"
                />
                <label mdbLabel class="form-label" for="search-input">Search</label>
              </mdb-form-control>
              <button
                mdbRipple
                class="btn btn-primary btn-sm ms-3"
                [disabled]="addRow || editElementIndex !== -1 || loading"
                (click)="addRow = true"
              >
                <i class="fa fa-plus"></i>
              </button>
            </div>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{
              'edited-table': addRow || editElementIndex !== -1
            }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [pagination]="pagination"
              [sort]="sort"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body" *ngIf="!loading">
                <tr
                  *ngIf="addRow"
                  [ngClass]="{ 'edited-row': addRow }"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.email"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.name"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.phone"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{ 'edited-row': editElementIndex === index }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.email }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.email"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.name }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.name"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.phone }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.phone"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="onEditClick(index)"
                        [disabled]="editElementIndex !== -1 && editElementIndex !== index"
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        (click)="onDeleteClick(data)"
                        [disabled]="editElementIndex !== -1 && editElementIndex !== index"
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="onDiscardEdit(index)"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
            <ng-container *ngIf="loading">
              <div class="datatable-loader bg-light">
                <span class="datatable-loader-inner">
                  <span class="datatable-progress bg-primary"></span>
                </span>
              </div>
              <p class="text-center text-muted my-4">Loading results...</p>
            </ng-container>
            <mdb-table-pagination
              #pagination
              [entries]="10"
              [disabled]="addRow || editElementIndex !== -1 || loading"
            ></mdb-table-pagination>
          </div>          
          
        
    
        
            
          import { HttpClient } from '@angular/common/http';
          import { Component, ViewChild } from '@angular/core';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          import { tap, take } from 'rxjs/operators';
          
          interface Person {
            company: string;
            email: string;
            name: string;
            phone: string;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            dataUrl = 'https://jsonplaceholder.typicode.com/users';
            loading = true;
            editElementIndex = -1;
            addRow = false;
          
            newRow: Person = {
              company: '',
              email: '',
              name: '',
              phone: '',
            };
          
            editRow: Person = {
              company: '',
              email: '',
              name: '',
              phone: '',
            };
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Email', field: 'email', disableSort: false },
              { label: 'Name', field: 'name', disableSort: false },
              { label: 'Phone', field: 'phone', disableSort: false },
            ];
          
            dataSource: Person[] = [];
          
            constructor(private _http: HttpClient) {}

            loadData() {
              this.getData()
                .pipe(take(1))
                .subscribe((data: any[]) => {
                  const mappedData = data.map((entry) => {
                    return { ...entry, company: entry.company.name };
                  });
                  this.dataSource = mappedData;
                });
            }
          
            getData() {
              return this._http
                .get<any>(this.dataUrl)
                .pipe(tap(() => (this.loading = false)));
            }
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow(): void {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.newRow.company = '';
              this.newRow.email = '';
              this.newRow.name = '';
              this.newRow.phone = '';
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.email = '';
              this.newRow.name = '';
              this.newRow.phone = '';
              this.addRow = false;
            }
          
            onEditClick(index: number): void {
              this.editElementIndex = index;
              this.editRow.company = this.table.data[index].company;
              this.editRow.email = this.table.data[index].email;
              this.editRow.name = this.table.data[index].name;
              this.editRow.phone = this.table.data[index].phone;
            }
          
            onDiscardEdit(index: number): void {
              this.editElementIndex = -1;
              this.table.data[index].company = this.editRow.company;
              this.table.data[index].email = this.editRow.email;
              this.table.data[index].name = this.editRow.name;
              this.table.data[index].phone = this.editRow.phone;
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          }          
          
        
    

Custom rows

M.B.

(5 Avenue 26, New York)

Berkley & Clark

(43th Street 12, New York)

D&D Inc.

(14 Street 67, New York)

Thomas & Co.

(2 Avenue 54, New York)


        
            
          <div class="row">
            <div class="col-md-3 col-sm-6 p-3">
              <h4>M.B.</h4>
              <p>(5 Avenue 26, New York)</p>
              <button
                class="btn btn-primary btn-sm"
                (click)="loadMB()"
                [disabled]="mBLoaded || addRow"
              >
                {{ mBLoaded ? "Loaded" : "Load into table" }}
              </button>
            </div>
            <div class="col-md-3 col-sm-6 p-3">
              <h4>Berkley & Clark</h4>
              <p>(43th Street 12, New York)</p>
              <button
                class="btn btn-primary btn-sm"
                (click)="loadBarkleyAndClark()"
                [disabled]="barkleyAndClarkLoaded || addRow"
              >
                {{ barkleyAndClarkLoaded ? "Loaded" : "Load into table" }}
              </button>
            </div>
            <div class="col-md-3 col-sm-6 p-3">
              <h4>D&D Inc.</h4>
              <p>(14 Street 67, New York)</p>
              <button
                class="btn btn-primary btn-sm"
                (click)="loadDAndDInc()"
                [disabled]="dAndDIncLoaded || addRow"
              >
                {{ dAndDIncLoaded ? "Loaded" : "Load into table" }}
              </button>
            </div>
            <div class="col-md-3 col-sm-6 p-3">
              <h4>Thomas & Co.</h4>
              <p>(2 Avenue 54, New York)</p>
              <button
                class="btn btn-primary btn-sm"
                (click)="loadThomasAndCo()"
                [disabled]="thomasAndCoLoaded || addRow"
              >
                {{ thomasAndCoLoaded ? "Loaded" : "Load into table" }}
              </button>
            </div>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{
              'edited-table': addRow || editElementIndex !== -1
            }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr
                  *ngIf="addRow"
                  [ngClass]="{ 'edited-row': addRow }"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.address"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.city"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{ 'edited-row': editElementIndex === index }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.address }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.address"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.city }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.city"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="onEditClick(index)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        (click)="onDeleteClick(data)"
                        [disabled]="
                          addRow ||
                          (editElementIndex !== -1 && editElementIndex !== index)
                        "
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="editElementIndex = -1"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="onDiscardEdit(index)"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>                        
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          
          export interface Person {
            company: string;
            address: string;
            city: string;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            editElementIndex = -1;
            addRow = false;
            mBLoaded = false;
            barkleyAndClarkLoaded = false;
            dAndDIncLoaded = false;
            thomasAndCoLoaded = false;
          
            newRow: Person = {
              company: '',
              address: '',
              city: '',
            };
          
            editRow: Person = {
              company: '',
              address: '',
              city: '',
            };
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Address', field: 'address', disableSort: false },
              { label: 'City', field: 'city', disableSort: false },
            ];
          
            dataSource: Person[] = [
              { company: 'Smith & Johnson', address: 'Park Lane 2', city: 'London' },
              { company: 'P.J. Company', address: 'Oak Street 7', city: 'Aberdeen' },
              {
                company: 'Food & Wine',
                address: 'Netherhall Gardens 3',
                city: 'Hampstead',
              },
              { company: 'IT Service', address: 'Warwick Road 14', city: 'London' },
              {
                company: 'A. Jonson Gallery',
                address: 'Oaklands Avenue 2',
                city: 'London',
              },
              { company: 'F.A. Architects', address: 'Frognal Way 7', city: 'Hampstead' },
            ];
            constructor() {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow(): void {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.newRow.company = '';
              this.newRow.address = '';
              this.newRow.city = 'null';
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.address = '';
              this.newRow.city = 'null';
              this.addRow = false;
            }
          
            onEditClick(index: number): void {
              this.editElementIndex = index;
              this.editRow = { ...this.table.data[index] };
            }
          
            onDiscardEdit(index: number): void {
              this.editElementIndex = -1;
              this.table.data[index] = { ...this.editRow };
            }
          
            onDeleteClick(data: Person) {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          
            loadMB(): void {
              const row = {
                company: 'M.B.',
                address: '5 Avenue 26',
                city: 'New York',
              };
              this.mBLoaded = true;
              this.addRow = true;
              this.newRow = row;
            }
          
            loadBarkleyAndClark(): void {
              const row = {
                company: 'Berkley & Clark',
                address: '43th Street 12',
                city: 'New York',
              };
              this.barkleyAndClarkLoaded = true;
              this.addRow = true;
              this.newRow = row;
            }
          
            loadDAndDInc(): void {
              const row = {
                company: 'D&D Inc.',
                address: '14 Street 67',
                city: 'New York',
              };
              this.dAndDIncLoaded = true;
              this.addRow = true;
              this.newRow = row;
            }
          
            loadThomasAndCo(): void {
              const row = {
                company: 'Thomas & Co.',
                address: '2 Avenue 54',
                city: 'New York',
              };
              this.thomasAndCoLoaded = true;
              this.addRow = true;
              this.newRow = row;
            }
          }                            
          
        
    

Notifications

Note: This example use Alerts Remember to import them.

        
            
          <div class="d-flex justify-content-end mb-4">
            <mdb-form-control>
              <input
                mdbInput
                type="text"
                class="form-control"
                id="search-input"
                [disabled]="addRow || editElementIndex !== -1"
                (keyup)="search($event)"
              />
              <label mdbLabel class="form-label" for="search-input">Search</label>
            </mdb-form-control>
            <button
              mdbRipple
              class="btn btn-primary btn-sm ms-3"
              [disabled]="editElementIndex !== -1"
              (click)="addRow = true"
            >
              <i class="fa fa-plus"></i>
            </button>
          </div>
          <hr />
          <div
            class="datatable table-editor mt-4"
            [ngClass]="{
              'edited-table': addRow || editElementIndex !== -1
            }"
          >
            <table
              class="table datatable-table"
              mdbTable
              mdbTableSort
              #table="mdbTable"
              #sort="mdbTableSort"
              [dataSource]="dataSource"
              [sort]="sort"
              [pagination]="pagination"
            >
              <thead class="datatable-header">
                <tr>
                  <th
                    *ngFor="let header of headers"
                    [mdbTableSortHeader]="header.field"
                    [disableSort]="header.disableSort"
                    scope="col"
                  >
                    {{ header.label | titlecase }}
                  </th>
                  <th scope="col">Actions</th>
                </tr>
              </thead>
              <tbody class="datatable-body">
                <tr
                  *ngIf="addRow"
                  [ngClass]="{ 'edited-row': addRow }"
                  scope="row"
                  cdkTrapFocus
                  cdkTrapFocusAutoCapture="true"
                >
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="text"
                        class="form-control"
                        [(ngModel)]="newRow.company"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <mdb-select [(ngModel)]="newRow.office">
                        <mdb-option
                          *ngFor="let option of options"
                          [value]="option.value"
                          >{{ option.label }}</mdb-option
                        >
                      </mdb-select>
                    </mdb-form-control>
                  </td>
                  <td>
                    <mdb-form-control>
                      <input
                        mdbInput
                        type="number"
                        class="form-control"
                        [(ngModel)]="newRow.employees"
                      />
                    </mdb-form-control>
                  </td>
                  <td>
                    <div class="form-check ms-1 mt-1">
                      <input
                        mdbCheckbox
                        class="form-check-input"
                        type="checkbox"
                        [(ngModel)]="newRow.international"
                      />
                    </div>
                  </td>
                  <td>
                    <button
                      class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                      (click)="addNewRow()"
                    >
                      <i class="fa fa-check"></i>
                    </button>
                    <button
                      class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                      (click)="discardNewRow()"
                    >
                      <i class="fa fa-ban"></i>
                    </button>
                  </td>
                </tr>
                <tr
                  *ngFor="let data of table.data; let index = index"
                  scope="row"
                  [cdkTrapFocus]="editElementIndex === index"
                  [cdkTrapFocusAutoCapture]="editElementIndex === index"
                  [ngClass]="{ 'edited-row': editElementIndex === index }"
                >
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.company }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="text"
                          class="form-control"
                          [(ngModel)]="data.company"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.office }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <mdb-select [(ngModel)]="data.office">
                          <mdb-option
                            *ngFor="let option of options"
                            [value]="option.value"
                            >{{ option.label }}</mdb-option
                          >
                        </mdb-select>
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td style="min-width: 250px; max-width: 250px">
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.employees }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <mdb-form-control>
                        <input
                          mdbInput
                          type="number"
                          class="form-control"
                          [(ngModel)]="data.employees"
                        />
                      </mdb-form-control>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container *ngIf="editElementIndex !== index">
                      {{ data.international }}
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <div class="form-check ms-1 mt-1">
                        <input
                          mdbCheckbox
                          class="form-check-input"
                          type="checkbox"
                          [(ngModel)]="data.international"
                        />
                      </div>
                    </ng-container>
                  </td>
                  <td>
                    <ng-container
                      *ngIf="editElementIndex === -1 || editElementIndex !== index"
                    >
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark edit-button"
                        (click)="onEditClick(index)"
                        [disabled]="editElementIndex !== -1 && editElementIndex !== index"
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark delete-button"
                        (click)="onDeleteClick(data)"
                        [disabled]="editElementIndex !== -1 && editElementIndex !== index"
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </ng-container>
                    <ng-container *ngIf="editElementIndex === index">
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-dark save-button"
                        (click)="onSaveClick(data)"
                      >
                        <i class="fa fa-check"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-dark discard-button"
                        (click)="onDiscardEdit(index)"
                      >
                        <i class="fa fa-ban"></i>
                      </button>
                    </ng-container>
                  </td>
                </tr>
              </tbody>
            </table>
            <mdb-table-pagination
              #pagination
              [entries]="5"
              [disabled]="addRow || editElementIndex !== -1"
            ></mdb-table-pagination>
          </div>          
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import {
            MdbNotificationService,
            MdbNotificationRef,
          } from 'mdb-angular-ui-kit/notification';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          import { NotificationComponent } from './notification.component';
          
          export interface Person {
            company: string;
            office: string;
            employees: number | null;
            international: boolean;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            notificationRef: MdbNotificationRef<NotificationComponent> | null = null;
            editElementIndex = -1;
            addRow = false;
          
            newRow: Person = {
              company: '',
              office: 'Warsaw',
              employees: 1,
              international: false,
            };
          
            editRow: Person = {
              company: '',
              office: '',
              employees: null,
              international: false,
            };
          
            options = [
              { value: 'London', label: 'London' },
              { value: 'Warsaw', label: 'Warsaw' },
              { value: 'New York', label: 'New York' },
            ];
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Office', field: 'office', disableSort: true },
              { label: 'Employees', field: 'employees', disableSort: false },
              { label: 'International', field: 'international', disableSort: false },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                office: 'London',
                employees: 30,
                international: true,
              },
              {
                company: 'P.J. Company',
                office: 'London',
                employees: 80,
                international: false,
              },
              {
                company: 'Food & Wine',
                office: 'London',
                employees: 12,
                international: false,
              },
              {
                company: 'IT Service',
                office: 'London',
                employees: 17,
                international: false,
              },
              {
                company: 'A. Jonson Gallery',
                office: 'London',
                employees: 4,
                international: false,
              },
              {
                company: 'F.A. Architects',
                office: 'London',
                employees: 4,
                international: false,
              },
            ];
          
            constructor(private notificationService: MdbNotificationService) {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            addNewRow(): void {
              this.dataSource = [...this.dataSource, { ...this.newRow }];
              this.openAlert(this.newRow, 'add');
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.newRow.international = false;
              this.addRow = false;
            }
          
            discardNewRow(): void {
              this.newRow.company = '';
              this.newRow.office = 'Warsaw';
              this.newRow.employees = 1;
              this.addRow = false;
            }
          
            onEditClick(index: number): void {
              this.editElementIndex = index;
              this.editRow = { ...this.table.data[index] };
            }
          
            onDiscardEdit(index: number): void {
              this.editElementIndex = -1;
              this.table.data[index] = { ...this.editRow };
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
              this.openAlert(data, 'delete');
            }
          
            onSaveClick(data: Person): void {
              this.editElementIndex = -1;
              this.openAlert(data, 'edit');
            }
          
            openAlert(data: Person, action: 'add' | 'delete' | 'edit'): void {
              const options = {
                action: action,
                rowData: `${data.company} (${data.office})`,
              };
              this.notificationRef = this.notificationService.open(
                NotificationComponent,
                { data: options, autohide: true, delay: 1000 }
              );
            }
          }          
          
        
    
        
            
          <div class="alert alert-{{ color }}" role="alert">
            <strong>{{ actionText }}</strong> {{ rowData }}
          </div>          
          
        
    
        
            
          import { Component, OnInit } from '@angular/core';
          import { MdbNotificationRef } from 'mdb-angular-ui-kit/notification';
          
          @Component({
            selector: 'app-notification',
            templateUrl: './notification.component.html',
          })
          export class NotificationComponent implements OnInit {
            action: 'add' | 'delete' | 'edit' | null = null;
            rowData: string | null = null;
            color: string | null = null;
            actionText: string | null = null;
          
            constructor(
              public notificationRef: MdbNotificationRef<NotificationComponent>
            ) {}
          
            ngOnInit(): void {
              switch (this.action) {
                case 'add':
                  this.color = 'success';
                  this.actionText = 'New entry:';
                  break;
                case 'delete':
                  this.color = 'danger';
                  this.actionText = 'Deleted entry:';
                  break;
                case 'edit':
                  this.color = 'primary';
                  this.actionText = 'Updated entry:';
                  break;
                default:
                  break;
              }
            }
          }          
          
        
    

Dark

Note: This example use Modal. Remember to import them.


Company Address Employees
Smith & Johnson Park Lane 2, London 30
P.J. Company Oak Street 7, Aberdeen 80
Food & Wine Netherhall Gardens 3, Hampstead 12
IT Service Warwick Road 14, London 17
A. Jonson Gallery Oaklands Avenue 2, London 4
F.A. Architects Frognal Way 7, Hampstead 4
        
            
          <section class="border p-4 mb-4 bg-dark">
            <div class="d-flex justify-content-end mb-4">
              <mdb-form-control class="form-white">
                <input
                  mdbInput
                  type="text"
                  class="form-control"
                  id="search-input"
                  (keyup)="search($event)"
                />
                <label mdbLabel class="form-label" for="search-input">Search</label>
              </mdb-form-control>
              <button
                mdbRipple
                class="btn btn-outline-light btn-sm ms-3"
                (click)="openModal('add')"
              >
                <i class="fa fa-plus"></i>
              </button>
            </div>
            <hr />
            <div
              class="datatable table-editor bg-dark datatable-dark text-white border-white mt-4"
            >
              <table
                class="table datatable-table"
                mdbTable
                mdbTableSort
                #table="mdbTable"
                #sort="mdbTableSort"
                [dataSource]="dataSource"
                [sort]="sort"
                [pagination]="pagination"
              >
                <thead class="datatable-header text-white">
                  <tr>
                    <th
                      *ngFor="let header of headers"
                      [mdbTableSortHeader]="header.field"
                      [disableSort]="header.disableSort"
                      scope="col"
                    >
                      {{ header.label | titlecase }}
                    </th>
                    <th scope="col">Actions</th>
                  </tr>
                </thead>
                <tbody class="datatable-body text-white">
                  <tr *ngFor="let data of table.data; let index = index" scope="row">
                    <td style="min-width: 250px; max-width: 250px">
                      {{ data.company }}
                    </td>
                    <td style="min-width: 250px; max-width: 250px">
                      {{ data.address }}
                    </td>
                    <td style="min-width: 250px; max-width: 250px">
                      {{ data.employees }}
                    </td>
          
                    <td>
                      <button
                        class="me-2 m-0 p-0 shadow-0 btn btn-lg text-light edit-button"
                        (click)="openModal('edit', data)"
                      >
                        <i class="far fa-edit"></i>
                      </button>
                      <button
                        class="m-0 p-0 shadow-0 btn btn-lg text-light delete-button"
                        (click)="onDeleteClick(data)"
                      >
                        <i class="far fa-trash-alt"></i>
                      </button>
                    </td>
                  </tr>
                </tbody>
              </table>
              <mdb-table-pagination #pagination [entries]="5"></mdb-table-pagination>
            </div>
          </section>          
          
        
    
        
            
          import { Component, ViewChild } from '@angular/core';
          import { MdbModalRef, MdbModalService } from 'mdb-angular-ui-kit/modal';
          import { MdbTableDirective } from 'mdb-angular-ui-kit/table';
          import { ModalComponent } from './modal.component';
          
          export interface Person {
            company: string;
            address: string;
            employees: number | null;
          }
          
          @Component({
            selector: 'app-root',
            templateUrl: './app.component.html',
          })
          export class AppComponent {
            @ViewChild('table') table!: MdbTableDirective<Person>;
          
            modalRef: MdbModalRef<ModalComponent> | null = null;
          
            headers = [
              { label: 'Company', field: 'company', disableSort: false },
              { label: 'Address', field: 'address', disableSort: false },
              { label: 'Employees', field: 'employees', disableSort: false },
            ];
          
            dataSource: Person[] = [
              {
                company: 'Smith & Johnson',
                address: 'Park Lane 2, London',
                employees: 30,
              },
              {
                company: 'P.J. Company',
                address: 'Oak Street 7, Aberdeen',
                employees: 80,
              },
              {
                company: 'Food & Wine',
                address: 'Netherhall Gardens 3, Hampstead',
                employees: 12,
              },
              {
                company: 'IT Service',
                address: 'Warwick Road 14, London	',
                employees: 17,
              },
              {
                company: 'A. Jonson Gallery',
                address: 'Oaklands Avenue 2, London	',
                employees: 4,
              },
              {
                company: 'F.A. Architects',
                address: 'Frognal Way 7, Hampstead	',
                employees: 4,
              },
            ];
            constructor(private modalService: MdbModalService) {}
          
            search(event: Event): void {
              const searchTerm = (event.target as HTMLInputElement).value;
              this.table.search(searchTerm);
            }
          
            openModal(mode: 'add' | 'edit', data?: Person): void {
              this.modalRef = this.modalService.open(ModalComponent, {
                data: {
                  modalTitle: mode === 'edit' ? 'Edit item' : 'New item',
                  company: data ? data.company : '',
                  address: data ? data.address : '',
                  employees: data ? data.employees : null,
                },
              });
              this.modalRef.onClose.subscribe((modalData: Person) => {
                if (!modalData) {
                  return;
                }
                if (mode === 'add') {
                  this.dataSource = [...this.dataSource, { ...modalData }];
                } else if (mode === 'edit' && data) {
                  const index = this.dataSource.indexOf(data);
                  this.dataSource[index] = modalData;
                  this.dataSource = [...this.dataSource];
                }
              });
            }
          
            onDeleteClick(data: Person): void {
              const index = this.dataSource.indexOf(data);
              this.dataSource.splice(index, 1);
              this.dataSource = [...this.dataSource];
            }
          }          
          
        
    
        
            
          <div class="modal-header bg-dark text-white">
            <h5 class="modal-title" id="exampleModalLabel">{{ modalTitle }}</h5>
          </div>
          <div class="modal-body bg-dark text-white">
            <div class="my-4 table-editor_input-wrapper">
              <mdb-form-control class="form-white">
                <input
                  mdbInput
                  type="text"
                  id="company-input"
                  class="form-control"
                  [(ngModel)]="company"
                />
                <label mdbLabel class="form-label" for="company-input">Company</label>
              </mdb-form-control>
            </div>
            <div class="my-4 table-editor_input-wrapper">
              <mdb-form-control class="form-white">
                <input
                  mdbInput
                  type="text"
                  id="address-input"
                  class="form-control"
                  [(ngModel)]="address"
                />
                <label mdbLabel class="form-label" for="address-input">Address</label>
              </mdb-form-control>
            </div>
            <div class="my-4 table-editor_input-wrapper">
              <mdb-form-control class="form-white">
                <input
                  mdbInput
                  type="number"
                  id="employees-input"
                  class="form-control"
                  [(ngModel)]="employees"
                />
                <label mdbLabel class="form-label" for="employees-input">Employees</label>
              </mdb-form-control>
            </div>
          </div>
          <div class="modal-footer bg-dark text-white">
            <button
              type="button"
              class="shadow-0 btn btn-md btn-outline-light"
              (click)="modalRef.close()"
            >
              Cancel
            </button>
            <button
              type="button"
              class="shadow-0 btn btn-md btn-light"
              (click)="saveData()"
            >
              Save
            </button>
          </div>          
          
        
    
        
            
          import { Component, OnInit } from '@angular/core';
          import { MdbModalRef } from 'mdb-angular-ui-kit/modal';
          
          @Component({
            selector: 'app-modal',
            templateUrl: './modal.component.html',
          })
          export class ModalComponent implements OnInit {
            modalTitle: string | null = null;
            company: string | null = null;
            address: string | null = null;
            employees: string | null = null;
          
            options = [
              { value: 'London', label: 'London' },
              { value: 'Warsaw', label: 'Warsaw' },
              { value: 'New York', label: 'New York' },
            ];
          
            constructor(public modalRef: MdbModalRef<ModalComponent>) {}
          
            ngOnInit(): void {}
          
            saveData(): void {
              const closeMessage = {
                company: this.company,
                employees: this.employees,
                address: this.address,
              };
          
              this.modalRef.close(closeMessage);
            }
          }          
          
        
    

Table editor - API


Import

        
            
        import { MdbTableModule } from 'mdb-angular-ui-kit/table';
        import { MdbFormsModule } from 'mdb-angular-ui-kit/forms';
        import { FormsModule } from '@angular/forms';
        import { A11yModule } from '@angular/cdk/a11y';
        import { MdbSelectModule } from 'mdb-angular-ui-kit/select';              // For examples with Select
        import { MdbModalModule } from 'mdb-angular-ui-kit/modal';                // For examples with Modal
        import { MdbNotificationModule } from 'mdb-angular-ui-kit/notification';  // For examples with Notification
        import { MdbPopconfirmModule } from 'mdb-angular-ui-kit/popconfirm';      // For examples with Popconfirm

        ...
        @NgModule({
          ...
          imports: [
            MdbTableModule,
            MdbFormsModule,
            FormsModule,
            A11yModule,
            MdbSelectModule,        // For examples with Select
            MdbModalModule,         // For examples with Modal
            MdbNotificationModule,  // For examples with Notification
            MdbPopconfirmModule     // For examples with Popconfirm
          ],
          ...
        })