This should be simple but I can't find a solution, the closest answer i can find on SO is this: How do I programmatically set focus to dynamically created FormControl in Angular2
However this is way more convoluted that my requirements. Mine are simple. I have an input in the template like so:
<div *ngIf="someValue">
<input class="form-control" #swiper formControlName="swipe" placeholder="Swipe">
</div>
(Note, it's in an ngx-boostrap form-control group but I'm pretty sure this should not matter)
And I have a button that when clicked calls the following function:
onClick() {
this.renderer.invokeElementMethod(this.swiper.nativeElement, 'focus')
}
The goal is that when the button is clicked, my input element gets focus. here is the rest of my component (the relevant parts):
import { Component, ElementRef, ViewChildren, Renderer } from '@angular/core';
import { MyService } from wherever/my/service/is
export class MyClass {
@ViewChildren('swiper') input: ElementRef;
someValue: any = false;
constructor(private renderer: Renderer, service: MyService) {
this.service.getSomeData().subscribe(data => {
this.someValue = true;
}
}
onClick() {
this.renderer.invokeElementMethod(this.swiper.nativeElement, 'focus');
}
}
The error I get is:
ERROR TypeError: Cannot read property 'focus' of undefined
at RendererAdapter.invokeElementMethod (core.js:12032)
etc...
Any ideas?
(Angular 5 btw)
Note, I edited the code to more accurately reflect what is actually going on, I think there may be some synchronization issue.
You are using ViewChildren
which returns a QueryList
You need to use ViewChild
and your code should work.
export class MyClass {
@ViewChild('swiper') swiper: ElementRef;
constructor(private renderer: Renderer) {}
onClick() {
this.swiper.nativeElement.focus();
}
}
Adding a cdkFocusInitial
directive works for me:
<input
matInput
cdkFocusInitial />
This is how I solved it:
Template:
<input class="form-control" #swiper formControlName="swipe" placeholder="Swipe">
Component:
import { Component, ElementRef, ViewChild } from '@angular/core';
export class MyClass {
@ViewChild('swiper') swiper: ElementRef;
constructor() {}
onClick() {
this.swiper.nativeElement.focus();
}
}
The key being two things: first using the ViewChild not ViewChildren (thanks @Teddy Stern for that one) and second there is no need to use the Renderer at all, just directly use the nativeElement's focus function.
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