web-dev-qa-db-ja.com

<input>要素にフォーカスを設定します

Angular 5を使用してフロントエンドアプリケーションを操作しています。検索ボックスを非表示にする必要がありますが、ボタンをクリックすると、検索ボックスが表示され、フォーカスされます。

StackOverflowで見つかったいくつかの方法をディレクティブなどで試しましたが、成功しません。

サンプルコードは次のとおりです。

@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();
  }

検索ボックスがフォーカスに設定されていません。

どうやってやるの?

36
Bob

Show searchメソッドを次のように変更します

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

これにはhtml autofocusを使用する必要があります。

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

注:コンポーネントが永続化されて再利用される場合、フラグメントが最初に作成されたときにのみオートフォーカスされます。この問題は、domフラグメントがアタッチされたときにdomフラグメント内のautofocus属性をチェックするグローバルdomリスナーを使用し、それを再適用するか、JavaScriptを介してフォーカスすることで克服できます。

18
N-ate

このディレクティブは、表示されるとすぐに要素内のテキストを即座にフォーカスして選択します。これには、場合によってはsetTimeoutが必要になる場合がありますが、あまりテストされていません。

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();
  }
}

そしてHTMLで:

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

これについて検討します(Angular 7 Solution)

入力[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

ブール値が変更された後に実行を行い、タイムアウトの使用を回避するには、次のようにします。

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

constructor(private cd: ChangeDetectorRef) {}

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