Ionic-framework: bug: ion-item padding prevents child ion-input focus

Created on 11 Jun 2020  路  20Comments  路  Source: ionic-team/ionic-framework

Bug Report

Ionic version:


[ ] 4.x
[x] 5.x

Current behavior:

While working with a community member, it was observed that when a floating label and ion-input are nested in an ion-item, users can tap the left padding of the item and it will:

  1. Animate the floating label to the top
  2. Present the device keyboard
  3. Not focus the input field

This behavior was captured for iOS with Ionic Angular 5.2.0.

Expected behavior:

When tapping the padding, it should place the input field in focus in addition to the other actions performed.

Steps to reproduce:

  1. Create an ion-item with an ion-label and ion-input as children.
  2. Set the position of the ion-label to floating.
  3. Open the app on an iOS device/simulator.
  4. Tap the far-left of the ion-item.

Please find a GIF of this behavior towards the bottom of this Issue.

Related code:

Reproduction Application: https://github.com/ehorodyski-ionic/ionic-floating-label-focus-issue

Other information:

ezgif-1-05eaea0df48e

Ionic info:

Ionic:

   Ionic CLI                     : 6.10.0 
   Ionic Framework               : @ionic/angular 5.2.0
   @angular-devkit/build-angular : 0.901.8
   @angular-devkit/schematics    : 9.1.8
   @angular/cli                  : 9.1.8
   @ionic/angular-toolkit        : 2.2.0

Capacitor:

   Capacitor CLI   : 2.2.0
   @capacitor/core : 2.2.0

Utility:

   cordova-res (update available: 0.14.0) : 0.11.0
   native-run                             : 1.0.0

System:

   NodeJS : v12.16.1 (/usr/local/bin/node)
   npm    : 6.14.4
   OS     : macOS Catalina
core bug

Most helpful comment

this might seem like a small issue but can impact UX quite heavy.... E.g. when your login form is based of two of these inputs and the user clicks on the password label, the keyboard shows up but the input goes into the void.

Any chance to add this to the 5.3.0 milestone?

All 20 comments

I have the same issue if clicking to the right of the label text (over the input) and on the label text.
Clicking anywhere on the ion-item should focus the input.

I have ionic version 5.2.1. Testet on iOS.

Could be a duplicate of #17694 ?

It appears this behavior is due delegatesFocus: true in https://github.com/ionic-team/ionic/blob/master/core/src/components/item/item.tsx#L25. delegatesFocus is a property that can be set on shadow roots. When this is true, focus events are delegated to the focusable element inside of the shadow dom.

For some reason, this is the native input inside of ion-input rather than ion-input itself.

In our app it seems to happen when clicking anywhere on the ion-item that wraps the ion-input (including the ion-label which for us is _not_ configured as a floating label). We do not see it happen on Android nor desktop Chrome.

From my testing in our app, Ionic v5.1.1 is the version where the behavior was introduced where clicking on the ion-item outside of the ion-input (such as on an ion-label) automatically puts focus in the ion-input. Like @liamdebeasi, I was suspicious of the delegatesFocus that was introduced being the change which introduced this behavior.

this might seem like a small issue but can impact UX quite heavy.... E.g. when your login form is based of two of these inputs and the user clicks on the password label, the keyboard shows up but the input goes into the void.

Any chance to add this to the 5.3.0 milestone?

I can confirm this, it's quite annoying...
A fix would be great!

We can confirm this as well and it is impacting users of our app.
A fix would be very much appreciated

Edit:
I figured it out.

At the top of app.tsx (not in a function):

const oldAttachShadow = HTMLElement.prototype.attachShadow;

HTMLElement.prototype.attachShadow = function (options) {
  if (this.tagName === "ION-ITEM") {
    oldAttachShadow.bind(this)({ ...options, delegatesFocus: false });
  } else {
    oldAttachShadow.bind(this)(options);
  }
};

The code above disable delegatesFocus on ion-item shadow roots

Hi @michaelmesser

Can you please provide some additional context and information. Where exactly did you put those lines of code? Where is the declaration of the oldAttachShadow variable?

@iphilgood I updated the code to define oldAttachShadow. I put it at the top (not in any function) of my app.tsx.

@michaelmesser Unfortunately, you fix didn't work for me. The behaviour was exactly the same after applying it. I assume you're working with react? 馃 The reason I'm asking is because I'm using @ionic/angular. Do you think this could also have an impact?

To provide some additional information we usually use a markup like this for our forms:

<ion-list>
  <ion-item (click)="onTitleClicked()" button>
    <ion-label position="floating">
      Title
    </ion-label>
    <ion-input [value]="item.title" readonly></ion-input>
    <ion-button
      *ngIf="item.title"
      slot="end"
      fill="clear"
      size="small"
      (click)="resetTitle($event)"
    >
      <ion-icon name="md-close"></ion-icon>
    </ion-button>
  </ion-item>
</ion-list>

Unfortunately, a single click on the whole item (somewhere next to label) doesn't trigger an event. Sometimes you need to click like four times until the event gets triggered. If you click on the label in most of the cases the event gets triggered immediately.

While testing out different versions from @ionic/angular I noticed the last working version is v5.0.5. I tried to narrow down the issue even further by having a look at the introduced changes in v5.0.6. When you compare the tags I didn't notice anything special. At this point I'm not even sure if this is the same issue? 馃

This issue really has an impact on the usability of our clients and a soon fix would be very nice. If anybody has an additional hint I would even create a PR, so please let me know.

@iphilgood My code prevents ion-item's shadow from having delegatesFocus set to true. I am using react but my code should still work for angular. Is your problem caused by delegatesFocus on ion-item's shadow being true? Did you verify that the line with delegatesFocus: false is being called at some point?

@michaelmesser I can confirm that your workaround works in an angular environment.
@iphilgood I placed the snippet in the constructor of app.component.ts

@michaelmesser @capc0 thanks for your fast replies 馃帀 I'm going to try that out and keep you updated. Maybe my issue is even something else. 馃

@michaelmesser @capc0 I've encountered a different bug than this 馃檲 But I can confirm that your workaround fixed this issue 馃憤馃徑 Thanks again.

Hi all, I've created a dev build with a potential fix if you could test it out. During my testing it seems to fix this bug:

# for an angular app
npm i @ionic/[email protected] --save

# for a react app
npm i @ionic/[email protected] --save
npm i @ionic/[email protected] --save

# for a stencil / vanilla JS app
npm i @ionic/[email protected] --save

Thanks!

I can confirm that @ionic/[email protected] resolves this issue within the repro posted as part of this issue. Thank you @brandyscarney!

Confirmed :-)

Thanks for confirming! I created a new dev build if anyone wants to test it: 5.4.0-dev.202008212054.e0116be

This is essentially the same but I removed the blur/focus events from firing when they shouldn't be. We also found out this is a WebKit bug reported and fixed here: https://bugs.webkit.org/show_bug.cgi?id=214859

It should be fixed in iOS 14 but we'll still merge in this fix for older versions. I'm planning on Monday if no issues come up and then it will be in the 5.3.2 release. 馃檪

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.

Was this page helpful?
0 / 5 - 0 ratings