Ionic and Stripe Elements: keyboard bug with iOS

2019-04-12 02:13发布

Stripe introduced a way to collect credit cards information named Stripe Elements. Roughly speaking, it consists on letting Stripe propose an UI for collecting credit cards.

I used it in an Ionic3/Angular4 application. For now, it works perfectly, except I found a very annoying bug, in iOS only: When focusing the credit card number, a keyboard appears (seems to be the native one), then it is replaced by the ionic one 0,5 second after, as showed on these 2 iPhone screenshots:

That would not be a problem usually. But then, if I press “back” button, I go to the previous page but the keyboard stays! Even if I close the keyboard, it will reopen forever as soon as I go to a new page, or if I open the menu… my UI is broken.

I have the intuition there is a conflict between the ionic keyboard triggered on any input, and the native keyboard triggered by Stripe code. But due to the nature of stripe Elements, I can’t control the content of the form, I only have pretty much this in the html code:

<form action="/charge" method="post" id="payment-form">
      <div class="form-row">
          <div id="card-element">
            <!-- a Stripe Element will be inserted here. -->
          </div>

      ....
</form>

Any idea how to try to debug this? Do you think I could tell to Ionic not to trigger the keyboard?

Thanks a lot. Notes : I’m using ionic-angular 3.7.1

3条回答
The star\"
2楼-- · 2019-04-12 02:44

Ok sound like Stripe isn't going to fix this anytime soon and have suggested the same method of focus then blur. Here's their response for completeness.

For PCI reasons our fields are hosted in iframes and mobile safari has been fairly bad since last version with how it handles hidden iframes. There are potential fixes here we could implement but they would likely introduce more issues in the long run so we're still looking into a better solution.

Hopefully there is a workaround here and it should be fairly simple. The problem comes from the fact Safari ignores the .blur() if the iframe is unfocused which then causes the keyboard to stay open. What you can do is to call the .focus() and .blur() methods manually which would reset the state.

Update

Also I found that none of the suggestions worked and the keyboard would remain open. What you actually need to do is use Stripe's own focus and blur methods i.e;

const card = elements.create('card');

card.focus();
setTimeout(() => {
  card.blur();
});

I had to add the setTimeout in my angular app as without it the blur didn't seem to work.

查看更多
冷血范
3楼-- · 2019-04-12 02:46

I have the same issue as well. I fixed it by inserting an invisible input node. Once purchase / next button is pressed, or anytime you decide to hide the keyboard, focus on that invisible input and then blur.

<input id="inviInput" type="tel" style="border: 0px; color: transparent; width: 0px; height: 0px; background: transparent;">

var inviInput = $('#inviInput')[0];
inviInput.focus();
inviInput.blur();

Any approach to get the DOM node shall be fine, even for pure Javascript.

Note that the input shall not be "display: none;", or "visibility: hidden;", otherwise iOS Safari won't focus on it.

EDIT with specific solution for Ionic3/Angular4:

<input #invisiInput
           id="invisiInput"
           type="tel"
           style="border: 0; color: transparent; width: 0; height: 0; background: transparent;">

--

@ViewChild('invisiInput') invisiInput: ElementRef;

...

  ionViewWillLeave() {
    this.invisiInput.nativeElement.focus();
    this.invisiInput.nativeElement.blur();
  }

UPDATE

The following approach might be better:

$('.card_input iframe')[0].focus()
$('.card_input iframe')[0].blur()

Get the iframe and blur.

查看更多
小情绪 Triste *
4楼-- · 2019-04-12 02:57

I have reported this issue to Stripe and they have acknowledged that there is an issue and it's being looked into, so hopefully there will be a fix soon.

查看更多
登录 后发表回答