ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: autofocus property has no effect on ion-input for desktop

Open isangha1 opened this issue 6 years ago • 23 comments

Bug Report

Ionic version:

[x] 4.3.0

Current behavior:

If property autofocus is set to true for an <ion-input> element, the behavior for the <ion-input> element does not change when executing an ionic serve.

Expected behavior:

The app should focus on the <ion-input> element that has the property autofocus set to true.

Steps to reproduce:

  1. Insert <ion-input autofocus="true"></ion-input> to your HTML page
  2. Execute ionic serve in Ionic CLI
  3. Wait for browser to pop up with app and observe behavior

Ionic info:

Ionic:

   ionic (Ionic CLI)             : 4.2.1
   Ionic Framework               : @ionic/angular 4.3.0
   @angular-devkit/build-angular : 0.13.8
   @angular-devkit/schematics    : 7.2.4
   @angular/cli                  : 7.3.8
   @ionic/angular-toolkit        : 1.4.1

System:

   NodeJS : v8.12.0
   npm    : 6.4.1
   OS     : Windows 10

isangha1 avatar Apr 25 '19 16:04 isangha1

It also can lead to problems on iOS. I was using it in a PWA and when the modal was displayed the entire screen went blank with no way to navigate back since no buttons were available. It looked like the content might have been shifted up above the top because it still appeared in the inspector. Could not figure out a solution and eventually had to stop using the attribute.

I agree that it is important to get it working on desktop because that is the standard behavior for forms in that environment.

cjorasch avatar Apr 25 '19 17:04 cjorasch

Thanks for the issue! I was able to reproduce this for both the native input and ion-input inside of an ion-app. Outside of that tag it is working properly. Here's the Codepen I made to reproduce: https://codepen.io/brandyscarney/pen/axXZGV?editors=1010

brandyscarney avatar Apr 26 '19 15:04 brandyscarney

I believe this issue is fixed in @ionic/angular version 4.4.0. However, I also encountered the issue that is mentioned by @cjorasch. I opened another issue #18257.

msigwart avatar May 10 '19 19:05 msigwart

Hello, I can confirm the bug is still there using ionic core 4.11.x and on android too. Thanks.

fabiobeoni avatar Jun 11 '20 16:06 fabiobeoni

I can confirm this bug with Ionic 5.1.0 on Desktop/Safari, using the React IonInput component within an IonItem, IonContent, IonPage, IonApp (ordered from inside out).

Here's the workaround that I'm using:

useIonViewDidEnter(() => {setTimeout(() => inputRef.current.setFocus(), 100)})

larsblumberg avatar Jun 11 '20 17:06 larsblumberg

got the same issue.

dreamclass avatar Jul 02 '20 19:07 dreamclass

same issue on firefox linux with react

<IonItem>
  <IonInput autofocus={true}> </IonInput>
</IonItem>

Workaroud for react :

export const FormPage = () => {
    const inputRef = useRef<any>(null);

    useEffect(() => {
        setTimeout(() => inputRef.current.setFocus(), 100);
    })

    return <div>
        <h6>Name</h6>
        <IonItem>
            <IonInput ref={(ref) => inputRef.current = ref}> </IonInput>
        </IonItem>
    </div>
}

anthony-bernardo avatar Aug 06 '20 16:08 anthony-bernardo

Was this issue fixed for ion-button too?

Huluvu424242 avatar Sep 26 '20 18:09 Huluvu424242

Still happens. I'm using plain JS, no framework https://jsbin.com/jadosag/1/edit?html,js,output

dexster avatar Dec 10 '20 07:12 dexster

I have the same problem (using @ionic/angular: ^5.5.2) but I can see the focus on the input for a very short time, than the input loose the focus. I have only one autofocus input

davidecampello avatar Feb 22 '21 15:02 davidecampello

Still happens. Using @ionic/vue ^5.4.0.

obnijnil avatar Apr 12 '21 15:04 obnijnil

"@ionic/react": "^5.6.7". issue is present. doesn't work on web or android

avalanche1 avatar May 19 '21 18:05 avalanche1

