Reputation: 1588
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?
Upvotes: 12
Views: 27978
Reputation: 2195
If you are trying to focus on a custom Angular component (like a custom modal/dialog implementation nested inside another component), you may need to add a tabIndex
to it:
You can either do this directly in the template. E.g.:
<div class="my-modal" tabIndex="0">...</div>
Or via a @ViewChild
decorator in your component Typescript code. E.g.:
...
@ViewChild("myModal") myModal: ElementRef;
...
ngAfterViewInit()() {
this.myModal.nativeElement.tabIndex = "0";
this.myModal.nativeElement.focus();
}
Hope this helps someone!
Upvotes: 0
Reputation: 1
You can use @ViewChild
and focus()
to focus on a particular element.
It can be used like this:
In HTML file (abc.component.html)
<form #data="ngForm">
<input class="text-field" type="text" name="name" >
<input class="text-field" type="text" name="surname">
<input class="text-field" type="text" name="company">
</form>
<button type="submit" value="Submit" (click)="submitData(data.value)">Submit</button>
<input class="text-field" type="text" name="City" #setFocusField>
<input class="text-field" type="text" name="State">
In TypeScript file (abc.component.ts)
@ViewChild('setFocusField') setFocusField: any;
submitData(data:any){
this.setFocusField.focus();
}
When you click on the submit button, the focus will be set to the field "City".
Another way to achieve this:
In above code, instead of any
on ViewChild
field, we can use ElementRef
.
In that case typescript file changes will be as follow:
(abc.component.ts)
@ViewChild('setFocusField') setFocusField: ElementRef;
submitData(data:any){
this.setFocusField.nativeElement.focus();
}
Upvotes: 0
Reputation: 28708
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>
Upvotes: 3
Reputation: 657308
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();
}
Upvotes: 17