Search code examples
javascriptangulartypescriptangular-reactive-formsformarray

Is there a better way to highlight the selected formarray item in Reactive Form?


I have a list of players and on selecting a player name , I'm displaying the respective player details by introducing a boolean flag (isPlayerSelected) in each formGroup . One disadvantage with this approach is that the page response is slow (when there are more number of items) as it has to update the boolean flag in each formGroup by using patchValue . Is there a better way to do instead of introducing boolean flag?

Please help . I have attached the StackBlitz link as well

selectPlayer(player: any) {
    player.isPlayerSelected = !player.isPlayerSelected;
    const selectedPlayer = this.playerDetailsControls.find(
      (item) => player?.id === item.get('id')?.value
    );
    const otherPlayers = this.playerDetailsControls.filter(
      (item) => player.id !== item.get('id')?.value
    );
    selectedPlayer?.patchValue({
      isPlayerSelected: true,
    });
    otherPlayers.map((item) => {
      item?.patchValue({
        isPlayerSelected: false,
      });
    });
  }

HTML

<form [formGroup]="form">
    <div formArrayName="playerDetails">
      <div *ngFor="let control of playerDetailsControls; let i = index">
        <div [formGroupName]="i">
          <div *ngIf="control.get('isPlayerSelected')?.value">
            Player Name : <input formControlName="playerName" /><br /><br />
            Role: <input formControlName="role" /><br /><br />
            Country: <input formControlName="country" /><br /><br />
            <hr />
          </div>
        </div>
      </div>
    </div>
  </form>

enter image description here

Stackblitz


Solution

  • If you get the selected player form control, then you can directly use it in the form

    selectedPlayer: FormGroup;
    
    selectPlayer(player: any) {
      player.isPlayerSelected = !player.isPlayerSelected;
      this.selectedPlayer = this.playerDetailsControls.find(
        (item) => player?.id === item.get('id')?.value
      ) as FormGroup;
    }
    
    <form *ngIf="selectedPlayer" [formGroup]="selectedPlayer">
      Player Name : <input formControlName="playerName" /><br /><br />
      Role: <input formControlName="role" /><br /><br />
      Country: <input formControlName="country" /><br /><br />
      <hr />
      <button (click)="save()" [disabled]="!form.valid">Save</button>
    </form>