Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: How to do Credit Card Input?

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.

like image 235
devmrh Avatar asked May 18 '18 17:05

devmrh


2 Answers

Loop through the credit card number and manually add spaces

This works in Angular 7+ and probably earlier versions too.

We can just loop through the numbers and add a space every four digits for most Credit Card types, but in a 4-6-5 pattern for American Express.

The only tricky part is handling Backspace and Cursor Position editing (ie if the user clicks inside the input to edit it). If we don't handle this, the loop will make editing the number a weird UX headache.

You can write a custom component or directive for this, but no need to do so if you only have one component in your application that is taking credit card numbers, which is often the case. (Put this code in a directive if you have multiple credit card inputs in your application.)

Here's how I did it inside the payment component in my app:

  • Create a variable called partitions to handle the spacing format. Set it to 4-6-5 for Amex and default to 4-4-4-4 for all other cards. We'll loop through these partitions as we add spaces.
  • Use a template reference variable #ccNumber for cursor position detection.
  • To handle backspace and cursor arrow keys, we store the original cursor position and restore it after editing from a spot anywhere other than the end of the string.
  /* 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');
    }
  }


(If you have a routine of your own to detect American Express numbers, use it. What I'm using here simply examines the first two digits and compares them to PAN/IIN standards.)

Higher in your component, ensure you have the right imports:

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

And:

  @ViewChild('ccNumber') ccNumberField: ElementRef;

And when you set up your form controls, do this so that spaces can be included in your regex pattern:

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

And finally, in your template, configure your element like this:

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

You should be good to go. Spaces will automatically appear as the user enters their number, and they can still go back and edit if they make typos.

PS: If you want to format with dashes (-) instead of spaces, replace the space with a dash in the cardNumber.setValue(numbers.join(' ')) line, and in the regex adjustment.

like image 135
Tony Brasunas Avatar answered Sep 27 '22 20:09

Tony Brasunas


These are pretty popular Angular packages for credit cards:

  1. angular-credit-cards
  2. angular-cc-library
like image 22
Narm Avatar answered Sep 27 '22 19:09

Narm