Angular2 Text Mask is an Angular 2 directive for input text masking that enables developers to create formatted input fields with customizable mask patterns for phone numbers, dates, currency, and other structured data types. It provides a declarative API through the textMask directive with automatic formatting as users type, seamless two-way data binding with ngModel, and support for reactive forms.
npm install angular2-text-maskimport { TextMaskModule } from "angular2-text-mask";For component and directive imports:
import {
TextMaskModule,
MaskedInputDirective,
TextMaskConfig,
MASKEDINPUT_VALUE_ACCESSOR
} from "angular2-text-mask";For core masking functions:
import { conformToMask } from "angular2-text-mask";For Angular dependencies used by the directive:
import {
Directive,
ElementRef,
Renderer2,
Inject,
Optional
} from '@angular/core';
import {
ControlValueAccessor,
COMPOSITION_BUFFER_MODE
} from '@angular/forms';import { NgModule, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TextMaskModule } from 'angular2-text-mask';
@NgModule({
imports: [
FormsModule,
TextMaskModule
],
declarations: [AppComponent]
})
export class AppModule {}
@Component({
selector: 'app',
template: `
<input
[textMask]="{mask: phoneMask}"
[(ngModel)]="phoneNumber"
type="text"
placeholder="(___) ___-____"
/>
`
})
export class AppComponent {
public phoneNumber = '';
public phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
}Angular2 Text Mask is built around several key components:
The main Angular module that provides text masking functionality.
class TextMaskModule {
static forRoot?(): ModuleWithProviders;
}The core directive that applies text masking to input elements. It handles input events, composition events (for IME support), and provides form integration through ControlValueAccessor.
@Directive({
selector: '[textMask]',
exportAs: 'textMask',
providers: [MASKEDINPUT_VALUE_ACCESSOR],
host: {
'(input)': '_handleInput($event.target.value)',
'(blur)': 'onTouched()',
'(compositionstart)': '_compositionStart()',
'(compositionend)': '_compositionEnd($event.target.value)'
}
})
class MaskedInputDirective implements ControlValueAccessor, OnChanges {
@Input('textMask') textMaskConfig: TextMaskConfig;
// ControlValueAccessor implementation
writeValue(value: any): void;
registerOnChange(fn: (_: any) => void): void;
registerOnTouched(fn: () => void): void;
setDisabledState(isDisabled: boolean): void;
// OnChanges implementation
ngOnChanges(changes: SimpleChanges): void;
// Constructor with dependency injection
constructor(
private _renderer: Renderer2,
private _elementRef: ElementRef,
@Optional() @Inject(COMPOSITION_BUFFER_MODE) private _compositionMode: boolean
);
}Configuration interface for defining mask patterns and behavior. Default values are applied by the directive when properties are not specified.
interface TextMaskConfig {
/** The mask pattern as an array of strings and RegExp, or a function that returns a mask, or false to disable (default: []) */
mask: Array<string | RegExp> | ((raw: string) => Array<string | RegExp>) | false;
/** Whether to show guide characters in the input field (default: true) */
guide?: boolean;
/** Character to use for placeholder positions (default: '_') */
placeholderChar?: string;
/** Transform function to modify the conformed value before displaying (default: undefined) */
pipe?: (conformedValue: string, config: TextMaskConfig) => false | string | object;
/** Whether to keep character positions during editing (default: false) */
keepCharPositions?: boolean;
/** Whether to show the mask when the input is empty (default: false) */
showMask?: boolean;
}Re-exported core function for applying masks to strings. This function is from text-mask-core and provides the underlying masking algorithm.
/**
* Conforms a string to a given mask pattern
* @param rawValue - The raw input string to conform (default: '')
* @param mask - The mask pattern to apply (default: [])
* @param config - Optional configuration for the masking behavior (default: {})
* @returns Object containing the conformed value and metadata
*/
function conformToMask(
rawValue?: string,
mask?: Array<string | RegExp> | ((rawValue: string, config: any) => Array<string | RegExp>),
config?: {
guide?: boolean;
previousConformedValue?: string;
placeholderChar?: string;
placeholder?: string;
currentCaretPosition?: number;
keepCharPositions?: boolean;
}
): {
conformedValue: string;
meta: {
someCharsRejected: boolean;
};
};Provider constant for integrating with Angular's forms system.
const MASKEDINPUT_VALUE_ACCESSOR: Provider;@Component({
template: `
<input
[textMask]="{mask: phoneMask, guide: true}"
[(ngModel)]="phoneNumber"
type="text"
/>
`
})
export class PhoneComponent {
phoneNumber = '';
phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
}@Component({
template: `
<input
[textMask]="{mask: dateMask, placeholderChar: 'X'}"
[(ngModel)]="dateValue"
type="text"
/>
`
})
export class DateComponent {
dateValue = '';
dateMask = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/];
}import { FormControl } from '@angular/forms';
@Component({
template: `
<input
[textMask]="{mask: currencyMask}"
[formControl]="amountControl"
type="text"
/>
`
})
export class CurrencyComponent {
amountControl = new FormControl('');
currencyMask = ['$', ' ', /\d/, /\d/, /\d/, '.', /\d/, /\d/];
}@Component({
template: `
<input
[textMask]="{mask: dynamicMask}"
[(ngModel)]="cardNumber"
type="text"
/>
`
})
export class CardComponent {
cardNumber = '';
dynamicMask = (rawValue: string) => {
// Visa/Mastercard: 4 groups of 4
if (rawValue.startsWith('4') || rawValue.startsWith('5')) {
return [/\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/];
}
// Amex: 4-6-5 pattern
if (rawValue.startsWith('3')) {
return [/\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, /\d/];
}
// Default pattern
return [/\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/];
};
}// Works with Angular Material and other component libraries
@Component({
template: `
<mat-form-field>
<input
matInput
[textMask]="{mask: mask}"
[(ngModel)]="value"
placeholder="Enter value"
/>
</mat-form-field>
`
})
export class MaterialComponent {
value = '';
mask = [/\d/, /\d/, /\d/, '-', /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
}The directive includes important behavioral characteristics:
(input), (blur), (compositionstart), and (compositionend) eventsThe directive automatically detects the platform and adjusts composition handling:
COMPOSITION_BUFFER_MODE injection tokenFormControl, FormGroup, etc.ngModel and two-way data bindingNG_VALUE_ACCESSORImportant Notes:
change event is not supported when textMask is present. Use (ngModelChange) for template-driven forms or reactive form controls for change detection.