Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

secondman's avatar

Events Inside EventListener Not Updated On Page

I'm trying to implement stripe as per the Cashier instructions.

I've implemented an event listener to spot card errors then update the card-errors element.

cardElement.addEventListener('change', function(e) {
    if (e.error) {
        errorBlock.textContent = e.error.message;
    } else {
        errorBlock.textContent = '';
    }
    
    if (e.complete) {
        cardButton.classList.remove('disabled');
        cardButton.setAttribute('disabled', false);
    }
});

When I trigger an error and console.log the errorBlock it shows that the element has been updated:

<div id="card-errors" role="alert" class="text-danger mt-3 pl-2">
    Your card number is incomplete.
</div>

But it doesn't update the element on the page, very weird.

Same thing happens inside my cardElement listener .... I get a message that the element isn't mounted.

Any help would be appreciated.

0 likes
1 reply
secondman's avatar

Here's the whole block just in case it's needed.

const stripe = Stripe('{{ env("STRIPE_KEY") }}');
const elements = stripe.elements();
const cardButton = document.getElementById('card-submit');
const errorBlock = document.getElementById('card-errors');
const style = {
    base: {
        fontSize: '20px',
        textTransform: 'lowercase',
        color: '#636b6f',
        lineHeight: '24px',
        fontFamily: 'Montserrat, sans-serif',
        fontSmoothing: 'antialiased',
        '::placeholder': {
          color: '#747d8a',
        }
    },
    invalid: {
        color: '#e57373',
        ':focus': {
            color: '#747d8a',
        },
    }
};

const cardElement = elements.create('card', {style: style});

cardElement.mount('#card-element');

cardButton.classList.add('disabled');
cardButton.setAttribute('disabled', true);

cardElement.addEventListener('change', function(e) {
    if (e.error) {
        errorBlock.textContent = e.error.message;
    } else {
        errorBlock.textContent = '';
    }

    if (e.complete) {
        alert('yep it completed');
        cardButton.classList.remove('disabled');
        cardButton.setAttribute('disabled', false);
    }
});

const cardHolderName = document.getElementById('card-holder-name');
const clientSecret = cardButton.dataset.secret;

cardButton.addEventListener('click', async (e) => {
    e.preventDefault();

    cardButton.classList.add('disabled');
    cardButton.setAttribute('disabled', true);
    cardButton.textContent = 'Processing ... ';

    const { setupIntent, error } = await stripe.confirmCardSetup(
        clientSecret, {
            payment_method: {
                card: cardElement,
                billing_details: {
                    name: cardHolderName.value
                }
            }
        }
    );

    const form = document.getElementById('payment-form');
    const method = document.getElementById('payment-method');

    if (error) {
        errorBlock.textContent = error.message;
    } else {
        method.value = setupIntent.payment_method;
        form.submit();
    }
});

Please or to participate in this conversation.