shepherd icon indicating copy to clipboard operation
shepherd copied to clipboard

Targeted input loses focus on android and ios devices

Open alexd16 opened this issue 4 years ago • 33 comments

Hey, I am having a weird issue in mobile devices that I cannot figure out.

Basically I have one step that targets an input element, and it is expected that the user types something to proceed to the next step.

This works fine when trying on desktop, but on android or ios when I click the input element to start typing the input immediately loses focus. On android is very obvious that the keyboard shows for a little bit and disappears

Here's a simple codesanbox showing the issue: https://codesandbox.io/s/silly-ritchie-o0w88?file=/src/index.js

The issue doesn't appear in the browser's responsive mode, only in the actual devices.

One thing that I noticed is that If I remove the 'shepherd-element' element from the dom it works fine. Not sure if this indicates something relevant

Thanks

alexd16 avatar Sep 08 '20 18:09 alexd16

@alexd16 this sounds like an issue with focus. We focus trap the input to the shepherd-element, so hitting tab will cycle through all the things in the tooltip and not cycle out. I think if you show the step, then try to focus something outside the step, it might just be trapped to focusing in the step. We should definitely look into this more.

RobbieTheWagner avatar Sep 08 '20 19:09 RobbieTheWagner

@rwwagner90 Tested a bit more in chrome desktop and It does seem that it's the resize the does it.

This is what I tried

  1. Focus input
  2. Resize window
  3. input is not focused
  4. click next
  5. Focus input
  6. Resize window
  7. Input is focused

It doesn't really matter on chrome desktop because we don't usually resize the window, but the issue seems to match what's happening in android devices

Looking at this SO issue https://stackoverflow.com/questions/14854359/android-html-input-loses-focus-when-soft-keyboard-opens-asp-net, the first answer mentions that the keyboard opening on android does trigger a resize

Not sure if this helps, but I thought it was worth it to point out

alexd16 avatar Sep 08 '20 19:09 alexd16

@alexd16 ah, that is helpful info. We reposition things on resize and scroll I believe, so I could see that being a problem.

RobbieTheWagner avatar Sep 08 '20 20:09 RobbieTheWagner

@rwwagner90 So I looked a bit in the codebase and I think I was able to find what is causing the issue. It's the focusAfterRender modifier that's set here: https://github.com/shipshapecode/shepherd/blob/master/src/js/utils/general.js#L110