@ionic/[email protected]

Same issue, works like 20% of the times on android ... and the problem is there for 3 or 4 years now, no reliable way to auto focus a field, had to write custom hack to do it from ionic 2 ...

bboldi avatar Jun 02 '21 18:06 bboldi

That's how I do it in react. Not really a hack, just not as straightforward:

  const firstNameInputRef = use_ref<HTMLIonInputElement>(null);
  useIonViewDidEnter(() => {
    firstNameInputRef.current?.setFocus();
  });
<IonInput ref={firstNameInputRef} />

avalanche1 avatar Jun 02 '21 19:06 avalanche1

Thanks! My point is, if there's a directive for it, should work as expected, anything else that adding that directive is a hack... this is a long existing issue.

bboldi avatar Jun 02 '21 19:06 bboldi

how do we stir it up so it gets worked on? having a framework that does not do basic things it promises is making this framework irrelevant very quickly

iva2k avatar Sep 16 '21 23:09 iva2k

same issue on firefox linux with react

<IonItem>
  <IonInput autofocus={true}> </IonInput>
</IonItem>

Workaroud for react :

export const FormPage = () => {
    const inputRef = useRef<any>(null);

    useEffect(() => {
        setTimeout(() => inputRef.current.setFocus(), 100);
    })

    return <div>
        <h6>Name</h6>
        <IonItem>
            <IonInput ref={(ref) => inputRef.current = ref}> </IonInput>
        </IonItem>
    </div>
}

I could not submit anymore with this workaround, but with a little modification, it worked:

Workaroud for react :

export const FormPage = () => {
    const inputRef = useRef<any>(null);

    useEffect(() => {
        setTimeout(() => inputRef.current.setFocus(), 100);
    })

    return <div>
        <h6>Name</h6>
        <IonItem>
            <IonInput ref={inputRef}> </IonInput>
        </IonItem>
    </div>
}

pleymor avatar Sep 17 '21 14:09 pleymor

Issue still present on both desktop and android mobile device, running "@ionic/vue": "^5.4.0"

braincomb avatar Dec 21 '21 01:12 braincomb

