Having a problem regarding the autofocus
attribute in cooperation with Angular. In detail I have a <form>
with an <input type="text">
on top which is initially focussed by a condition.
<input [attr.autofocus]="selection===-1"
[(ngModel)]="myForm.firstInpElem"
name="firstInpElem"
placeholder="firstInpElem">
This is working as expected (Chrome).
Then the form continuous with a selection between two options controlled by an <input type="radio">
.
Once a selection is made an according element is shown and then should get the autofocus
.
But that is not happening and I don't understand the reason for it.
Prepared a stackblitz with a working example but mainly below is the markup which won't work as expected
<h1>Forms example</h1>
<form>
<pre>Condition to focus "firstInpElem" is {{selection===1|json}}</pre>
<p>This input element is autofocussed on page load</p>
<p>
<input [attr.autofocus]="selection===-1"
[(ngModel)]="myForm.firstInpElem"
name="firstInpElem"
placeholder="firstInpElem">
</p>
<p>
Provide one of both information:<br>
<label>
<input [(ngModel)]="selection"
name="radioInpElem"
type="radio"
[value]="1">
Option 1
</label>
<br>
<label>
<input [(ngModel)]="selection"
name="radioInpElem"
type="radio"
[value]="2">
Option 2
</label>
</p>
<pre>Condition to focus "secondInpElem" is {{selection===1|json}}</pre>
<pre>Condition to focus "thirdInpElem" is {{selection===2|json}}</pre>
<p>
<input *ngIf="selection===1"
[attr.autofocus]="selection===1"
[(ngModel)]="myForm.secondInpElem"
name="secondInpElem"
placeholder="secondInpElem">
<input *ngIf="selection===2"
[attr.autofocus]="selection===2"
[(ngModel)]="myForm.thirdInpElem"
name="thirdInpElem"
placeholder="thirdInpElem">
</p>
</form>
<pre>{{myForm|json}}</pre>
If you check in the development tools (F12 tools), you will see that the new input control actually gets the autofocus
attribute, but it does not get the focus. That is because autofocus
sets the focus on an element when the page loads. In your case, the page is already loaded when the new element becomes visible.
What you can do instead is to set the focus programmatically on the new input element. In order to do that, you can define a common template reference variable for the two input elements having an ngIf
condition:
<input #inputElement *ngIf="selection === 1"
[(ngModel)]="myForm.secondInpElem"
name="secondInpElem"
placeholder="secondInpElem">
<input #inputElement *ngIf="selection === 2"
[(ngModel)]="myForm.thirdInpElem"
name="thirdInpElem"
placeholder="thirdInpElem">
and monitor the presence of these elements with ViewChildren
and the QueryList.changes
event. Each time one of the input element becomes visible, you set the focus on it:
@ViewChildren("inputElement") inputElements: QueryList<ElementRef>;
ngAfterViewInit() {
this.inputElements.changes.subscribe(() => {
this.inputElements.last.nativeElement.focus();
});
}
See this stackblitz for a demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With