Angular: How to do Credit Card Input?

时间:2018-05-18 17:14:21

标签: angular

I want to keep input Capacity to 16 numbers and insert space between each set of 4 numbers.

I did a deep search for a input for credit cards that allow user to insert 16 digits and enter a " - " or space between number but all result are for JavaScript and etc. Is there an Angular way to do this? If you have any examples please share.

3 个答案:

答案 0 :(得分:4)

浏览信用卡号并手动添加空格

这在Angular 7+和更早的版本中也适用。

对于大多数信用卡类型,我们可以循环浏览数字并每四位数添加一个空格,但对于美国运通卡则为4-6-5。

唯一棘手的部分是处理Backspace和Cursor Position编辑(即,如果用户在输入中单击以对其进行编辑)。如果我们不解决这个问题,则循环将使编辑数字成为一种奇怪的用户体验难题。

您可以为此编写自定义组件或指令,但是如果您的应用程序中只有一个使用信用卡号的组件,则无需这样做(通常是这种情况)。 (如果您的应用程序中有多个信用卡输入,请将此代码放入指令中。)

这是我在应用程序的付款组件中执行的操作:

  • 创建一个名为partitions的变量来处理间距格式。对于美国运通卡,将其设置为4-6-5,对于所有其他卡,默认为4-4-4-4。在添加空格时,我们将遍历这些分区。
  • 使用模板参考变量#ccNumber进行光标位置检测。
  • 要处理退格键和光标箭头键,我们将存储原始光标位置,并在从字符串末尾以外的任何位置进行编辑后将其恢复。
  /* Insert spaces to enhance legibility of credit card numbers */
  creditCardNumberSpacing() {
    const input = this.ccNumberField.nativeElement;
    const { selectionStart } = input;
    const { cardNumber } = this.paymentForm.controls;

    let trimmedCardNum = cardNumber.value.replace(/\s+/g, '');

    if (trimmedCardNum.length > 16) {
      trimmedCardNum = trimmedCardNum.substr(0, 16);
    }

     /* Handle American Express 4-6-5 spacing */
    const partitions = trimmedCardNum.startsWith('34') || trimmedCardNum.startsWith('37') 
                       ? [4,6,5] 
                       : [4,4,4,4];

    const numbers = [];
    let position = 0;
    partitions.forEach(partition => {
      const part = trimmedCardNum.substr(position, partition);
      if (part) numbers.push(part);
      position += partition;
    })

    cardNumber.setValue(numbers.join(' '));

    /* Handle caret position if user edits the number later */
    if (selectionStart < cardNumber.value.length - 1) {
      input.setSelectionRange(selectionStart, selectionStart, 'none');
    }
  }


(如果您有自己的例程来检测美国运通卡号码,请使用它。我在这里使用的只是检查前两位数字并将它们与PAN/IIN standards进行比较。)

在组件中较高的位置,确保导入正确:

import { ViewChild, ElementRef } from '@angular/core';

并且:

  @ViewChild('ccNumber') ccNumberField: ElementRef;

在设置表单控件时,请执行以下操作,以便可以在正则表达式模式中包含空格:

this.paymentForm = this.fb.group({
  cardNumber: ['', [Validators.required, Validators.pattern('^[ 0-9]*$';), Validators.minLength(17)]]
})

最后,在模板中,像这样配置元素:

    <input maxlength="20"
        formControlName="cardNumber"
        type="tel"
        #ccNumber
        (keyup)="creditCardNumberSpacing()">

你应该很好。用户输入数字时,空格会自动显示,如果输入错字,他们仍然可以返回并进行编辑。

PS:如果要使用破折号(-)而不是空格进行格式化,请在cardNumber.setValue(numbers.join(' '))行和正则表达式调整中用破折号代替空格。

答案 1 :(得分:1)

这些是非常受欢迎的信用卡Angular套餐:

  1. angular-credit-cards
  2. angular-cc-library

答案 2 :(得分:0)

您可以为其创建自定义表单控件类。

import { FormControl } from '@angular/forms';

export class CardNumberFormControl extends FormControl{
    setValue(value: string | null, options: any) {
        if(!value){
            super.setValue('', {...options, emitModelToViewChange:true});
            return;
        }
        if(value.match(/[^0-9|\-]/gi)){
            super.setValue(this.value, {...options, emitModelToViewChange: true});
            return;
        }
        if(value.length>19){
            super.setValue(this.value, {...options, emitModelToViewChange:true});
            return;
        }
        if((value.length === 4 && this.value.length === 5) || (value.length === 9 && this.value.length === 10) || (value.length === 14 && this.value.length === 15)){
            super.setValue(value, {...options, emitModelToViewChange: true});
            return;
        }
        if(value.length === 4 || value.length === 9 || value.length === 14){
            super.setValue(value + '-', {...options, emitModelToViewChange: true});
            return;
        }
        super.setValue(value, {...options, emitModelToViewChange: true});
    }
}

如果最终的if语句说要在第4个字符后插入'-',但是您可以每第4个字符执行一次。