Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewChild and focus()

I have a component which contains a textarea which is hidden by default :

<div class="action ui-g-2" (click)="toggleEditable()">edit</div>
<textarea [hidden]="!whyModel.inEdition" #myname id="textBox_{{whyModel.id}}" pInputTextarea focus="true" [(ngModel)]="whyModel.description"></textarea>

When I click on the "edit" div I want to show the textarea and put focus on it :

@ViewChild('myname') input: ElementRef;
...
private toggleEditable(): void {
  this.whyModel.toggleEditable();
  this.input.nativeElement.focus();
}

The "show" part is working but not the focus part. What do I miss?

like image 760
Lempkin Avatar asked Sep 05 '17 09:09

Lempkin


2 Answers

Bindings are only updated when change detection runs, which is usually after an event handler completed. This is to late for your use case, because the event handler itself depends already on the effect of change detection.

You can enforce change detection immediately (synchronically) by calling detectChanges()

constructor(private cdRef:ChangeDetectorRef) {}

@ViewChild('myname') input: ElementRef;
...
private toggleEditable(): void {
  this.whyModel.toggleEditable();
  this.cdRef.detectChanges();
  this.input.nativeElement.focus();
}
like image 94
Günter Zöchbauer Avatar answered Oct 06 '22 01:10

Günter Zöchbauer


You can also 'force' the focus with AfterViewCheck. I simplified your code for the demo purposes:

Typescript:

  editable;

  @ViewChild('myname') input: ElementRef;
  private toggleEditable(): void {
      this.editable = !this.editable;
   }

   ngAfterViewChecked(){
     if(this.editable){
          this.input.nativeElement.focus();
     }
   }

HTML

<div class="action ui-g-2" (click)="toggleEditable()">edit</div>
<br>
<textarea [hidden]="!editable" #myname id="textBox_{{id}}" pInputTextarea
   focus="true" [(ngModel)]="description"></textarea>

Stackblitz example

like image 36
Vega Avatar answered Oct 06 '22 00:10

Vega