Search code examples
javascriptangularviewchild

Focus on element in ngFor is further off each item added to collection


I'm using a @ViewChild to focus to the last question asked and answered in a for loop in Angular. This works perfectly for the first question asked. However when I ask second question the focus not on the element and is off a few pixels, then asking a another question doubles that offset and so on.

I'm using this question on SO to build a solution and my code for my solution is as follows:

HTML:

<div tabindex="1" #questionDiv class="faq-item" *ngFor="let faq of faqsAnswered">
    <div *ngIf="faq.question" class="ml-auto mr-3 col-lg-8 faq-user">
        {{faq.question}}
    </div>
    <div *ngIf="faq.answer" class="col-lg-8 ml-3 faq-response">
        {{faq.answer}}
        <p *ngIf="!feedbackGiven" class="mt-3">Was this answer helpful? <br /> <i class="fad fa-thumbs-up mr-3 text-success" (click)="provideFeedback(true)"></i> <i class="fad fa-thumbs-down text-danger" (click)="provideFeedback(false)"></i></p>
        <p *ngIf="feedbackGiven" class="mt-3">Thank you for your feedback!</p>
    </div>
</div>

CSS:

.faq-item {
    outline: none;
}

.faq-chat {
    max-height: 500px;
    overflow-x: hidden;
    overflow-y: auto;
}

And Typescript:

export class FaqComponent implements OnInit {

  @ViewChildren('questionDiv') questionDivs: QueryList<ElementRef>;

  // tslint:disable-next-line: max-line-length
  constructor() { }

  // tslint:disable-next-line: use-lifecycle-interface
  ngAfterViewInit() {
    this.questionDivs.changes.subscribe(() => {
      if (this.questionDivs && this.questionDivs.last) {
        this.questionDivs.last.nativeElement.focus();
      }
    });
  }
}

Solution

  • In order to be focusable, your "divs" should have tabindex. At least negative but it has to be present.

    <div *ngFor="let item of elements" #questionDiv 
         tabindex="-1" class="list-item">
      {{item}}
    </div>
    

    All other things in your question seem to be valid. Here is an example of the implementation I think you've been looking for.

    https://stackblitz.com/edit/focus-last-child

    Feel free to fork or modify it if there are some specific conditions that I didn't take into account or ask questions