遍历信用卡号并手动添加空格
这适用于 Angular 7+ 和可能更早的版本。
对于大多数信用卡类型,我们可以遍历数字并每四位数添加一个空格,但对于美国运通,我们可以采用 4-6-5 模式。
唯一棘手的部分是处理退格和光标位置编辑(即,如果用户在输入内单击以进行编辑)。如果我们不处理这个问题,循环将使编辑数字成为一个奇怪的 UX 头痛。
您可以为此编写一个自定义组件或指令,但如果您的应用程序中只有一个组件用于获取信用卡号码,则无需这样做,这通常是这种情况。 (如果您的应用程序中有多个信用卡输入,请将此代码放入指令中。)
以下是我在应用的支付组件中的操作方式:
- 创建一个名为
partitions 的变量来处理间距格式。对于 Amex,将其设置为 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(' ')) 行和正则表达式调整中将空格替换为破折号。