DEV Community

Reza Nazari
Reza Nazari

Posted on

Separate numbers in input with Angular Directive

Imagine that you have an input tag in your project for entering credit card numbers and you want to separate the entered numbers with a few digits for better readability.
Using commands in Angular, we write it as follows.

First, we create a directive that only allows the user to enter numbers, arrows, and backspace.

import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: '[appOnlyNumber]',
})
export class NumberDirective {
  constructor() {}

  @HostListener('keydown', ['$event'])
  onKeyDown(event) {
    const charCode = event.which ? event.which : event.keyCode;

    if (
      (charCode >= 48 && charCode <= 57) ||
      (charCode >= 96 && charCode <= 105) ||
      (charCode >= 37 && charCode <= 40) ||
      charCode == 8 ||
      charCode == 16
    ) {
      return true;
    }

    return false;
  }
}
Enter fullscreen mode Exit fullscreen mode

Then we write to the main directive. This directive executes commands during the 'keyup' event.
This directive has two inputs, one for 'all the digits of the credit card' and the other for 'the number of digits' to be separated.

import { Directive, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appDigiSeperator]',
})
export class DigiSeperatorDirective {
  @Input()
  detachableDigit: number;
  @Input()
  totalFigures: number;

  @HostListener('keyup', ['$event'])
  onKeyDown(event) {
    let enteredNumber = 
        this.check_number_not_longer_than_total_figure(
            this.remove_space_from_numbers(event.target.value)
        );

    const categorizedNumbers = [];

    for (
      let index = 0;
      index < enteredNumber.length;
      index += this.detachableDigit
    ) {
      const seperatedDigit = this.substring_numbers_by_digit(
        enteredNumber,
        index,
        this.detachableDigit
      );

      categorizedNumbers.push(seperatedDigit);
    }

    event.target.value = this.join_categorized_numbers(categorizedNumbers);
  }

  private remove_space_from_numbers(numbers: string) {
    return numbers.replace(/\s/g, '');
  }

  private check_number_not_longer_than_total_figure = (numbers: string) => {
    if (numbers.length > this.totalFigures) {
      return numbers.slice(0, this.totalFigures);
    }

    return numbers;
  };

  private substring_numbers_by_digit(
    numbers: string,
    startIndex: number,
    endIndex: number
  ) {
    return numbers.substring(startIndex, startIndex + endIndex);
  }

  private join_categorized_numbers(categorizedNumbers: number[]) {
    return categorizedNumbers.join(' ');
  }
}
Enter fullscreen mode Exit fullscreen mode

Now use it in your compnents

<input
  type="text"
  appOnlyNumber
  appDigiSeperator
  [detachableDigit]="4"
  [totalFigures]="16"
  [(ngModel)]="data"
/>

Enter fullscreen mode Exit fullscreen mode

Image description

Here is complete code!
See complete code

Top comments (0)