title: Angular Editable Material Table
body: <p>I am using Material tables and having a hard time finding an example of editable Material table. I found one example but I have no idea how would that fit with my existing code..he is the best link I found
  Link:<a href="https://www.npmjs.com/package/angular4-material-table" rel="nofollow noreferrer">https://www.npmjs.com/package/angular4-material-table</a></p>
  
  <p>plunker:<a href="https://plnkr.co/edit/9kZfUW?p=preview" rel="nofollow noreferrer">https://plnkr.co/edit/9kZfUW?p=preview</a></p>
  
  <p>here is my code also I am open for any suggestion if someone uses other kind of editable tables. Also before I tried to add the editable feature my table was displaying &amp; working properly with sorting and search. Now I need to make it editable</p>
  
  <p>HTML</p>
  
  <pre><code>&lt;mat-table #table [dataSource]="dataSource" matSort&gt;
                          &lt;ng-container matColumnDef="ID"&gt;
                              &lt;mat-header-cell *matHeaderCellDef mat-sort-header&gt; ID &lt;/mat-header-cell&gt;
                              &lt;mat-cell *matCellDef="let row"&gt;
                                  {{row.ID}}
  
                              &lt;/mat-cell&gt;
                          &lt;/ng-container&gt;
                          &lt;ng-container matColumnDef="Comment"&gt;
                              &lt;mat-header-cell *matHeaderCellDef mat-sort-header&gt; Commment &lt;/mat-header-cell&gt;
                              &lt;mat-cell *matCellDef="let row"&gt;
  
                                  &lt;mat-form-field floatPlaceholder="{{ row.editing ? 'float' : 'never'}}"&gt;
                                      &lt;input [formControl]="row.validator.controls['Comment']" [readonly]="!row.editing" placeholder="Comment" [(ngModel)]="row.currentData.Comment" matInput&gt;
                                  &lt;/mat-form-field&gt;
                              &lt;/mat-cell&gt;
                          &lt;/ng-container&gt;
                          &lt;ng-container matColumnDef="actionsColumn"&gt;
                              &lt;mat-header-cell *matHeaderCellDef&gt;
                                  &lt;button mat-icon-button color="accent" (click)="dataSource.createNew()"&gt;&lt;i class="fa fa-plus mat-icon"&gt;&lt;/i&gt;&lt;/button&gt;
                              &lt;/mat-header-cell&gt;
                              &lt;mat-cell *matCellDef="let row"&gt;
                                  &lt;button *ngIf="!row.editing" mat-icon-button color="primary" focusable="false" (click)="row.startEdit()"&gt;
                                      &lt;i class="fa fa-pencil mat-icon"&gt;&lt;/i&gt;
                                  &lt;/button&gt;
                                  &lt;button *ngIf="row.editing" mat-icon-button color="primary" focusable="false" (click)="row.confirmEditCreate()"&gt;
                                      &lt;i class="fa fa-check mat-icon"&gt;&lt;/i&gt;
                                  &lt;/button&gt;
                                  &lt;button mat-icon-button color="primary" focusable="false" (click)="row.cancelOrDelete()"&gt;
                                      &lt;i class="fa fa-times mat-icon"&gt;&lt;/i&gt;
                                  &lt;/button&gt;
                              &lt;/mat-cell&gt;
                          &lt;/ng-container&gt;
                          &lt;mat-header-row *matHeaderRowDef="displayedColumns"&gt;&lt;/mat-header-row&gt;
                          &lt;mat-row *matRowDef="let row; columns:displayedColumns"&gt;&lt;/mat-row&gt;
                      &lt;/mat-table&gt;
                      &lt;mat-paginator #paginator
                                     [pageSize]="10"
                                     [pageSizeOptions]="[5, 10, 20]"&gt;
                      &lt;/mat-paginator&gt;
  </code></pre>
  
  <p>Interface</p>
  
  <pre><code>export interface IToDoList {
  
      ID: number,
      Comment: string
  }
  </code></pre>
  
  <p>component.ts</p>
  
  <pre><code>export class DashboardComponent implements OnInit {
      toDoList: IToDoList[] = null;
      dataSource = new MatTableDataSource();
      @ViewChild(MatPaginator) paginator: MatPaginator;
      @ViewChild(MatSort) sort: MatSort;
      displayedColumns = ['Comment'];
  
       ngOnInit(): void { 
          this.GetToDoList(this.userID);
      }
      onOpen() {
  
          this._dashboardService.delBSAFollowup(this.selectedRowID).subscribe(() =&gt; {
            //  this.showMessage('File has been uploaded successfully!', 'alert alert-success');
             this.getBSAFollowup();
  
          },
            error =&gt; console.log('Upload File: '));
  
      }
  
      GetToDoList(ID: string) {
          this._dashboardService.getToDoList(ID)
              .subscribe(
              data =&gt; {
                //  this.toDoList = data.result;
                  //this.dataSource = new MatTableDataSource(data.result);
                  this.dataSource.data = data.result;
                    },
              error =&gt; console.log('GetControls Method: ' + &lt;any&gt;error, 'alert alert-danger'));
      }
  
       ngAfterViewInit() {
  
          this.dataSource.paginator = this.paginator;
          this.dataSource.sort = this.sort;
      }
      applyFilter(filterValue: string) {
          filterValue = filterValue.trim(); // Remove whitespace
          filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
          this.dataSource.filter = filterValue;
      }
  
  }
  </code></pre>
  
  <p>service.ts</p>
  
  <pre><code>import { IToDoList } from './toDoList';
  @Injectable()
  
  export class DashboardService {
  
  
      baseAPIURL: string;
      constructor(private _http: Http) {
  
  
  
      }
  
      getToDoList(psnlUID:string) {
  
  
          return this._http.get(environment.BASE_API_URL + 'XXXXX/' + ID)
              .map((response: Response) =&gt; response.json())
              .do(data =&gt; console.log('All' + JSON.stringify(data)))
              .catch(this.handleError);
  
      }
  
  
      private handleError(error: Response) {
          return Observable.throw(error.json().error || 'Server Error');
      }
  }
  </code></pre>
  
  <p>****************************************************Update**************************************************</p>
  
  <pre><code>HTML
                 &lt;mat-table #table [dataSource]="dataSource" matSort&gt;
                          &lt;ng-container matColumnDef="ID"&gt;
                              &lt;mat-header-cell *matHeaderCellDef mat-sort-header&gt; ID &lt;/mat-header-cell&gt;
                              &lt;mat-cell *matCellDef="let row"&gt;
  
      {{row.currentData.id}}
  
  
                              &lt;/mat-cell&gt;
                          &lt;/ng-container&gt;
                          &lt;ng-container matColumnDef="Comment"&gt;
                              &lt;mat-header-cell *matHeaderCellDef mat-sort-header&gt; Commment &lt;/mat-header-cell&gt;
                              &lt;mat-cell *matCellDef="let row"&gt;
                                  &lt;mat-form-field floatPlaceholder="{{ row.editing ? 'float' : 'never'}}"&gt;
                                      &lt;input matInput [formControl]="row.validator.controls['Comment']" placeholder="Comment" [(ngModel)]="row.currentData.Comment"&gt;
                                  &lt;/mat-form-field&gt;
                                                   &lt;/mat-cell&gt;
                          &lt;/ng-container&gt;
                          &lt;ng-container matColumnDef="actionsColumn"&gt;
                              &lt;mat-header-cell *matHeaderCellDef&gt;
                                  &lt;button mat-icon-button color="accent" (click)="dataSource.createNew()"&gt;&lt;i class="fa fa-plus mat-icon"&gt;&lt;/i&gt;&lt;/button&gt;
                              &lt;/mat-header-cell&gt;
                              &lt;mat-cell *matCellDef="let row"&gt;
                                  &lt;button *ngIf="!row.editing" mat-icon-button color="primary" focusable="false" (click)="row.startEdit()"&gt;
                                      &lt;i class="fa fa-pencil mat-icon"&gt;&lt;/i&gt;
                                  &lt;/button&gt;
                                  &lt;button *ngIf="row.editing" mat-icon-button color="primary" focusable="false" (click)="row.confirmEditCreate()"&gt;
                                      &lt;i class="fa fa-check mat-icon"&gt;&lt;/i&gt;
                                  &lt;/button&gt;
                                  &lt;button mat-icon-button color="primary" focusable="false" (click)="row.cancelOrDelete()"&gt;
                                      &lt;i class="fa fa-times mat-icon"&gt;&lt;/i&gt;
                                  &lt;/button&gt;
                              &lt;/mat-cell&gt;
                          &lt;/ng-container&gt;
                          &lt;mat-header-row *matHeaderRowDef="displayedColumns"&gt;&lt;/mat-header-row&gt;
                          &lt;mat-row *matRowDef="let row; columns:displayedColumns"&gt;&lt;/mat-row&gt;
                      &lt;/mat-table&gt;
                      &lt;mat-paginator #paginator
                                     [pageSize]="10"
                                     [pageSizeOptions]="[5, 10, 20]"&gt;
                      &lt;/mat-paginator&gt;
  </code></pre>
  
  <p>TodoItemValidatorService.ts</p>
  
  <pre><code>@Injectable()
  export class TodoItemValidatorService implements ValidatorService {
      getRowValidator(): FormGroup {
          return new FormGroup({
  
              'Comment': new FormControl(),
          });
      }
  }
  </code></pre>
  
  <p>component.ts</p>
  
  <pre><code>    class TodoItem {
          ID: number;
          Comment: string;
      }
      export class DashboardComponent implements OnInit {
       @Output() personListChange = new EventEmitter&lt;TodoItem&gt;();
      dataSource: TableDataSource&lt;TodoItem&gt;;
      @Output() personListChange = new EventEmitter&lt;TodoItem&gt;();
  
          @Input() todoList = [];
  
          constructor(private _dashboardService:  private todoItemValidator: ValidatorService) {
  
              _appParams.AdminPSNLUID.subscribe((val) =&gt; {
                  this.userID = val;
              });
  
          }
  
        ngOnInit(): void {
  
              this.GetToDoList(this.userID);
              this.dataSource = new TableDataSource&lt;any&gt;(this.todoList, TodoItem, this.todoItemValidator);
  
      this.dataSource.datasourceSubject.subscribe(todoList =&gt; this.personListChange.emit(todoList));
  
  
          }
  
      GetToDoList(ID: string) {
              this._dashboardService.getToDoList(ID)
                  .subscribe(
                  data =&gt; {
  
                       this.dataSource.updateDatasource(data.result);
                        },
                  error =&gt; console.log('GetControls Method: ' + &lt;any&gt;error, 'alert alert-danger'));
          }
  
  
      }
  </code></pre>
  
  <p>service</p>
  
  <pre><code>@Injectable()
  
  export class DashboardService {
  
  
      baseAPIURL: string;
      constructor(private _http: Http) {
  
  
  
      }
  
      getToDoList(psnlUID:string) {
  
  
          return this._http.get(environment.BASE_API_URL + 'XXXXX/' + ID)
              .map((response: Response) =&gt; response.json())
              .do(data =&gt; console.log('All' + JSON.stringify(data)))
              .catch(this.handleError);
  
      }
  
  
      private handleError(error: Response) {
          return Observable.throw(error.json().error || 'Server Error');
      }
  }
  </code></pre>