Focus input programatically + scroll


#1

I’ve an app where I need to set focus on a certain input field. The first problem I’ve found was setting the focus (with setfocus method) didn’t do anything. Tried in the class constructor and also in the ionviewdidload event. After doing some research and reading some posts, I ended up calling the method in a timer. The thing is, depending on the view, sometimes a delay of 100 ms do the trick, but in some others I have to use a bigger one (eg: 500 ms). Also, I have to call Keyboard.Open in order to get my device keyboard up. What’s the reason for this?
The second problem is, although the keyboard pops up, the view does not scroll as expected like it does when you focus on the field manually. Is there any way I can force it?
Thanks!!!


#2

Second problem -
Are you trying to scroll your container/view on certain event?
Try looking at this solution (I haven’t tested it in iOS yet). You can call that function after required event gets trigerred.

First problem -
If it helps, look at this solution.

Mine implementation -

home.html-

<ion-input #messageInput placeholder="Type your message" name="inputMessage" on-return="sendMessage()" 
    (ngModelChange)="autoSuggest($event)">
</ion-input>

home.ts-

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

export class HomePage {
    @ViewChild("messageInput") public messageInput: ElementRef;

    public setInputFocus(){
        var elem:any = this.messageInput;
        elem._native.nativeElement.focus(); // Keep the focus on input field.
    }

The setInputFocus is the function which focusses on input field. You need to call it from some event or function (may be from SendMessage()).
You can set blurOnSubmit={false} to your <ion-input> if you want to retain keyboard opened after you submit message (using Enter).


#3

Hi @sujit77! Thanks for your quick reply. I couldn’t answer before because I didn’t have the chance to test it.
Regarding the first problem, yes, I’m using the same implementation that you are referring:

  @ViewChild('phoneNumberInput') phoneNumberInput;
  
  ionViewDidLoad() {

    this.platform.ready().then(() => {

      // We need to use a timeout in order to set the focus on load
      setTimeout(() => {
        this.keyboard.show(); // Needed for android. Call in a platform ready function
        this.phoneNumberInput.setFocus();
      },150);

    });

  }

My problem here is, in some pages, I have to increment the timeout (eg: 500ms) in order to get it working. I’m I using the wrong lifecycle event? I want to get the focus on the input as soon as the view is displayed.

The second problem is that, although I managed to get the focus in the input and the keyboard is displayed, the view doesn’t scroll and the input is hidden by the keyboard. I thought it might be a method to scroll the view to make a certain control visible or similar. Is there any?

Thanks!


#4

You are using correct page lifecycle event ionViewDidLoad.
Have you tried only followings code inside ionViewDidLoad() without platform.ready() and setTimeout() ?

this.keyboard.show(); // Needed for android. Call in a platform ready function
this.phoneNumberInput.setFocus();

I don’t think that device keyboard would overlap with active input field.
Try keeping your HTML strcture in following format -

<ion-header>
    // header codes
</ion-header>

<ion-content>
    // codes for contents
</ion-content>

<ion-footer>
    // Keep your input field here
</ion-footer>

If you need to scroll the view only to bottom, follow first solution of this solution which works perfectly for me.


#5

Hi @sujit77 and thanks again for your response. Yes, I’ve tried everything you recommend and the only way to get it working is with the setTimeout. Again, sometimes, I have to use a longer timeout to get it working (eg: 500 ms.). The problem with this is that, sometimes, it doesn’t work and also, if the time is too long, it is perceivable by the user.

On the other hand, I think I didn’t explain very well the problem with scroll. Imagine I have a header, some text, some vertical inputs and a button at the bottom (the entire layout fills the screen). If you focus manually on first input (which is in the middle-bottom of the screen) the view scrolls automatically, so the keyboard doesn’t hide the field. But if I focus the field programatically (setFocus), besides the problem that I mentioned before, when it works, the caret gets displayed in the fields, the keyboard pops up, but the view doesn’t scroll, so the field gets hidden by the keyboard. The input cannot be at the bottom. I couldn’t manage yet to get this working.


#6

Your request seems similar(to some extent) to the one reported here.
Please try some workarounds mentioned by other users.

As you mentioend that your view is not scrolling up and getting overlapped by keyboard, try adding this code under ready() but outside of setTimeout() -

this.keyboard.disableScroll(false);