简体   繁体   中英

Angular 2 Material input focus not working

The inputs are inside of a modal dialog. I have no idea why it is not working. I looked at the official docs and it listed focus as something you can pass to the element but it's not working?

Does anyone know why?

Angular Material - Input Docs

<form class="example-form">

  <md-input-container class="example-full-width" style="width: 300px; padding: 5px; border-radius: 10px;">
    <input mdInput type="email" name="to" placeholder="Email">
    <md-error></md-error>
  </md-input-container>

  <md-input-container focus focused>
    <input mdInput type="text" name="a" placeholder="zzzz" focus focused (focus)="">
  </md-input-container>

</form>

Your attempts do not work because:

  • focused is a property driving the mat-focused class on mdInputContainer . You can use it to know whether your input is focused or not. You cannot use it to change the focus state.
  • focus is a method on mdInput that lets you programmatically focus the input. You can call the myInput.focus() with myInput being something like ViewChild('myInput') for instance.

But the simplest way to achieve what you want is to use the standard autofocus attribute :

<md-input-container>
    <input mdInput type="text" name="a" placeholder="zzzz" autofocus>
</md-input-container>

Have you try with cdkFocusInitial which will specify the element that will receive focus upon initialization

documentation can be found here

<form class="example-form">
  <md-input-container class="example-full-width" style="width: 300px; padding: 5px; border-radius: 10px;">
    <input mdInput #emailInput="matInput" type="email" name="to" placeholder="Email">
    <md-error></md-error>
  </md-input-container>
</form>

Then in the controller:

@ViewChild('emailInput') searchInput: MatInput;
....
ngAfterViewInit() {
  this.emailInput.focus();
}

What this.emailInput.focus() does is actually "elementRef.nativeElement.focus()" https://github.com/angular/material2/blob/master/src/lib/input/input.ts#L287

so you could do that your self like:

this.emailInput.nativeElement.focus()

I was struggling with the same issue. I was using F6 to open the dialog and I could not get the <input> to get focus. It turned out that I wasn't preventing the default behavior of F6 and F6 highlights the browser URL window; so it was stealing focus.

switch (event.keyCode) {
      case 117:
        event.preventDefault();
        this.openAddAveragesDialog();
        break;
      default:
        return;
    }

Also, no magic tag attribute works. Autofocus, Focused, Focus, whatever, no dice. I had to create a directive and use that in my input element. I got help with that using this answer.

Here is the element after adding the directive (numberOnly is another directive for only number input):

<md-input-container> <input mdInput [focus]="true" [numberOnly]="true"/></md-input-container>

**Edit : Adding Directive code as suggested by @Mackelito for clarity. Here is the directive I wrote using the answer I linked above. Keep in mind material has changed their tag labels to <input matInput> from <input md-input>

import {Directive, ElementRef, Inject, Input, OnChanges, OnInit,     Renderer} from '@angular/core';

@Directive({
  selector: '[focus]'
})

export class FocusDirective implements OnChanges, OnInit {
@Input()
focus: boolean;

constructor(@Inject(ElementRef) private element: ElementRef, public renderer: Renderer) {}

ngOnInit() {
    this.renderer.invokeElementMethod(this.element.nativeElement,   'focus', []);
}

public ngOnChanges() {
this.element.nativeElement.focus();
}

} 

You can usually set focus without any Typescript code, using the Template markup. But in the case of a Dialog, you'll need to use @Mackelito's solution with @ViewChild and ngAfterViewInit() .

I had to focus a TextArea that's inside a Menu, when that Menu appears. Fortunately, Menu has a (menuOpened) event I could bind to.

  <button mat-stroked-button color="accent" [matMenuTriggerFor]="addMenu"
    (menuOpened)="newTypes.focus()">
    Add
    <mat-icon class="dyna-dropdown-arrow">arrow_drop_down</mat-icon>
  </button>
  <mat-menu #addMenu="matMenu" [overlapTrigger]="false">
    <form [formGroup]="formGroup" (ngSubmit)="onFormSubmit()" novalidate (keydown.tab)="$event.stopPropagation()">
      <mat-form-field appearance="outline" (click)="$event.stopPropagation(); false;">
        <mat-label>New Pay Types</mat-label>
        <textarea #newTypes rows="6" matInput placeholder="New Pay Types" [formControl]="formGroup.controls['payTypes']" required></textarea>
        <mat-hint>Enter multiple Pay Types, separated by newlines</mat-hint>
        <mat-error *ngIf="formGroup.controls['payTypes'].invalid">Required</mat-error>
      </mat-form-field>
      <div fxLayout="row-reverse" fxLayoutGap="8px" fxLayoutAlign="start center">
        <button mat-stroked-button color="accent" type="submit" [disabled]="!formGroup.valid">Add</button>
        <button mat-button type="button">
          Cancel
        </button>
      </div>
    </form>
  </mat-menu>

The important part here is the (menuOpened)="newTypes.focus()" and we see the newTypes is a TemplateRef variable attached to the TextArea I want to focus marked as <textarea #newTypes .

Here's a screen shot that shows my menu opening up and it immediately gets focus to the Textarea inside it.

在此处输入图片说明

In input tag type

<input matInput [(ngModule)]="cityName" cdkFocusInitial>

That set its work 100%

If u won't to more info click here

Try to add some delay before set the input get focus. I've made this behavior a directive for your reference.

delay-focus.ts

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

@Directive({
  selector: '[delayFocus]'
})
export class DelayFocusDirective {

  @Input() delayFocusInterval;
  @Input() set delayFocus(condition: boolean) {
    if (condition) {
      console.log(this.delayFocusInterval);
      setTimeout(() => {
        this.el.nativeElement.focus();
      }, this.delayFocusInterval | 500);
    }
  }
  constructor(private el: ElementRef) { }
}

example

<input type="text" placeholder="Delay 100ms to get focus" delayFocus="true" delayFocusInterval="100">

You can try it here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM