ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.04k stars 13.51k forks source link

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

Closed isangha1 closed 10 months ago

isangha1 commented 5 years ago

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
cjorasch commented 5 years ago

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.

brandyscarney commented 5 years ago

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

msigwart commented 5 years ago

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.

fabiobeoni commented 4 years ago

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

larsblumberg commented 4 years ago

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)})

dreamclass commented 4 years ago

got the same issue.

anthony-bernardo commented 4 years ago

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>
}
Huluvu424242 commented 4 years ago

Was this issue fixed for ion-button too?

dexster commented 3 years ago

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

davidecampello commented 3 years ago

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

obnijnil commented 3 years ago

Still happens. Using @ionic/vue ^5.4.0.

avalanche1 commented 3 years ago

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

bboldi commented 3 years ago

@ionic/angular@5.6.8

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 ...

avalanche1 commented 3 years ago

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} />
bboldi commented 3 years ago

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.

iva2k commented 3 years ago

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

pleymor commented 3 years ago

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>
}
braincomb commented 2 years ago

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

tattivitorino commented 2 years ago

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 commented 2 years ago

[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);
  }
iva2k commented 2 years ago

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

avalanche1 commented 2 years ago

@iva2k "to other" like what?

gsoulie commented 2 years ago

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>
iva2k commented 1 year ago

@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.

JulienLecoq commented 1 year ago

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

folsze commented 1 year ago

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

JulienLecoq commented 1 year ago

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.

eliaharris commented 1 year ago
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.

mapsandapps commented 10 months ago

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.

ionitron-bot[bot] commented 9 months ago

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.