46

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/

Thomas
  • 1,189
  • 2
  • 11
  • 19
  • 1
    It does not work in iOS :( – Ciprian Mocanu Dec 28 '16 at 09:41
  • 2
    `ionViewLoaded()` did not work for me, I had to use `ionViewDidLoad()` – JCisar Mar 02 '17 at 03:18
  • Also, if you are testing this using `ionic serve` I believe seeing something like this 'Native: tried calling Keyboard.show, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator' in the console means it worked. – JCisar Mar 02 '17 at 03:19
  • When I do this I get "ngc: Error: Cannot assign to a reference or variable!" when building – Quintin Balsdon Apr 12 '17 at 14:21
  • Nice, but you may want to choose `ionViewDidEnter()` instead of `ionViewDidLoad()`. The first one fires every time the page is showed to the user. The second one fires just the first time loaded (so if the user is seeing a cached page, the event won't fire) – martom Oct 19 '18 at 01:12
  • @QuintinBalsdon That happens when you give it the same ref as a property you already have in the ts class. Consider changing the name of the ref i.e "#somethingElse" – Toby Okeke Nov 07 '18 at 05:13
  • 2
    Can you converte QUESTION in a new answer using "Post you answer" button? Put answer in question body is confuse, when i found your question I could not understand where an answer was. After put a new answer mark as correct so it will help people to better guide themselves :) – Guilherme Nascimento Mar 24 '19 at 02:13

10 Answers10

13

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

Yerkon
  • 3,580
  • 1
  • 13
  • 26
Mateusz Mateja
  • 249
  • 1
  • 4
  • 14
  • 2
    Actually, it won't work on iOS if you're using WKWebView, as described in this Cordova issue : https://issues.apache.org/jira/browse/CB-10376. The provided fix does work on UIWebView though. – jean-baptiste Feb 09 '17 at 12:21
  • This works on iOS 11.3.1 on iPhone 6S using WKWebView and `ionic-angular` 3.9.2. – Alex Steinberg May 17 '18 at 19:32
7

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>
davejoem
  • 3,310
  • 3
  • 17
  • 29
6

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.

Eric G
  • 927
  • 11
  • 21
5

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>
Kanomdook
  • 633
  • 6
  • 6
3
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>
2

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!

ThonyFD
  • 41
  • 7
1

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();
    });
  }
D.Roters
  • 191
  • 6
0

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>
alchi baucha
  • 772
  • 5
  • 15
0

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" />
Jaydeep Kataria
  • 715
  • 8
  • 21
-1

Setting timeout worked for me!

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

However, if a new input element is added it sets focus to first input only.

Andry
  • 14,281
  • 23
  • 124
  • 216