having the same problem with angular.. after all this time.. :(((( i'm running a pwa

Ionic CLI                     : 6.12.3 (/usr/local/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 6.1.15
   @angular-devkit/build-angular : 14.1.0
   @angular-devkit/schematics    : 14.1.0
   @angular/cli                  : 14.1.0
   @ionic/angular-toolkit        : 6.1.0

Utility:

   cordova-res : not installed
   native-run  : 1.6.0

System:

   NodeJS : v14.18.3 
   npm    : 6.14.15
   OS     : macOS

here's my input

<ion-input #inputCpf
                  autofocus="true"
                  tabindex="1"
                  placeholder="cpf:"
                  formControlName="cpf"
                  type="text"
                  inputmode="numeric"
                  enterkeyhint="done"
                  clearInput
                  maxlength="14"
                  simpleMask="999.999.999-99"></ion-input>

even tried the this.inputCpf.setFocus() on ngAfterViewInit and nothing? :(((

tattivitorino avatar Aug 14 '22 13:08 tattivitorino

[updating] - it seems like this did the trick.. but why should i wait after view init? autofocus on the input does nothing

ngAfterViewInit(): void {
    setTimeout(() => {
      console.log('set focus');
      this.myInput.setFocus();
    }, 100);
  }

tattivitorino avatar Aug 14 '22 13:08 tattivitorino

I gave up on Ionic, moving on to other, better things. Unsubscribe.

iva2k avatar Aug 28 '22 04:08 iva2k

@iva2k "to other" like what?

avalanche1 avatar Aug 29 '22 10:08 avalanche1

Just in case, it still doesn't work with the following Ionic / Capacitor configuration (tested on Android mobile device + browser)

Ionic:

   Ionic CLI                     : 6.19.0
   Ionic Framework               : @ionic/angular 6.2.5
   @angular-devkit/build-angular : 14.2.1
   @angular-devkit/schematics    : 14.2.1
   @angular/cli                  : 14.2.1
   @ionic/angular-toolkit        : 6.1.0

Capacitor:

   Capacitor CLI      : 4.1.0
   @capacitor/android : 4.1.0
   @capacitor/core    : 4.1.0

And there is nothing fancy in the view...

    <ion-item>
      <ion-label position="fixed">Name</ion-label>
      <ion-input requried [(ngModel)]="Username" autofocus="true"></ion-input>
    </ion-item>

gsoulie avatar Sep 07 '22 15:09 gsoulie

@avalanche1 Other things like Svelte-kit. My main reason starting to use Ionic was far back in time their "Creator" - online GUI editor, which was very handy for replacing wireframing with quick almost-functioning demo that was easy to fully finish offline. But "Creator" is abandoned and stuck on Ionic v3.0, with no replacement.

iva2k avatar Nov 12 '22 05:11 iva2k

Same issue here, just tried on iOS. autofocus does not work with Angular and Ionic 6.

JulienLecoq avatar May 17 '23 19:05 JulienLecoq

Still very inconsistent and weird with Ionic 7. For both android and ios. Web now works pretty well actually afaik, consistent rn.

There are two different approaches I found:

  1. set the autofocus property to true on ion-input, make the input-ion-item appear ngIf ionViewDidEnter
  2. set this.myInput.setFocus() when ionViewDidEnter

Both approaches are inconsistent and often do not work

folsze avatar Aug 18 '23 17:08 folsze

Still very inconsistent and weird with Ionic 7. For both android and ios. Web now works pretty well actually afaik, consistent rn.

There are two different approaches I found:

  1. set the autofocus property to true on ion-input, make the input-ion-item appear ngIf ionViewDidEnter
  2. set this.myInput.setFocus() when ionViewDidEnter

Both approaches are inconsistent and often do not work

I did not know about the 1., but the 2. is working for me. I'm using this solution since few months now, more exactly I'm putting the this.myInput.setFocus() part inside ionViewWillEnter instead of ionViewDidEnter so that it triggers the keyboard quicker.

JulienLecoq avatar Aug 18 '23 23:08 JulienLecoq

const useAutoFocusInput = () => {
  const isUnmounted = useRef(false);
  useEffect(() => {
    return () => {
      isUnmounted.current = true;
    };
  }, []);

  const waitForIonInput = useCallback(
    async (input: HTMLIonInputElement): Promise<HTMLInputElement | null> => {
      if (isUnmounted.current) {
        return null;
      }
      let nativeInput: HTMLInputElement | null = null;
      nativeInput = await input.getInputElement();
      if (nativeInput != null) {
        return nativeInput;
      } else {
        const immediate = new Promise((resolve) => window.setTimeout(resolve));
        return immediate.then(() => waitForIonInput(input));
      }
    },
    []
  );

  return (input: HTMLIonInputElement) => {
    return waitForIonInput(input).then((nativeInput) => {
      nativeInput?.focus();
      return true;
    });
  };
};

Hacky but this custom hook works great. This is react specific.

eliaharris avatar Sep 07 '23 14:09 eliaharris

Hi, thank you for submitting this issue. We agree that the behavior of the autofocus property can be unexpected.

The autofocus property on Input and Textarea sets the autofocus attribute on the native input element. However, this may not be sufficient for the element to be focused on page load.

One example of this is that if you are navigating to a page with an element with autofocus, the element will load before the page is visible, and it will not be able to focus. Also, each platform has different restrictions on when elements can be focused and if the keyboard will open when an element is focused.

We recommend that developers use the setFocus API with the ionViewDidEnter lifecycle method to focus an element once the view is guaranteed to be visible.

We have added an example to the docs of how to do this in each framework.

We have also updated the documentation for the autofocus property and setFocus method of Input, Textarea, and Searchbar to clarify the autofocus behavior and how to set the focus.

mapsandapps avatar Dec 07 '23 22:12 mapsandapps

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

ionitron-bot[bot] avatar Jan 06 '24 23:01 ionitron-bot[bot]