1

I am using Angular 2 material datatable in one of my projects. There are actually 2 parts to my question:

  1. if I click on any one of the rows in the datatable, I need to get the row index so that I can apply an appropriate CSS on the selected row. I have read the documentation but could not find any mention of getting the index of each row.

  2. I also allow the users to edit individual records in a datatable. For this, each row will have an EDIT button, clicking on which will open a modal dialog pre-populated with values. Once the data has been updated, I want to update the datatable with the new values. I can access the updated data model in the window containing the table. I want to understand how I Can dynamically update a row OR insert a new row in the datatable (the best practices).

Would appreciate any inputs here.

tftd
  • 16,203
  • 11
  • 62
  • 106
va1b4av
  • 431
  • 9
  • 26
  • Check this [answer](https://stackoverflow.com/a/45417497/5556177) for your first question. – Nehal Aug 25 '17 at 12:15

3 Answers3

2
  1. As @Nehal mentioned you can do this to get the row.id

html:

<md-row *cdkRowDef="let row; columns: displayedColumns; let index=index;"
  (click)="select(row, index)">
</md-row>

ts:

select(row, index) {
  // you can use a row id or just a table index
  this.selectedRowIndex = row.id;
}
  1. The datatable will rerender if you connect() observable emits a new value. That solution will be specific to your application, but all you need to do is update your data model and then emit your data model again.
Will Howell
  • 3,585
  • 2
  • 21
  • 32
  • Nehal's solution actually talks about using an Id field that is already present in the table. In my case, I may not have a column that uniquely identifies a row. So it may not work in my case. WIll, your solution, gives me the following error. Can you please help? Parser Error: Unexpected token = at column 42 in [let row; columns: displayedColumns; index=index;] in ng – va1b4av Aug 26 '17 at 03:41
  • 1
    It should be: let index=index; – jymdman Aug 27 '17 at 08:51
  • @va1b4av: fixed per @jymdman's suggestion. And as you mentioned, if you don't have a unique ID, then you can use the index. Just keep in mind that `index` is the index of displayed columns, so it will change if you're doing pagination or filtering. – Will Howell Aug 28 '17 at 13:46
1

after you dynamically changed the elements in your MatTableDataSource

elements.forEach(ele => { this.dataSource.data.push(ele) });

you can force your table to redraw with

this.dataSource._updateChangeSubscription();
schitzN
  • 13
  • 4
0

Question #2 really wasn't answered so here is a solution with my delete code but the same for update code. Notice that once the result is a success I call a success modal to notify the user then call a function to remove the row from the data table. This way I don't have to download all the data again.

public deleteMember(memberId) {
      // Call the confirm dialog component
      this.confirmService.confirm('Confirm Delete', 'This action is final. Gone forever!')
          .switchMap(res => {if (res === true) {
              return this.appService.deleteItem(this.dbTable, memberId);
          }})
          .subscribe(
              result => {
                this.success();
                // Refresh DataTable to remove row.
                this.updateDataTable (memberId);
              },
              (err: HttpErrorResponse) => {
                  console.log(err.error);
                  console.log(err.message);
                this.messagesService.openDialog('Error', 'Delete did not happen.');
              }
          );
  }

Now lets remove, or update, that deleted, or edited, row.

  // Remove the deleted row from the data table. Need to remove from the downloaded data first.
  private updateDataTable (itemId) {
    this.dsData = this.dataSource.data;
    if (this.dsData.length > 0) {
      for (let i = 0; i < this.dsData.length; i++ ) {
        if (this.dsData[i].member_id === itemId) {
          this.dataSource.data.splice(i, 1);
        }
      }
    }
    this.dataSource.paginator = this.paginator;
  }
Preston
  • 3,260
  • 4
  • 37
  • 51