Dev
Dev

Reputation: 687

Angular 2/4 set focus on input element

How can I set focus on an input by (click) event? I have this function in place but I'm clearly missing something (angular newbie here)

sTbState: string = 'invisible';
private element: ElementRef;
toggleSt() {
  this.sTbState = (this.sTbState === 'invisible' ? 'visible' : 'invisible');
  if (this.sTbState === 'visible') {
    (this.element.nativeElement).find('#mobileSearch').focus();
  }
}

Upvotes: 18

Views: 37022

Answers (4)

M.Laida
M.Laida

Reputation: 1938

try this.

//on .html file
<button (click)=keyDownFunction($event)>click me</button>

// on .ts file
// navigate to form elements automatically.
keyDownFunction(event) {
    // specify the range of elements to navigate
    let maxElement = 4;
    if (event.keyCode === 13) {
        // specify first the parent of container of elements
        let container = document.getElementsByClassName("myForm")[0];
        // get the last index from the current element.
        let lastIndex = event.srcElement.tabIndex ;
        for (let i=0; i<maxElement; i++) {
            // element name must not equal to itself during loop.
            if (container[i].id !== event.srcElement.id && 
                lastIndex < i) {   
                lastIndex = i;                 
                const tmp = document.getElementById(container[i].id);
                (tmp as HTMLInputElement).select();
                tmp.focus();
                event.preventDefault();
                return true;
            }
        }           
    }
}

Upvotes: 1

Kapil Thakkar
Kapil Thakkar

Reputation: 870

Get input element as native elements in ts file.

//HTML CODE

<input #focusTrg />
<button (click)="onSetFocus()">Set Focus</button>

//TS CODE
@ViewChild("focusTrg") trgFocusEl: ElementRef;

  onSetFocus() {
     setTimeout(()=>{
      this.trgFocusEl.nativeElement.focus();
    },100);
  }

we need to put this.trgFocusEl.nativeElement.focus(); in setTimeout() then it'll work fine otherwise it will throw undefined error.

Upvotes: 11

Doguhan Uluca
Doguhan Uluca

Reputation: 7333

You can use the @ViewChild decorator for this. Documentation is at https://angular.io/api/core/ViewChild.

Here's a working plnkr: http://plnkr.co/edit/KvUmkuVBVbtL1AxFvU3F

This gist of the code comes down to, giving a name to your input element and wiring up a click event in your template.

 <input #myInput />
 <button (click)="focusInput()">Click</button>

In your component, implement @ViewChild or @ViewChildren to search for the element(s), then implement the click handler to perform the function you need.

export class App implements AfterViewInit {
  @ViewChild("myInput") inputEl: ElementRef;

  focusInput() {
    this.inputEl.nativeElement.focus()
  }

Now, click on the button and then the blinking caret will appear inside the input field. Use of ElementRef is not recommended as a security risk, like XSS attacks (https://angular.io/api/core/ElementRef) and because it results in less-portable components.

Also beware that, the inputEl variable will be first available, when ngAfterViewInit event fires.

Upvotes: 20

Mohamed Ali RACHID
Mohamed Ali RACHID

Reputation: 3297

try this :

in you HTML file:

<button type="button" (click)="toggleSt($event, toFocus)">Focus</button>

<!-- Input to focus -->
<input #toFocus> 

in your ts File :

sTbState: string = 'invisible';

toggleSt(e, el) {
  this.sTbState = (this.sTbState === 'invisible' ? 'visible' : 'invisible');
  if (this.sTbState === 'visible') {
    el.focus();
  }
}

Upvotes: 1

Related Questions