简体   繁体   中英

Vuejs format credit card number not working

I have a payment gateway component, when you choose credit card I use the _formatCreditCard method to leave the credit card number in this format: 4444 2442 4342 3434

This is my function:

_formatCreditCard: function() {

        var numberChunks = this.credit_card_number.match(/.{1,4}/g);

        if (numberChunks) {
          this.credit_card_number = numberChunks.join(' ');

        }
        else
          return '';

      }

And this is my component:

Vue.component('payment-methods', {

   template : '<div>\
                <template>\
                    <div class="radio col-xs-12">\
                      <label><input type="radio" v-model="pick" name="payment_method" value="CARD"> <i class="fa fa-credit-card-alt"></i> Tarjeta</label>\
                    </div>\
                    <div id="creditCard" class="col-xs-12" v-if="pick == credit_card">\
                      <div class="form-group col-sm-12">\
                        <label for="cardholderName">Titular de la tarjeta</label>\
                        <input type="text" class="form-control" id="cardholderName" name="credit_card[holder_name]">\
                      </div>\
                      <div class="form-group col-sm-9">\
                        <label for="cardNumber">Número de tarjeta</label>\
                        <input v-model="credit_card_number" type="text" class="form-control" id="cardNumber" name="credit_card[number]" @keyup="_formatCreditCard">\
                      </div>\
                      <div class="form-group col-sm-3">\
                        <label for="credit_card_number">CVN <i class="fa fa-info-circle"></i></label>\
                        <input id="cvn" type="text" class="form-control" name="credit_card[cvn]">\
                      </div>\
                      <div class="form-group col-sm-12">\
                        <label for="holder_name">Fecha de vencimiento <span class="subtitle">(ej: 06/26)</span></label><br>\
                        <div class="date-element">\
                          <select id="expiryDateMM" \
                                  name="credit_card[expiry_date_mm]"\
                                  class="form-control">\
                            <option v-for="month in months">{{month}}</option>\
                          </select>\
                        </div>\
                        <div class="divider">/</div>\
                        <div class="date-element">\
                          <select id="expiryDateYY"\
                                name="credit_card[expiry_date_yy]"\
                                class="form-control">\
                          <option v-for="year in years">{{year}}</option>\
                        </select>\
                        </div>\
                      </div>\
                    </div>\
                    <div class="radio col-xs-12">\
                      <label><input type="radio" v-model="pick" name="payment_method" value="PAYPAL"> <i class="fa fa-cc-paypal"></i> Paypal</label>\
                    </div>\
                    <div id="paypal" class="col-xs-12" v-if="pick == paypal">\
                      <p class="payment-info">\
                      Tanto si eres cliente de Paypal como si no, puedes realizar pagos a través de esta plataforma. Es el método más popular de pagos online en todo el mundo.\
                      </p>\
                    </div>\
                    <div class="radio col-xs-12">\
                      <label><input type="radio" v-model="pick" name="payment_method" value="BANK_TRANSFER"> <i class="fa fa-bank"></i> Transferencia</label>\
                    </div>\
                    <div id="bankTransfer" class="col-xs-12" v-if="pick == bank_transfer">\
                      <p class="payment-info">\
                      El pedido será enviado una vez recibamos el ingreso o  transferencia. Recuerda que las transferencias pueden tardar 2-3 días hábiles en recibirse y los ingresos al menos 24 h.\
                      </p>\
                    </div>\
                </template>\
               </div>',    


    data: function()
    {
       return {
            pick:   'CARD',
            credit_card: 'CARD',
            paypal: 'PAYPAL',
            bank_transfer: 'BANK_TRANSFER',
            credit_card_number: '',
       }
    },

    props : ['products','web_general_discount','current_article_size','current_article_model','simple_view_properties'],

    updated: function() {

       if(this.show)
        $('body').addClass('no-scroll')
       else
        $('body').removeClass('no-scroll')

    },

    computed: {

     months: function () {
        return [
          '01', '02', '03', '04',
          '05', '06', '07', '08',
          '09', '10', '11', '12'
        ];
      },

      years: function () {
        var years= [];
        var currentYear = (new Date()).getFullYear() % 2000;

        for (var i = 0; i < 18; i++)
          years.push(currentYear + i);

        return years;
      },




    },


    mounted: function() {


    },

    methods: {    

      _formatCreditCard: function() {

        var numberChunks = this.credit_card_number.match(/.{1,4}/g);

        if (numberChunks) {
          this.credit_card_number = numberChunks.join(' ');

        }
        else
          return '';

      }


    }

});

it currently doesn't work and I get this as a result: 在此处输入图像描述

I want this result: 在此处输入图像描述

look like you forgot to account for the spaces of the string? if i understand it right. If you remove the spaces of the string before anything, won't that fix the problem? I made a sample with jquery and html like this at jsfiddle. https://jsfiddle.net/uwry7xn7/

$( "#input" ).keyup(function(e) {
  //.replace(/\s/g, ''); is for removing spaces
  var str = $(e.currentTarget).val().replace(/\s/g, '');
  var numberChunks = str.match(/.{1,4}/g);
  console.log(numberChunks)
  var result = numberChunks.join(' ');
  console.log(result)
  $(e.currentTarget).val(result)
});

and the jquery does the job.

try this simple function

in your script:

formatCardNumber(event) {
        let value = event.target.value;
        if(!value) return

        this.cardNumber = value.replaceAll(" ", "")
        .split("")
        .map((v, index) => {
            if(index > 0 && index % 4 == 0 ) {
                return " " + v
            }else {
                return v
            }
        }).join("")
    }

in your html template

<input v-model="cardNumber" @keyup="formatCardNumber($event)" type="tel" inputmode="numeric" pattern="[0-9\s]{13,19}" maxlength="19" placeholder="xxxx xxxx xxxx xxxx">

PS: the cardNumber is in your data function that returns the initial reactive state for the component instance ( https://vuejs.org/api/options-state.html#data )

Tip: for the format of the expiry date (xx/xx) you can use the same function but inside the 'map' change the return " " by "/" and modulo 4 by 2

Have a good day

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