0

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:https://www.npmjs.com/package/angular4-material-table

plunker:https://plnkr.co/edit/9kZfUW?p=preview

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 & working properly with sorting and search. Now I need to make it editable

HTML

<mat-table #table [dataSource]="dataSource" matSort>
                        <ng-container matColumnDef="ID">
                            <mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
                            <mat-cell *matCellDef="let row">
                                {{row.ID}}

                            </mat-cell>
                        </ng-container>
                        <ng-container matColumnDef="Comment">
                            <mat-header-cell *matHeaderCellDef mat-sort-header> Commment </mat-header-cell>
                            <mat-cell *matCellDef="let row">

                                <mat-form-field floatPlaceholder="{{ row.editing ? 'float' : 'never'}}">
                                    <input [formControl]="row.validator.controls['Comment']" [readonly]="!row.editing" placeholder="Comment" [(ngModel)]="row.currentData.Comment" matInput>
                                </mat-form-field>
                            </mat-cell>
                        </ng-container>
                        <ng-container matColumnDef="actionsColumn">
                            <mat-header-cell *matHeaderCellDef>
                                <button mat-icon-button color="accent" (click)="dataSource.createNew()"><i class="fa fa-plus mat-icon"></i></button>
                            </mat-header-cell>
                            <mat-cell *matCellDef="let row">
                                <button *ngIf="!row.editing" mat-icon-button color="primary" focusable="false" (click)="row.startEdit()">
                                    <i class="fa fa-pencil mat-icon"></i>
                                </button>
                                <button *ngIf="row.editing" mat-icon-button color="primary" focusable="false" (click)="row.confirmEditCreate()">
                                    <i class="fa fa-check mat-icon"></i>
                                </button>
                                <button mat-icon-button color="primary" focusable="false" (click)="row.cancelOrDelete()">
                                    <i class="fa fa-times mat-icon"></i>
                                </button>
                            </mat-cell>
                        </ng-container>
                        <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
                        <mat-row *matRowDef="let row; columns:displayedColumns"></mat-row>
                    </mat-table>
                    <mat-paginator #paginator
                                   [pageSize]="10"
                                   [pageSizeOptions]="[5, 10, 20]">
                    </mat-paginator>

Interface

export interface IToDoList {

    ID: number,
    Comment: string
}

component.ts

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(() => {
          //  this.showMessage('File has been uploaded successfully!', 'alert alert-success');
           this.getBSAFollowup();

        },
          error => console.log('Upload File: '));

    }

    GetToDoList(ID: string) {
        this._dashboardService.getToDoList(ID)
            .subscribe(
            data => {
              //  this.toDoList = data.result;
                //this.dataSource = new MatTableDataSource(data.result);
                this.dataSource.data = data.result;
                  },
            error => console.log('GetControls Method: ' + <any>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;
    }

}

service.ts

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) => response.json())
            .do(data => console.log('All' + JSON.stringify(data)))
            .catch(this.handleError);

    }


    private handleError(error: Response) {
        return Observable.throw(error.json().error || 'Server Error');
    }
}

****************************************************Update**************************************************

HTML
               <mat-table #table [dataSource]="dataSource" matSort>
                        <ng-container matColumnDef="ID">
                            <mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
                            <mat-cell *matCellDef="let row">

    {{row.currentData.id}}


                            </mat-cell>
                        </ng-container>
                        <ng-container matColumnDef="Comment">
                            <mat-header-cell *matHeaderCellDef mat-sort-header> Commment </mat-header-cell>
                            <mat-cell *matCellDef="let row">
                                <mat-form-field floatPlaceholder="{{ row.editing ? 'float' : 'never'}}">
                                    <input matInput [formControl]="row.validator.controls['Comment']" placeholder="Comment" [(ngModel)]="row.currentData.Comment">
                                </mat-form-field>
                                                 </mat-cell>
                        </ng-container>
                        <ng-container matColumnDef="actionsColumn">
                            <mat-header-cell *matHeaderCellDef>
                                <button mat-icon-button color="accent" (click)="dataSource.createNew()"><i class="fa fa-plus mat-icon"></i></button>
                            </mat-header-cell>
                            <mat-cell *matCellDef="let row">
                                <button *ngIf="!row.editing" mat-icon-button color="primary" focusable="false" (click)="row.startEdit()">
                                    <i class="fa fa-pencil mat-icon"></i>
                                </button>
                                <button *ngIf="row.editing" mat-icon-button color="primary" focusable="false" (click)="row.confirmEditCreate()">
                                    <i class="fa fa-check mat-icon"></i>
                                </button>
                                <button mat-icon-button color="primary" focusable="false" (click)="row.cancelOrDelete()">
                                    <i class="fa fa-times mat-icon"></i>
                                </button>
                            </mat-cell>
                        </ng-container>
                        <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
                        <mat-row *matRowDef="let row; columns:displayedColumns"></mat-row>
                    </mat-table>
                    <mat-paginator #paginator
                                   [pageSize]="10"
                                   [pageSizeOptions]="[5, 10, 20]">
                    </mat-paginator>

