1

I'm trying to add multiple input text fields for a description that is being assigned to an array, but I'm having trouble using ngModel here. In the code below, when typing into the textbox it loses focus and I can only type one character at a time -- almost like its lagging. It seems to work when outputting the array to the console, however, when I add another text field element instead of the third element being blank it will return the previous value.

component.html

<div class="input-group mb-3" *ngFor="let descriptions of descriptionPool;let i = index">
          <span class="input-group-text" id="inputGroup-sizing-lg">Description #{{ i + 1 }}</span>
          <textarea class="form-control text-wrap" placeholder="Posts will use this description." [(ngModel)]="descriptionPool[i]" name="somename"></textarea>
          <button class="btn btn-primary text-light" (click)="addDescriptionField(descriptionPool[i])"> + </button>
          <button class="btn btn-primary text-light" (click)="delDescriptionField(i)"><i class="fas fa-trash-alt"></i></button>
</div>

component.ts

descriptionPool: Array<string> = [];

ngOnInit(): void {
     
      this.descriptionPool.push('');
      
  }

addDescriptionField(description: string) {
    console.log('descriptions? ' + JSON.stringify(this.descriptionPool));
    this.descriptionPool.push(description);
  }

  delDescriptionField(index: any) {
    this.descriptionPool.splice(index, 1);
    console.log('after deleting: ' + JSON.stringify(this.descriptionPool));
  }

The delete function works as expected. :)

Daniel
  • 53
  • 2
  • 8

1 Answers1

0

When you input some text the angular ngOnChange listener will run, so the ngFor indexes will rerendered and the focus will be lost. For avoid this issue a trackFn can be added to the ngFor. See https://angular.io/api/core/TrackByFunction for more details on the topic. Below the code solution for your issue:

In you html code define the ngFor a trackFn function that will be corrispond to the trackByFn function declared in the .ts file.

<div class="input-group mb-3" *ngFor="let descriptions of descriptionPool;let i = index; trackFn: trackByFn
">
      <span class="input-group-text" id="inputGroup-sizing-lg">Description #{{ i + 1 }}</span>
      <textarea class="form-control text-wrap" placeholder="Posts will use this description." [(ngModel)]="descriptionPool[i]" name="somename"></textarea>
      <button class="btn btn-primary text-light" (click)="addDescriptionField(descriptionPool[i])"> + </button>
      <button class="btn btn-primary text-light" (click)="delDescriptionField(i)"><i class="fas fa-trash-alt"></i></button>

And in the ts file declare the abowe mentioned trackByFn function:

trackByFn(i: number, items: any) {
return i //returning the index itself for avoiding ngFor to change focus after ngModelChange
}
vnapastiuk
  • 609
  • 7
  • 12