Set focus on <input> element

↘锁芯ラ 提交于 2019-12-03 10:27:26

问题


I am working a front-end application with Angular 5, and I need to have a search box hidden, but on click of a button, the search box should be displayed and focused.

I have tried a few ways found on StackOverflow with directive or so, but can't succeed.

Here is the sample code:

@Component({
   selector: 'my-app',
   template: `
    <div>
    <h2>Hello</h2>
    </div>
    <button (click) ="showSearch()">Show Search</button>
    <p></p>
    <form>
      <div >
        <input *ngIf="show" #search type="text"  />            
      </div>
    </form>
    `,
  })
  export class App implements AfterViewInit {
  @ViewChild('search') searchElement: ElementRef;

  show: false;
  name:string;
  constructor() {    
  }

  showSearch(){
    this.show = !this.show;    
    this.searchElement.nativeElement.focus();
    alert("focus");
  }

  ngAfterViewInit() {
    this.firstNameElement.nativeElement.focus();
  }

The search box is not set to focus.

How can I do that?


回答1:


Modify the show search method like this

showSearch(){
  this.show = !this.show;  
  setTimeout(()=>{ // this will make the execution after the above boolean has changed
    this.searchElement.nativeElement.focus();
  },0);  
}



回答2:


You should use html autofocus for this:

<input *ngIf="show" #search type="text" autofocus /> 

Note: if your component is persisted and reused it will only autofocus the first time the fragment is created. This can be overcome by having a global dom listener that checks for autofocus attribute inside a dom fragment when it is attached and then reapplying it or focus via javascript.




回答3:


This directive will instantly focus and select any text in the element as soon as it's displayed. This might require a setTimeout for some cases, it has not been tested much.

import { Directive, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: '[appPrefixFocusAndSelect]',
})
export class FocusOnShowDirective implements OnInit {

  constructor(private el: ElementRef) {
    if (!el.nativeElement['focus']) {
      throw new Error('Element does not accept focus.');
    }
  }

  ngOnInit(): void {
    const input: HTMLInputElement = this.el.nativeElement as HTMLInputElement;
    input.focus();
    input.select();
  }
}

And in the HTML:

 <mat-form-field>
     <input matInput type="text" appPrefixFocusAndSelect [value]="'etc'">
 </mat-form-field>



回答4:


I'm going to weigh in on this (Angular 7 Solution)

input [appFocus]="focus"....

import {AfterViewInit, Directive, ElementRef, Input,} from '@angular/core';

@Directive({
  selector: 'input[appFocus]',
})
export class FocusDirective implements AfterViewInit {

  @Input('appFocus')
  private focused: boolean = false;

  constructor(public element: ElementRef<HTMLElement>) {
  }

  ngAfterViewInit(): void {
    // ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
    if (this.focused) {
      setTimeout(() => this.element.nativeElement.focus(), 0);
    }
  }
}



回答5:


To make the execution after the boolean has changed and avoid the usage of timeout you can do:

import { ChangeDetectorRef } from '@angular/core';

constructor(private cd: ChangeDetectorRef) {}

showSearch(){
  this.show = !this.show;  
  this.cd.detectChanges();
  this.searchElement.nativeElement.focus();
}


来源:https://stackoverflow.com/questions/50006888/set-focus-on-input-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!