It seems that it runs every time there is a resize which causes the issue. If I remove that modifier it seems to work fine (at least on android, didn't have the chance to test on iphone)

Does this make sense?

alexd16 avatar Sep 08 '20 21:09 alexd16

@alexd16 yes, that makes sense, however we need this modifier, so we shouldn't remove it. I think perhaps the fix would be to manually call .focus on your element you want to focus, after Shepherd calls focus.

I suppose we could also try to make it not refocus after every resize, and just do it the first time. I am unsure of the best fix here.

RobbieTheWagner avatar Sep 11 '20 16:09 RobbieTheWagner

@rwwagner90 yup, I figured we couldn't just remove the modifier. But this is pretty limiting in mobile right now, it's basically prevents any step to have any sort of input.

I think calling focus on the input after shepherd calls focus could lead to an infinite loop of the keyboard opening and closing (didn't test this).

I am not 100% sure what is the purpose of that modifier but from what I saw is for accessibility purposes right? What if shepherd calls focus only if the document.activeElement is not a form element (I am assuming document.activeElement is reliable, didn't test this)

alexd16 avatar Sep 14 '20 13:09 alexd16

@alexd16 we have to call focus on each step. It is for a11y. What we don't necessarily need to do is call it on every resize. I'm open to suggestions to fix it.

RobbieTheWagner avatar Sep 14 '20 16:09 RobbieTheWagner

My assumption is that the resize logic is being triggered by popper so its outside of shepherd control. Let me know if this is a correct assumption This means we would need to remove the focus logic from the modifier and move it elsewhere.

Can't we do it inside the step's show method? It would meet the requirement of doing it on each step right? From what I can see it already has logic to handle the step's scrollTo option, I assume it could have the focus logic as well

Let me know what you think

alexd16 avatar Sep 15 '20 18:09 alexd16

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 17 '20 20:10 stale[bot]

@alexd16 that seems logical. I'm unsure if we would hit timing issues with Popper or not.

RobbieTheWagner avatar Oct 18 '20 15:10 RobbieTheWagner

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 21 '20 07:11 stale[bot]

@xiwcx any interest in working on this?

RobbieTheWagner avatar Dec 16 '20 18:12 RobbieTheWagner

apowerful1 has contributed $50.00 to this issue on Rysolv.

The total bounty is now $50.00. Solve this issue on Rysolv to earn this bounty.

rysolv-bot avatar Dec 21 '20 22:12 rysolv-bot

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Feb 27 '21 22:02 stale[bot]

Hello, I am interested in working on this. Please do not close this issue due to staleness.

ColinSather avatar May 14 '21 19:05 ColinSather

@rwwagner90 So I looked a bit in the codebase and I think I was able to find what is causing the issue. It's the focusAfterRender modifier that's set here: https://github.com/shipshapecode/shepherd/blob/master/src/js/utils/general.js#L110

It seems that it runs every time there is a resize which causes the issue. If I remove that modifier it seems to work fine (at least on android, didn't have the chance to test on iphone)

Does this make sense?

Disabling "focusAfterRender" from "popperOptions" in "defaultStepOptions" seems working for me.

var startTour = new Shepherd.Tour({ defaultStepOptions: { classes: 'shadow-md bg-purple-dark', scrollTo: false, cancelIcon: { enabled: true }, popperOptions: { modifiers: [{ name: "focusAfterRender", enabled: false }] } }, useModalOverlay: true });

alperenersoy avatar Jun 04 '21 16:06 alperenersoy

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jul 08 '21 09:07 stale[bot]

@ColinSather are you still interested in taking a look?

@alperenersoy yeah, we do need to keep it enabled though, as we need to focus the popper when it is rendered. See the discussion above.

RobbieTheWagner avatar Jul 28 '21 04:07 RobbieTheWagner

Even if I disable focus using popperOptions, I cannot see the input because it is covered by the popover. The keyboard does not close but I cannot see the input.

Maybe it should be possible to allow the popover to be out of the screen while an input is focused

andresespinosapc avatar Aug 31 '21 23:08 andresespinosapc

Even if I disable focus using popperOptions, I cannot see the input because it is covered by the popover. The keyboard does not close but I cannot see the input.

Maybe it should be possible to allow the popover to be out of the screen while an input is focused

You can try to hide "shepherd-element" class on focus and show it on focusout if it is not important to keep it open while typing. You should also check the element and position in attachTo property of steps. If you give more information about your using we can better help you.

alperenersoy avatar Aug 31 '21 23:08 alperenersoy

@alperenersoy I finally made a workaround using a modal for that step in mobile, but I think that this should be considered when fixing this issue. If I have some time to try your solution I'll share the result here.

andresespinosapc avatar Sep 01 '21 14:09 andresespinosapc

@andresespinosapc could you not use step.hide and step.show for this?

RobbieTheWagner avatar Sep 01 '21 14:09 RobbieTheWagner

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 02 '21 01:10 stale[bot]

Are there any plans to address this issue or has a suitable work around been found? This makes any form input on mobile impossible.

ktranel avatar Nov 30 '21 16:11 ktranel

I'm having the same issue, is there a solution to this? Thanks!

CharlotteArai avatar Jan 19 '22 10:01 CharlotteArai

We're certainly open to PRs to fix the issue, if anyone has any ideas!

RobbieTheWagner avatar Jan 19 '22 17:01 RobbieTheWagner

I'm unable to replicate this issue currently. I have an Iphone 12 and M1pro macbook, no immediate access to an Android device to test on. I ended up pulling out my old Iphone SE running on iOS 14.2 and also could not replicate this issue.

I'm wondering if the latest iOS has resolved this type resizing issue. I don't see any changes in Popper.js git history that would lead to a resolution.

Seems like we should connect with an Android phone owner to test this and if its not an issue for them either, get this closed up. Thoughts?

Steezli avatar Aug 03 '22 15:08 Steezli

@EmNicholson93 sounds good to me. @ktranel @CharlotteArai @andresespinosapc @alperenersoy can any of you confirm if this issue is gone as of Shepherd 10.0.1 please?

RobbieTheWagner avatar Aug 04 '22 01:08 RobbieTheWagner

@rwwagner90 Just stumbled on this thread by accident since I had exactly this issue (focusing an input makes it lose it immediately). The device is a Google Pixel 5, Shepherd is on version 10.0.1. For me the fix with the popperOptions given above is working fine, but since you just talked about if it is still happening on Android - it seems it is.

Zacherl avatar Aug 06 '22 16:08 Zacherl

I just hit this issue on PC as well. Iam using Vue-Multiselect and when menu with options is open it does resize slightly parent modal dialog. As i need to guide user to fill data into this dialog its content is target for step as whole. So user clicks into input to choose from selectbox, this triggeres resize and shapperd in change forces focus on itself as part of computePosition near // Replaces focusAfterRender modifier.

It seems there is no way of blocking this force focusing. Maybe simple option for disabling autofocus after repositioning? Seems like simple fix. Over all iam not sure i understand well why its even ther in first place. Seems that focus is good when step is opened for the first time but after that it feels like bug

sadovsf avatar Dec 13 '22 11:12 sadovsf