1

To reproduce issue:

<label for="card-element">
    {{stripeGateway.getPaymentFormHtml({})|raw}}
</label>

Then whenever I click either the First Name or Last Name input field my cursor would jump straight to the Card number or card date or CVC input fields (depending which one was clicked last, defaults to Card Number), making it impossible to enter the First Name or Last Name without click and holding onto the respective field. This bug doesn't appear anymore when the code is simply:

{{stripeGateway.getPaymentFormHtml({})|raw}}

i.e. without the <label tags. I am using Stripe as my payment gateway, I have disabled (commented out) all javascript on the page including reference to https://js.stripe.com/v3/ with no success. Whenever I click either First Name or Last Name, in the console of inspect element, I see: enter image description here Not sure whether that information helps.

Any clues on why and how to resolve this would be much appreciated

2

The getPaymentFormHtml() method will output a huge chunk of code, including Stripe's iframe and all its nested fields and functionality - you can't simply wrap that in a label element and expect it to work, as the click event of the label will not reach inside the iFrame.

The default output of Commerce Stripe's getPaymentFormHtml leaves a lot to be desired, but if you want/need to gain more control than getPaymentFormHtml(), then you basically have two options:

  1. Tweak the output after-the-fact using your own JavaScript... or
  2. Go fully custom like this: https://github.com/craftcms/commerce-stripe#creating-a-stripe-payment-form-for-the-payment-intents-gateway

Personally I feel like the downsides to a fully custom approach outweigh the advantages, so in the past I've just added my own JS to tweak the output.

It's not perfect but here's a quick JS hack I'm using to at least get the firstName/lastName labels working:

// Craft's Stripe plugin uses jQuery (for now), so we might as well piggyback on it...
// https://github.com/craftcms/commerce-stripe/issues/153
$('.card-holder-first-name,.card-holder-last-name').each(function(i){

    var field = $(this);
    var properLabel = '<label for="stripeField"' + i + '>Card holder ' + field.attr('placeholder').toLowerCase() + ' <em>&bull;</em></label>';
    var theVal = field.is('.card-holder-first-name') ? '{{ cart.billingAddress.firstName ?? null }}' : '{{  cart.billingAddress.lastName ?? null }}';

    field.attr('id','stripeField'+i)
         .removeAttr('placeholder')
         .before(properLabel)
         .prop('required',true).attr('required','required')
         .val(theVal);
});

var fauxLabel = '<p class="stripeLabelHack">Card details <em class="required">&bull;</em></p>';
$('.StripeElement').before(fauxLabel);
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.