简体   繁体   中英

Stripe js: don't let empty form be sent

I'm trying to avoid letting users submit stripe form when inputs are empty, I`m using stripe.js elements integration to render my form and handle form submition inside my vue component.

this.cardNumberElement.on('change', this.enableForm);
this.cardExpiryElement.on('change', this.enableForm);
this.cardCvcElement.on('change', this.enableForm);

After checking the docs I tried to use the change event on inputs but this is not working sice the user can just not type anything and click submit button.

This is my component:

mounted()
{
    console.log(this.$options.name + ' component succesfully mounted');

    this.stripe = Stripe(this.stripePK);
    this.elements = this.stripe.elements();

    this.cardNumberElement = this.elements.create('cardNumber', {style: this.stripeStyles});
    this.cardNumberElement.mount('#card-number-element');
    this.cardExpiryElement = this.elements.create('cardExpiry', {style: this.stripeStyles});
    this.cardExpiryElement.mount('#card-expiry-element');
    this.cardCvcElement = this.elements.create('cardCvc', {style: this.stripeStyles});
    this.cardCvcElement.mount('#card-cvc-element');

    let stripeElements = document.querySelectorAll("#card-number-element, #card-expiry-element, #card-cvc-element");
    stripeElements.forEach(el => el.addEventListener('change', this.printStripeFormErrors));
    this.cardNumberElement.on('change', this.enableForm);
    this.cardExpiryElement.on('change', this.enableForm);
    this.cardCvcElement.on('change', this.enableForm);
},

methods: 
{
    ...mapActions('Stripe', ['addSource', 'createSourceAndCustomer']),
    ...mapMutations('Stripe', ['TOGGLE_PAYMENT_FORM']),
    ...mapMutations('Loader', ['SET_LOADER', 'SET_LOADER_ID']),

    enableForm:function(event){
        if(event.complete){
            this.disabled = false;
        }
        else if(event.empty){
            this.disabled = true;
        }
    },


    submitStripeForm: function()
    {
        this.SET_LOADER({ status:1, message: 'Procesando...' });
        var self = this;

        this.stripe.createSource(this.cardNumberElement).then(function(result) {
            if (result.error) {
                self.cardErrors = result.error.message;
            }
            else {
                self.stripeSourceHandler(result.source.id);
            }
        });   
    },


    stripeSourceHandler: function(sourceId)
    {
        console.log('stripeSourceHandler');

        this.cardNumberElement.clear();
        this.cardExpiryElement.clear();
        this.cardCvcElement.clear();

        if(this.customerSources.length == 0)
        {
            console.log('createSourceAndCustomer');
            this.createSourceAndCustomer({ id: sourceId });
        }
        else
        {
            console.log('addSource');
            this.addSource({ id: sourceId });
        }
    },


    printStripeFormErrors: function(event)
    {
        if(event.error)
        {
            self.cardErrors = event.error.message
        } 
        else
        {
            self.cardErrors = '';
        }
    }  
}

Given the stripe docs, the use of the event seems correct (though it can be improved a bit with using this.disabled = !event.complete to cover error case and not only empty case).

You may try to console.log in the event callback enableForm to check if event is well fired.

Anyway, it's more likely coming from the disabling logic of the submit button and it misses in your post. I've created below a fake secure-component that triggers a change event when value change.

The interesting part in on the container component :

  • Submit is disabled by default through data disabled ,
  • Submit is enabled if event received has a property complete set to true. If false, it is disabled.

Hope it will help you to focus your trouble.

 /** Mock component to emulate stripes card element behavior with change event */ const SecureInput = { template: '<input type="text" v-model="cardnumber"/>', data: () => ({ cardnumber: null }), watch: { cardnumber: function(val) { if(!val) { this.$emit('change', {empty: true, error: false, complete: false}); return; } if(val.length < 5) { this.$emit('change', {empty: false, error: true, complete: false}); return; } this.$emit('change', {empty: false, error: false, complete: true}); } } } /* Logic is here */ const app = new Vue({ el: '#app', components: { SecureInput }, data: { disabled: true }, methods: { updateDisable: function(event) { this.disabled = !event.complete; } } }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <form @submit.prevent="$emit('submitted')"> <p><secure-input @change="updateDisable"/></p> <p><input type="submit" :disabled="disabled"/></p> </form> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM