0

I have Angular 7 with Material table:

<mat-table #table [dataSource]="dataSource" matSort>

    <ng-container matColumnDef="Extension"> 
        <mat-header-cell *matHeaderCellDef (click)="sortData('agentExtn')" class="pointer" [ngClass]="getSortClass('agentExtn')" id="ExtnHeader" >
        {{ ExtnHeader | translate }} <div></div >
        </mat-header-cell> <mat-cell *matCellDef="let element" class="ExtnCol"> {{ element.Extn }} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="Play"> 
        <mat-header-cell *matHeaderCellDef>{{ 'MAIN.PLAY' | translate }}</mat-header-cell> 
        <mat-cell *matCellDef="let element"> 
            <button id="play" class="float-right icon-link" mat-icon-button matTooltip="{{ 'MAIN.PLAY' | translate }}" (click)="    $event.stopPropagation(); playRecord(element.recordId)" >    
                <i class="fa fa-play" aria-hidden="true"></i> 
            </button>
        </mat-cell> 
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>

    <mat-row *matRowDef="let row; columns: displayedColumns" [ngClass]="{ 'highlight-row': selectedRow == row.MediaRecord.$.recordId, pointer: true }" (click)="showRecordDetailsDialog(row)">
    </mat-row>
</mat-table>

So rows looks similar to following:

enter image description here

On the click of the Play icon, an audio element is displayed somewhere else on the screen.

Now, I want the Play icon of that particular row to replaced by Pause icon. Also, if the user clicks Play icon of another row, the previous row with Pause icon should be replaced by Play icon.

How can I do this? How can I get reference to the particular rows and replace those particular icons?

user5155835
  • 4,392
  • 4
  • 53
  • 97

2 Answers2

0

Make another array isPlaying[] of booleans initialized to false (or add a new column to the existing one) where you save the state of each row, and make the icon change based on that array.Make another array (or add a new column to the existing one) where you save the state of each row, and make the icon change based on that array.

<mat-cell *matCellDef="let element; let i = index"> 
    <button id="play" class="float-right icon-link" mat-icon-button matTooltip="{{ 'MAIN.PLAY' | translate }}" (click)="    $event.stopPropagation(); playRecord(element.recordId, i)" >    
        <i *ngIf="isPlaying[i]=false" class="fa fa-play" aria-hidden="true"></i> 
        <i *ngIf="isPlaying[i]=true" class="fa fa-pause" aria-hidden="true"></i> 
    </button>
</mat-cell>

Your playRecord should play/pause according to isPlaying[i], that's why I passed i as a parameter.

Ala Abid
  • 2,256
  • 23
  • 35
0

I would suggest do put an ui layer on top of each row entry.

For example, you have the element Audio

interface Audio {
    name: string;
    song: any;
}

Then extend Audio like:

interface UIAudio extends Audio {
    isPlaying: boolean;
}

Map the dataSource

dataSource = dataSource as UIAudio[];

Now you can check in the template for isPlaying, like:

Html:

<ng-container matColumnDef="Play"> 
    <mat-header-cell *matHeaderCellDef>{{ 'MAIN.PLAY' | translate }}</mat-header-cell> 
    <mat-cell *matCellDef="let element"> 
        <button id="play" class="float-right icon-link" mat-icon-button matTooltip="{{ 'MAIN.PLAY' | translate }}" (click)="    $event.stopPropagation(); playRecord(element)" >    
            <i class="fa fa-{{element.isPlaying ? 'pause' : 'play'}}" aria-hidden="true"></i> 
        </button>
    </mat-cell> 
</ng-container>

TS

playRecord(element) {
    element.isPlaying = true;
}

You could also create a Component for Audio.