TodoItemValidatorService.ts

@Injectable()
export class TodoItemValidatorService implements ValidatorService {
    getRowValidator(): FormGroup {
        return new FormGroup({

            'Comment': new FormControl(),
        });
    }
}

component.ts

    class TodoItem {
        ID: number;
        Comment: string;
    }
    export class DashboardComponent implements OnInit {
     @Output() personListChange = new EventEmitter<TodoItem>();
    dataSource: TableDataSource<TodoItem>;
    @Output() personListChange = new EventEmitter<TodoItem>();

        @Input() todoList = [];

        constructor(private _dashboardService:  private todoItemValidator: ValidatorService) {

            _appParams.AdminPSNLUID.subscribe((val) => {
                this.userID = val;
            });

        }

      ngOnInit(): void {

            this.GetToDoList(this.userID);
            this.dataSource = new TableDataSource<any>(this.todoList, TodoItem, this.todoItemValidator);

    this.dataSource.datasourceSubject.subscribe(todoList => this.personListChange.emit(todoList));


        }

    GetToDoList(ID: string) {
            this._dashboardService.getToDoList(ID)
                .subscribe(
                data => {

                     this.dataSource.updateDatasource(data.result);
                      },
                error => console.log('GetControls Method: ' + <any>error, 'alert alert-danger'));
        }


    }

service

@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) => response.json())
            .do(data => console.log('All' + JSON.stringify(data)))
            .catch(this.handleError);

    }


    private handleError(error: Response) {
        return Observable.throw(error.json().error || 'Server Error');
    }
}
2
  • Your plunker seems to work Commented Apr 2, 2018 at 21:09
  • yes but it is not working with my code..I have more complex code since I have a service to load the data Commented Apr 2, 2018 at 21:42

1 Answer 1

1

You should follow these steps:

  1. Create a class with the data you want to store. I'd suggest you to use lowerCamelCase for variables:

    public class Comment {
      id: number;
      comment: string;
    }
    
  2. Instantiate a new TableDataSource with the class you specified. In the example you've specified, you're instatianting MatTableDataSource:

    this.dataSource = new TableDataSource<any>([], Comment);
    // The array is empty, if you want to have initial elements just pass a filled array.
    
  3. If you followed the advice to use lowerCamelCasing, then remember to change your html file.

Next time you have issues with the specific package, you can open an issue directly in the package's repo and I'll gladly answer there.


Edit:

I'd suggest you to read the angular4-material-table's repo readme.md where you can find the available methods and properties for row (TableElement) and TableDataSource. If that info is not enough, i,'ll encourage you to navigate into the code and see method descriptions.

Sign up to request clarification or add additional context in comments.

14 Comments

I am still not sure what do you mean...my issue is trying to implement row.startEdit(), row.confirmEditCreate() for the comment field see above code..I dot' want the edit to be in a popup box but rather a text box is enabled for the comment to be edited within the grid..Can you help? i can't find documentation for it
Isee what you mean about creating a class to store my data, i still don't know how to connect the pieces together ..how can I do that with my above code..how can I call this new class
I see that you are using: dataSource = new MatTableDataSource(); instead of: dataSource = new TableDataSource<any>([], Comment);. That's probably the problem in your code.
I am bit confused on how to fit this in my code... I already have an interface and service class.. can you show me how will that work with my code? I updated my above code to show the interface and service class
Please check this plnkr. It does not follow the comments I made about good code practices because I've copy/pasted the most I could from your code to show you how it works.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.