Stripe js: не разрешать отправлять пустую форму - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь не допустить, чтобы пользователи отправляли форму чередования, когда входные данные пусты, я использую интеграцию элементов stripe.js для рендеринга моей формы и обработки представления формы внутри моего компонента vue.

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

После проверки документов я попытался использовать событие изменения на входах, но это не работает, так как пользователь может просто ничего не вводить и нажать кнопку отправки.

Это мой компонент:

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 = '';
        }
    }  
}

1 Ответ

0 голосов
/ 30 апреля 2019

С учетом документов в полосе использование события кажется правильным (хотя его можно немного улучшить с помощью this.disabled = !event.complete, чтобы охватить случай ошибки, а не только пустой случай).

Вы можете попробовать console.log в обратном вызове события enableForm, чтобы проверить, правильно ли запущено событие.

В любом случае, скорее всего, это происходит из-за логики отключения кнопки отправки, и она отсутствует в вашем сообщении. Ниже я создал поддельный безопасный компонент, который вызывает событие change при изменении значения.

Интересная часть в контейнере компонент:

  • Передача по умолчанию отключена через данные disabled,
  • Отправка включена, если полученное событие имеет свойство complete, установленное в значение true. Если false, он отключен.

Надеюсь, это поможет вам сфокусировать вашу проблему.

/**
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>
...