Set focus on an input with Ionic 2

2019-01-22 17:48发布

问题:

SOLVED :

import { Component, ViewChild} from '@angular/core';
import { Keyboard } from 'ionic-native';


@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('input') myInput ;

  constructor() {}

  ionViewDidLoad() {

    setTimeout(() => {
      Keyboard.show() // for android
      this.myInput.setFocus();
    },150);

 }

} 

1) import "ViewChild"

import {Component, ViewChild} from '@angular/core';

2) Create a reference to your input in your html template :

<ion-input #focusInput></ion-input>

3) Use @ViewChild to get access to the input component you just referenced previously.

@ViewChild('focusInput') myInput ;

4) Trigger the focus

Use the ionViewLoaded() method to trigger it each time the view/page is loaded.

setTimeout is needed

  ionViewLoaded() {

    setTimeout(() => {
      Keyboard.show() // for android
      this.myInput.setFocus();
    },150); //a least 150ms.

 }

4) Show the keyboard on Android

import { Keyboard } from 'ionic-native';

Call Keyboard.show() to call the keyboard on Android.

5) Show the keyboard on iOS

add this line to your config.xml to make it work on iOS :

<preference name="KeyboardDisplayRequiresUserAction" value="false" />

With the help from the great article of mhartington : http://mhartington.io/post/setting-input-focus/

回答1:

You don't need to import the 'Input' from 'angular/core'.

Simply:

import {Component,ViewChild} from '@angular/core';
import {NavController, TextInput } from 'ionic-angular';

@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('input') myInput: TextInput;

  constructor(private navCtrl: NavController) { }

  ionViewDidLoad() {

    setTimeout(() => {
      this.myInput.setFocus();
    },150);

 }

} 

And answering comment to Ciprian Mocanu:

It does not work in iOS :(

It works on iOS -> checked on iPhone 6 PLUS with iOS 10



回答2:

I think you should make a global directive for this as you will probably want this behavior more than once.

import {  ViewChild, ElementRef, Directive, OnInit } from '@angular/core';
import { Keyboard } from 'ionic-native';

@Directive({
    selector: '[autofocus]'
})
export class FocusInput implements OnInit {
    @ViewChild('myinput') input
    private focused: boolean
    ngOnInit(){
      this.focused = true
    }
    ionViewDidLoad() {
      if (this.focused) {
        setTimeout(()=>{
          this.input.setFocus()
          this.focused = false
          Keyboard.show()
        }, 300)
      }
    }
}

Now on you ion-input field just add the autofocus attribute

<ion-input #myinput type="..." placeholder="..."
            (keyup.enter)="someAction()"
            autofocus ></ion-input>


回答3:

None of the above was working for me. Here is how I resolved:

import {  ElementRef, AfterViewChecked, Directive } from '@angular/core';
import {Keyboard} from 'ionic-native';

@Directive({
    selector: '[autofocus]'
})
export class FocusInput implements AfterViewChecked {
    private firstTime: boolean = true;
    constructor(public elem: ElementRef) {
}

ngAfterViewChecked() {
  if (this.firstTime) {
    let vm = this;
    setTimeout(function(){

    vm.elem.nativeElement.firstChild.focus();
    vm.firstTime = false;
    Keyboard.show();

    }, 300)
  }
 }
}

Then in your ion-input field just add the autofocus attribute:

 <ion-input #input type="text" placeholder="..."
            [(ngModel)]="myBoundVariable"
            (keyup.enter)="myEnterKeyAction()"
            autofocus></ion-input>

Tested on Browser and Android not IOS yet but no reason it should not work.



回答4:

import {Component, ViewChild} from '@angular/core';
import {NavController} from 'ionic-angular';

@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('Comment') myInput ;

  constructor(private navCtrl: NavController) { }

  ionViewLoaded() {

    setTimeout(() => {
      this.myInput.setFocus();
    },150);

 }

}

Create a reference to your input in your template :

<ion-input #Comment>



回答5:

import {Component,ViewChild} from '@angular/core';
import {NavController} from 'ionic-angular';

@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
  @ViewChild('myInput') myInput ;

  constructor(private navCtrl: NavController) { }

  ionViewDidLoad() {

    window.setTimeout(() => {
      this.myInput.setFocus();
    }, 600); //SET A LONG TIME IF YOUR ARE IN A MODAL/ALERT

  }

}
<ion-input #myInput ></ion-input>


回答6:

I found this solution to also fix the problem that the keyboard is pushing the content away.

<ion-list>
<ion-item>
  <ion-label>Name</ion-label>
  <ion-input #inputRef type="text"></ion-input>
</ion-item>
<button ion-button (click)="focusMyInput(inputRef)">Focus</button>

  @ViewChild(Content) content: Content;

  focusMyInput(inputRef) {
    const itemTop = inputRef._elementRef.nativeElement.getBoundingClientRect().top;
    const itemPositionY = this.content.scrollTop + itemTop -80;

    this.content.scrollTo(null, itemPositionY, 500, () => {
      inputRef.setFocus();
    });
  }


回答7:

In my case, for some reason, ionViewLoaded() was not getting triggered. Tried ionViewDidLoad() and set the timer to 200 and it worked.

150 proved too early for me. Complete Solution:

import { Component, ViewChild } from '@angular/core';//No need to import Input

export class HomePage {

  @ViewChild('inputToFocus') inputToFocus;
  constructor(public navCtrl: NavController) {}

  ionViewDidLoad()
  {
    setTimeout(() => {
      this.inputToFocus.setFocus();
    },200)
  }  
}

And on the input tag:

<ion-input type="text" #inputToFocus></ion-input>


回答8:

For IOS and Android its fine working for me. put focus code in ionViewWillEnter().

import { Component, ViewChild, ElementRef } from '@angular/core';
 import { Keyboard } from '@ionic-native/keyboard';
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 @ViewChild("Input") inputEl: ElementRef;
 constructor(public keyboard:Keyboard){}

 ionViewWillEnter() { 
    setTimeout(() => {           
      this.inputEl.nativeElement.focus();
      this.keyboard.show();    
    }, 800); //If its your first page then larger time required 
}

Input tag in html file

 <ion-input type="text" #Input></ion-input>

And add this line to your config.xml to make it work on iOS :

<preference name="KeyboardDisplayRequiresUserAction" value="false" />


回答9:

If you need to set focus on an input at init component, set the class input-has-focus by default to ion-item just like this:

<ion-item class="input-has-focus">

That's all!