<p>The <code>getPaymentFormHtml()</code> 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 <code>label</code> element and expect it to work, as the click event of the label will not reach inside the iFrame.</p>
<p>The default output of Commerce Stripe's getPaymentFormHtml leaves a lot to be desired, but if you want/need to gain more control than <code>getPaymentFormHtml()</code>, then you basically have two options:</p>
<ol>
<li>Tweak the output after-the-fact using your own JavaScript... or</li>
<li>Go fully custom like this: <a href="https://github.com/craftcms/commerce-stripe#creating-a-stripe-payment-form-for-the-payment-intents-gateway" rel="nofollow noreferrer">https://github.com/craftcms/commerce-stripe#creating-a-stripe-payment-form-for-the-payment-intents-gateway</a></li>
</ol>
<p>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.</p>
<p>It's not perfect but here's a quick JS hack I'm using to at least get the firstName/lastName labels working:</p>
<pre><code>// 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 = '&lt;label for=&quot;stripeField&quot;' + i + '&gt;Card holder ' + field.attr('placeholder').toLowerCase() + ' &lt;em&gt;&amp;bull;&lt;/em&gt;&lt;/label&gt;';
    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 = '&lt;p class=&quot;stripeLabelHack&quot;&gt;Card details &lt;em class=&quot;required&quot;&gt;&amp;bull;&lt;/em&gt;&lt;/p&gt;';
$('.StripeElement').before(fauxLabel);
</code></pre>

CC BY-SA 4.0
2021-07-20T03:16:48.693Z
For some reason, Jquery doesn't seem to affect my webpage at all? I have added https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js to the <head> of my _layout template
Steven Zhang
CC BY-SA 4.0
2021-07-19T11:33:10.647Z
2021-07-19T11:33:10.647Z
James Smith
<p>To reproduce issue:</p>
<pre><code>&lt;label for=&quot;card-element&quot;&gt;
    {{stripeGateway.getPaymentFormHtml({})|raw}}
&lt;/label&gt;
</code></pre>
<p>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:</p>
<pre><code>{{stripeGateway.getPaymentFormHtml({})|raw}}
</code></pre>
<p>i.e. without the &lt;label tags.
I am using Stripe as my payment gateway, I have disabled (commented out) all javascript on the page including reference to <a href="https://js.stripe.com/v3/" rel="nofollow noreferrer">https://js.stripe.com/v3/</a> with no success.
Whenever I click either First Name or Last Name, in the console of inspect element, I see:
<a href="https://i.sstatic.net/bjIj1.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/bjIj1.png" alt="enter image description here" /></a>
Not sure whether that information helps.</p>
<p>Any clues on why and how to resolve this would be much appreciated</p>

<craft3><plugin-craftcommerce><stripe><plugin-commerce-stripe>
input fields in getpaymentformhtml auto click out of card holder information
# input fields in getpaymentformhtml auto click out of card holder information

(Asked by: username_0 on 2021-07-16)

To reproduce issue:

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


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

Not sure whether that information helps.
Any clues on why and how to resolve this would be much appreciated

**Tags:** craft3, plugin-craftcommerce, stripe, plugin-commerce-stripe


---

## 1 answers

### Answer by username_1 on 2021-07-19. Score: 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:

Tweak the output after-the-fact using your own JavaScript... or
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 = 'Card holder ' + field.attr('placeholder').toLowerCase() + ' •';
    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 = 'Card details •';
$('.StripeElement').before(fauxLabel);

> **Comments:**
> **username_0**: For some reason, Jquery doesn't seem to affect my webpage at all? I have added https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js to the <head> of my _layout template  

---

