0
votes

I have a dynamic data table build using Angular Material where I am using an API to supply the table with data currently.

What I am trying to do is add delete capability where I am able to select a row and delete the entire row.

I want to use mat-checkbox to select the the row, and use a delete button in the header to delete the selected row.

Right now, the checkbox are added on every cell item in the row, where I would rather to select the entire row.

How can/could I add or fix this funtionality?

HTML Component

 <mat-card *ngIf="!loading">
<span>
    <mat-card-header class="mat-card-header view-title" style="background-color: lightblue;
    padding: 11px 0px 0px 0px;
    margin: 0px 0px 8px 0px;
    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 15px 0 rgba(0, 0, 0, 0.19)">
    <mat-card-title>{{viewName}}</mat-card-title>
    <span class="fill-nav-bar"></span>
      <button style="padding-right: 80px;" mat-icon-button>
        <mat-icon>cancel</mat-icon>
      </button>
      </mat-card-header>
</span>

  <mat-card-content>
    <div class="view-container mat-elevation-z8">
      <table mat-table [dataSource]="dataSource" matSort>

        <ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns">
          <th mat-header-cell *matHeaderCellDef mat-sort-header>
            {{ column }}
            <mat-icon aria-hidden="false" aria-label="filter icon">more_horiz</mat-icon>
          </th>
          <td mat-cell *matCellDef="let action">{{ action[column] }}
           <mat-checkbox></mat-checkbox>
          </td>
        </ng-container>

        <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
      </table>

      <mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons></mat-paginator>
    </div>
  </mat-card-content>
</mat-card>

TS Component

@Component({
  templateUrl: 'view.component.html',
  encapsulation: ViewEncapsulation.None
})
export class ViewComponent implements OnInit, OnDestroy {

  // User Fields
  currentUser: User;
  users: User[] = [];
  currentUserSubscription: Subscription;

  loading : boolean;
  // Action Fields
  viewData: any;
  viewName: string;
  refNumber: number;
  currentActionSubscription: Subscription;
  displayedColumns: string[] = [];
  dataSource: any = new MatTableDataSource([]);
  pageSizeOptions: number[] = [10, 20, 50];

  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatPaginator) paginator: MatPaginator;

  defaultSort: MatSortable = {
    id: 'defColumnName',
    start: 'asc',
    disableClear: true
  };

  defaultPaginator: MatPaginator;

  constructor(
    private iconRegistry: MatIconRegistry,
    private sanitizer: DomSanitizer,
    private actionService: ActionService
  ) {
    this.loading = false;
    this.iconRegistry.addSvgIcon(
      'thumbs-up',
      this.sanitizer.bypassSecurityTrustResourceUrl(
        'assets/img/examples/thumbup-icon.svg'
      )
    );
  }

  loadAction(action: any) {

    this.loading = true;
    // If there is already data loaded into the View, cache it in the service.
    if (this.viewData) {
      this.cacheAction();
    }

    if (this.sort) {
      // If there is sorting cached, load it into the View.
      if (action.sortable) {
        // If the action was cached, we should hit this block.
        this.sort.sort(action.sortable);
      } else {
        // Else apply the defaultSort.
        this.sort.sort(this.defaultSort);
      }
    }

    if (this.paginator) {
      // If we've stored a pageIndex and/or pageSize, retrieve accordingly.
      if (action.pageIndex) {
        this.paginator.pageIndex = action.pageIndex;
      } else { // Apply default pageIndex.
        this.paginator.pageIndex = 0;
      }

      if (action.pageSize) {
        this.paginator.pageSize = action.pageSize;
      } else { // Apply default pageSize.
        this.paginator.pageSize = 10;
      }
    }

    // Apply the sort & paginator to the View data.
    setTimeout(() => this.dataSource.sort = this.sort, 4000);
    setTimeout(() => this.dataSource.paginator = this.paginator, 4000);

    // Load the new action's data into the View:
    this.viewData = action.action;
    this.viewName = action.action.ActionName;
    this.refNumber = action.refNumber;

    // TODO: add uniquifiers/ids and use these as the sort for table

    const displayedColumns = this.viewData.Columns.map((c: { Name: any; }) => c.Name);
    displayedColumns[2] = 'Folder1';
    this.displayedColumns = displayedColumns;
    // tslint:disable-next-line: max-line-length
    const fetchedData = this.viewData.DataRows.map((r: { slice: (arg0: number, arg1: number) => { forEach: (arg0: (d: any, i: string | number) => any) => void; }; }) => {
      const row = {};
      r.slice(0, 9).forEach((d: any, i: string | number) => (row[this.displayedColumns[i]] = d));
      return row;
    });

    this.dataSource = new MatTableDataSource(fetchedData);
    this.loading = false;
  }


  // Stores the current Action, sort, and paginator in an ActionState object to be held in the action service's stateMap.
  cacheAction() {
    let actionState = new ActionState(this.viewData);

    // Determine the sort direction to store.
    let cachedStart: SortDirection;
    if (this.sort.direction == "desc") {
      cachedStart = 'desc';
    } else {
      cachedStart = 'asc';
    }

    // Create a Sortable so that we can re-apply this sort.
    actionState.sortable = {
      id: this.sort.active,
      start: cachedStart,
      disableClear: this.sort.disableClear
    }

    // Store the current pageIndex and pageSize.
    actionState.pageIndex = this.paginator.pageIndex;
    actionState.pageSize = this.paginator.pageSize;

    // Store the refNumber in the actionState for later retrieval.
    actionState.refNumber = this.refNumber;
    this.actionService.cacheAction(actionState);
  }

  ngOnInit() {
    // Subscribes to the action service's currentAction, populating this component with View data.
    this.actionService.currentAction.subscribe(action => this.loadAction(action));
  }
1

1 Answers

0
votes

You can add button instead of the checkbox, and in that button you pass the object of that row.

(click)="delete(obj)"

Now in your typescript file, you create a function where you only want the objects that are not the one that you received. Like:

delete (column) {
  this.array = this.array.filter(val => {
    return val.id != column.id 
    // this will maintain all objects that are not the one you received. 
  })
}

// If you use checkbox and press delete at the end. You can select multiple rows to delete so you need to pass an array. First you need to have &events that fire onde the row is selected, and push the values into an array. Or when you press delete, it pushes it to an array before filtering.

async delete () {
  await this.array.forEach( element => {
    if(element.check){
      this.deletedArray.push(element);
    }
  })
  
    this.array = this.array.filter(val => {
      for(var i = 0;i<this.deletedArray.length;i++){
        return val.id != this.deletedArray[i].id
      }    
  })
  
}

Hope I could help. I didn't look at your variables and properties, you need to put you arrays and var. That's only switching to yours. I only post the way I think to do with your problem