Reputation: 17451
I would like to have my input focused when it is 'activated'. The reason for that is that I am building a multi step form (like this one), which has multiple inputs that I am showing one by one. This is what I tried.
@Component(
...
template: `<input *ngIf="myCondition" id="myId" (load)="myLoad()">`){
myCondition = false;
load(){
document.getElementById("myId").focus();
}
}
The (load) event is not triggered when when myCondition later becomes true, it would seem to me to be the most logical DOM event in that case.
someFunction(){
this.myCondition = true;
document.getElementById("myId").focus();
}
This fails becomes the input element has not yet been loaded: document.getElementById("myId") returns undefined
. It does work if I setTimeOut
it one something like 100ms, but it is not a very elegant solution and the ideal timeout would be different on different clients.
Any other idea on how to achieve input focus when input is loaded in the DOM?
Upvotes: 3
Views: 3633
Reputation: 3722
For dynamically created inputs, i.e in a table, it can be done using @ViewChildren
changes listener
Template:
<tr *ngFor="let row of rows">
<td>
<input type="text" #name>
</td>
</tr>
Component
@Component({
selector: 'my-component',
templateUrl: './my-componentt.html',
styleUrls: ['./my-component.scss']
})
export class MyComponent implements OnInit, AfterViewInit {
@ViewChildren('name') nameInputs: QueryList<ElementRef>
ngAfterViewInit(): void {
this.nameInputs.changes.subscribe(()=>{
setTimeout(()=>{
this.nameInputs.last.nativeElement.focus()
});
})
}
}
Upvotes: 1
Reputation: 55443
Finally found the solution for your problem. I have made one directive called focus which takes care of current input.
Working DEMO : http://plnkr.co/edit/TzQNL6DcIJ9tjAntu6Si?p=preview
@Directive({
selector:'[focus]',
})
export class focusDirective{
constructor(private el:ElementRef, private rd:Renderer){
console.log(this.el.nativeElement);
rd.setElementStyle(el.nativeElement,'background','yellow');
}
ngAfterViewInit(){
this.el.nativeElement.focus();
}
}
Component.ts
@Component({
selector: 'my-app',
directives:[focusDirective],
template: `
<div *ngIf="step==1">
#{{step}}step :<input focus type="text">
</div>
<div *ngIf="step==2">
#{{step}}step : <input focus type="text">
</div>
<div *ngIf="step==3">
#{{step}}step : <input focus type="text">
</div>
<hr>
<button (click)="next()">NEXT</button>
`
})
export class App {
step=1;
next(){
++this.step;
}
}
Upvotes: 5