ngx-mask
Version:
awesome ngx mask
952 lines • 160 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { Directive, EventEmitter, HostListener, Input, Output, inject, } from '@angular/core';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR, } from '@angular/forms';
import { NGX_MASK_CONFIG, timeMasks, withoutValidation } from './ngx-mask.config';
import { NgxMaskService } from './ngx-mask.service';
import * as i0 from "@angular/core";
export class NgxMaskDirective {
constructor() {
this.maskExpression = '';
this.specialCharacters = [];
this.patterns = {};
this.prefix = '';
this.suffix = '';
this.thousandSeparator = ' ';
this.decimalMarker = '.';
this.dropSpecialCharacters = null;
this.hiddenInput = null;
this.showMaskTyped = null;
this.placeHolderCharacter = null;
this.shownMaskExpression = null;
this.showTemplate = null;
this.clearIfNotMatch = null;
this.validation = null;
this.separatorLimit = null;
this.allowNegativeNumbers = null;
this.leadZeroDateTime = null;
this.leadZero = null;
this.triggerOnMaskChange = null;
this.apm = null;
this.inputTransformFn = null;
this.outputTransformFn = null;
this.keepCharacterPositions = null;
this.maskFilled = new EventEmitter();
this._maskValue = '';
this._position = null;
this._maskExpressionArray = [];
this._allowFewMaskChangeMask = false;
this._justPasted = false;
this._isFocused = false;
/**For IME composition event */
this._isComposing = false;
this.document = inject(DOCUMENT);
this._maskService = inject(NgxMaskService, { self: true });
this._config = inject(NGX_MASK_CONFIG);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.onChange = (_) => { };
this.onTouch = () => { };
}
ngOnChanges(changes) {
const { maskExpression, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, showTemplate, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, leadZero, triggerOnMaskChange, apm, inputTransformFn, outputTransformFn, keepCharacterPositions, } = changes;
if (maskExpression) {
if (maskExpression.currentValue !== maskExpression.previousValue &&
!maskExpression.firstChange) {
this._maskService.maskChanged = true;
}
if (maskExpression.currentValue &&
maskExpression.currentValue.split("||" /* MaskExpression.OR */).length > 1) {
this._maskExpressionArray = maskExpression.currentValue
.split("||" /* MaskExpression.OR */)
.sort((a, b) => {
return a.length - b.length;
});
this._setMask();
}
else {
this._maskExpressionArray = [];
this._maskValue = maskExpression.currentValue || "" /* MaskExpression.EMPTY_STRING */;
this._maskService.maskExpression = this._maskValue;
}
}
if (specialCharacters) {
if (!specialCharacters.currentValue || !Array.isArray(specialCharacters.currentValue)) {
return;
}
else {
this._maskService.specialCharacters = specialCharacters.currentValue || [];
}
}
if (allowNegativeNumbers) {
this._maskService.allowNegativeNumbers = allowNegativeNumbers.currentValue;
if (this._maskService.allowNegativeNumbers) {
this._maskService.specialCharacters = this._maskService.specialCharacters.filter((c) => c !== "-" /* MaskExpression.MINUS */);
}
}
// Only overwrite the mask available patterns if a pattern has actually been passed in
if (patterns && patterns.currentValue) {
this._maskService.patterns = patterns.currentValue;
}
if (apm && apm.currentValue) {
this._maskService.apm = apm.currentValue;
}
if (prefix) {
this._maskService.prefix = prefix.currentValue;
}
if (suffix) {
this._maskService.suffix = suffix.currentValue;
}
if (thousandSeparator) {
this._maskService.thousandSeparator = thousandSeparator.currentValue;
}
if (decimalMarker) {
this._maskService.decimalMarker = decimalMarker.currentValue;
}
if (dropSpecialCharacters) {
this._maskService.dropSpecialCharacters = dropSpecialCharacters.currentValue;
}
if (hiddenInput) {
this._maskService.hiddenInput = hiddenInput.currentValue;
}
if (showMaskTyped) {
this._maskService.showMaskTyped = showMaskTyped.currentValue;
if (showMaskTyped.previousValue === false &&
showMaskTyped.currentValue === true &&
this._isFocused) {
requestAnimationFrame(() => {
this._maskService._elementRef?.nativeElement.click();
});
}
}
if (placeHolderCharacter) {
this._maskService.placeHolderCharacter = placeHolderCharacter.currentValue;
}
if (shownMaskExpression) {
this._maskService.shownMaskExpression = shownMaskExpression.currentValue;
}
if (showTemplate) {
this._maskService.showTemplate = showTemplate.currentValue;
}
if (clearIfNotMatch) {
this._maskService.clearIfNotMatch = clearIfNotMatch.currentValue;
}
if (validation) {
this._maskService.validation = validation.currentValue;
}
if (separatorLimit) {
this._maskService.separatorLimit = separatorLimit.currentValue;
}
if (leadZeroDateTime) {
this._maskService.leadZeroDateTime = leadZeroDateTime.currentValue;
}
if (leadZero) {
this._maskService.leadZero = leadZero.currentValue;
}
if (triggerOnMaskChange) {
this._maskService.triggerOnMaskChange = triggerOnMaskChange.currentValue;
}
if (inputTransformFn) {
this._maskService.inputTransformFn = inputTransformFn.currentValue;
}
if (outputTransformFn) {
this._maskService.outputTransformFn = outputTransformFn.currentValue;
}
if (keepCharacterPositions) {
this._maskService.keepCharacterPositions = keepCharacterPositions.currentValue;
}
this._applyMask();
}
validate({ value }) {
if (!this._maskService.validation || !this._maskValue) {
return null;
}
if (this._maskService.ipError) {
return this._createValidationError(value);
}
if (this._maskService.cpfCnpjError) {
return this._createValidationError(value);
}
if (this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
return null;
}
if (withoutValidation.includes(this._maskValue)) {
return null;
}
if (this._maskService.clearIfNotMatch) {
return null;
}
if (timeMasks.includes(this._maskValue)) {
return this._validateTime(value);
}
if (value && value.toString().length >= 1) {
let counterOfOpt = 0;
if (this._maskValue.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) &&
this._maskValue.includes("}" /* MaskExpression.CURLY_BRACKETS_RIGHT */)) {
const lengthInsideCurlyBrackets = this._maskValue.slice(this._maskValue.indexOf("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) + 1, this._maskValue.indexOf("}" /* MaskExpression.CURLY_BRACKETS_RIGHT */));
return lengthInsideCurlyBrackets === String(value.length)
? null
: this._createValidationError(value);
}
if (this._maskValue.startsWith("percent" /* MaskExpression.PERCENT */)) {
return null;
}
for (const key in this._maskService.patterns) {
if (this._maskService.patterns[key]?.optional) {
if (this._maskValue.indexOf(key) !== this._maskValue.lastIndexOf(key)) {
const opt = this._maskValue
.split("" /* MaskExpression.EMPTY_STRING */)
.filter((i) => i === key)
.join("" /* MaskExpression.EMPTY_STRING */);
counterOfOpt += opt.length;
}
else if (this._maskValue.indexOf(key) !== -1) {
counterOfOpt++;
}
if (this._maskValue.indexOf(key) !== -1 &&
value.toString().length >= this._maskValue.indexOf(key)) {
return null;
}
if (counterOfOpt === this._maskValue.length) {
return null;
}
}
}
if ((this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) > 1 &&
value.toString().length <
this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */)) ||
(this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) > 1 &&
value.toString().length <
this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */))) {
return this._createValidationError(value);
}
if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) === -1 ||
this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) === -1) {
// eslint-disable-next-line no-param-reassign
value = typeof value === 'number' ? String(value) : value;
const array = this._maskValue.split('*');
const length = this._maskService.dropSpecialCharacters
? this._maskValue.length -
this._maskService.checkDropSpecialCharAmount(this._maskValue) -
counterOfOpt
: this.prefix
? this._maskValue.length + this.prefix.length - counterOfOpt
: this._maskValue.length - counterOfOpt;
if (array.length === 1) {
if (value.toString().length < length) {
return this._createValidationError(value);
}
}
if (array.length > 1) {
const lastIndexArray = array[array.length - 1];
if (lastIndexArray &&
this._maskService.specialCharacters.includes(lastIndexArray[0]) &&
String(value).includes(lastIndexArray[0] ?? '') &&
!this.dropSpecialCharacters) {
const special = value.split(lastIndexArray[0]);
return special[special.length - 1].length === lastIndexArray.length - 1
? null
: this._createValidationError(value);
}
else if (((lastIndexArray &&
!this._maskService.specialCharacters.includes(lastIndexArray[0])) ||
!lastIndexArray ||
this._maskService.dropSpecialCharacters) &&
value.length >= length - 1) {
return null;
}
else {
return this._createValidationError(value);
}
}
}
if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) === 1 ||
this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) === 1) {
return null;
}
}
if (value) {
this.maskFilled.emit();
return null;
}
return null;
}
onPaste() {
this._justPasted = true;
}
onFocus() {
this._isFocused = true;
}
onModelChange(value) {
// on form reset we need to update the actualValue
if ((value === "" /* MaskExpression.EMPTY_STRING */ || value === null || value === undefined) &&
this._maskService.actualValue) {
this._maskService.actualValue = this._maskService.getActualValue("" /* MaskExpression.EMPTY_STRING */);
}
}
onInput(e) {
// If IME is composing text, we wait for the composed text.
if (this._isComposing)
return;
const el = e.target;
const transformedValue = this._maskService.inputTransformFn(el.value);
if (el.type !== 'number') {
if (typeof transformedValue === 'string' || typeof transformedValue === 'number') {
el.value = transformedValue.toString();
this._inputValue = el.value;
this._setMask();
if (!this._maskValue) {
this.onChange(el.value);
return;
}
let position = el.selectionStart === 1
? el.selectionStart + this._maskService.prefix.length
: el.selectionStart;
if (this.showMaskTyped &&
this.keepCharacterPositions &&
this._maskService.placeHolderCharacter.length === 1) {
const inputSymbol = el.value.slice(position - 1, position);
const prefixLength = this.prefix.length;
const checkSymbols = this._maskService._checkSymbolMask(inputSymbol, this._maskService.maskExpression[position - 1 - prefixLength] ??
"" /* MaskExpression.EMPTY_STRING */);
const checkSpecialCharacter = this._maskService._checkSymbolMask(inputSymbol, this._maskService.maskExpression[position + 1 - prefixLength] ??
"" /* MaskExpression.EMPTY_STRING */);
const selectRangeBackspace = this._maskService.selStart === this._maskService.selEnd;
const selStart = Number(this._maskService.selStart) - prefixLength;
const selEnd = Number(this._maskService.selEnd) - prefixLength;
if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
if (!selectRangeBackspace) {
if (this._maskService.selStart === prefixLength) {
this._maskService.actualValue = `${this.prefix}${this._maskService.maskIsShown.slice(0, selEnd)}${this._inputValue.split(this.prefix).join('')}`;
}
else if (this._maskService.selStart ===
this._maskService.maskIsShown.length + prefixLength) {
this._maskService.actualValue = `${this._inputValue}${this._maskService.maskIsShown.slice(selStart, selEnd)}`;
}
else {
this._maskService.actualValue = `${this.prefix}${this._inputValue
.split(this.prefix)
.join('')
.slice(0, selStart)}${this._maskService.maskIsShown.slice(selStart, selEnd)}${this._maskService.actualValue.slice(selEnd + prefixLength, this._maskService.maskIsShown.length + prefixLength)}${this.suffix}`;
}
}
else if (!this._maskService.specialCharacters.includes(this._maskService.maskExpression.slice(position - this.prefix.length, position + 1 - this.prefix.length)) &&
selectRangeBackspace) {
if (selStart === 1 && this.prefix) {
this._maskService.actualValue = `${this.prefix}${this._maskService.placeHolderCharacter}${el.value
.split(this.prefix)
.join('')
.split(this.suffix)
.join('')}${this.suffix}`;
position = position - 1;
}
else {
const part1 = el.value.substring(0, position);
const part2 = el.value.substring(position);
this._maskService.actualValue = `${part1}${this._maskService.placeHolderCharacter}${part2}`;
}
}
}
if (this._code !== "Backspace" /* MaskExpression.BACKSPACE */) {
if (!checkSymbols && !checkSpecialCharacter && selectRangeBackspace) {
position = Number(el.selectionStart) - 1;
}
else if (this._maskService.specialCharacters.includes(el.value.slice(position, position + 1)) &&
checkSpecialCharacter &&
!this._maskService.specialCharacters.includes(el.value.slice(position + 1, position + 2))) {
this._maskService.actualValue = `${el.value.slice(0, position - 1)}${el.value.slice(position, position + 1)}${inputSymbol}${el.value.slice(position + 2)}`;
position = position + 1;
}
else if (checkSymbols) {
if (el.value.length === 1 && position === 1) {
this._maskService.actualValue = `${this.prefix}${inputSymbol}${this._maskService.maskIsShown.slice(1, this._maskService.maskIsShown.length)}${this.suffix}`;
}
else {
this._maskService.actualValue = `${el.value.slice(0, position - 1)}${inputSymbol}${el.value
.slice(position + 1)
.split(this.suffix)
.join('')}${this.suffix}`;
}
}
else if (this.prefix &&
el.value.length === 1 &&
position - prefixLength === 1 &&
this._maskService._checkSymbolMask(el.value, this._maskService.maskExpression[position - 1 - prefixLength] ??
"" /* MaskExpression.EMPTY_STRING */)) {
this._maskService.actualValue = `${this.prefix}${el.value}${this._maskService.maskIsShown.slice(1, this._maskService.maskIsShown.length)}${this.suffix}`;
}
}
}
let caretShift = 0;
let backspaceShift = false;
if (this._code === "Delete" /* MaskExpression.DELETE */ && "separator" /* MaskExpression.SEPARATOR */) {
this._maskService.deletedSpecialCharacter = true;
}
if (this._inputValue.length >= this._maskService.maskExpression.length - 1 &&
this._code !== "Backspace" /* MaskExpression.BACKSPACE */ &&
this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ &&
position < 10) {
const inputSymbol = this._inputValue.slice(position - 1, position);
el.value =
this._inputValue.slice(0, position - 1) +
inputSymbol +
this._inputValue.slice(position + 1);
}
if (this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ &&
this.leadZeroDateTime) {
if ((position < 3 && Number(el.value) > 31 && Number(el.value) < 40) ||
(position === 5 && Number(el.value.slice(3, 5)) > 12)) {
position = position + 2;
}
}
if (this._maskService.maskExpression === "Hh:m0:s0" /* MaskExpression.HOURS_MINUTES_SECONDS */ &&
this.apm) {
if (this._justPasted && el.value.slice(0, 2) === "00" /* MaskExpression.DOUBLE_ZERO */) {
el.value = el.value.slice(1, 2) + el.value.slice(2, el.value.length);
}
el.value =
el.value === "00" /* MaskExpression.DOUBLE_ZERO */
? "0" /* MaskExpression.NUMBER_ZERO */
: el.value;
}
this._maskService.applyValueChanges(position, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */, (shift, _backspaceShift) => {
this._justPasted = false;
caretShift = shift;
backspaceShift = _backspaceShift;
});
// only set the selection if the element is active
if (this._getActiveElement() !== el) {
return;
}
if (this._maskService.plusOnePosition) {
position = position + 1;
this._maskService.plusOnePosition = false;
}
// update position after applyValueChanges to prevent cursor on wrong position when it has an array of maskExpression
if (this._maskExpressionArray.length) {
if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
const specialChartMinusOne = this.specialCharacters.includes(this._maskService.actualValue.slice(position - 1, position));
const specialChartPlusOne = this.specialCharacters.includes(this._maskService.actualValue.slice(position, position + 1));
if (this._allowFewMaskChangeMask && !specialChartPlusOne) {
position = el.selectionStart + 1;
this._allowFewMaskChangeMask = false;
}
else {
position = specialChartMinusOne ? position - 1 : position;
}
}
else {
position =
el.selectionStart === 1
? el.selectionStart + this._maskService.prefix.length
: el.selectionStart;
}
}
this._position =
this._position === 1 && this._inputValue.length === 1 ? null : this._position;
let positionToApply = this._position
? this._inputValue.length + position + caretShift
: position +
(this._code === "Backspace" /* MaskExpression.BACKSPACE */ && !backspaceShift ? 0 : caretShift);
if (positionToApply > this._getActualInputLength()) {
positionToApply =
el.value === this._maskService.decimalMarker && el.value.length === 1
? this._getActualInputLength() + 1
: this._getActualInputLength();
}
if (positionToApply < 0) {
positionToApply = 0;
}
el.setSelectionRange(positionToApply, positionToApply);
this._position = null;
}
else {
console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof transformedValue);
}
}
else {
if (!this._maskValue) {
this.onChange(el.value);
return;
}
this._maskService.applyValueChanges(el.value.length, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */);
}
}
// IME starts
onCompositionStart() {
this._isComposing = true;
}
// IME completes
onCompositionEnd(e) {
this._isComposing = false;
this._justPasted = true;
this.onInput(e);
}
onBlur(e) {
if (this._maskValue) {
const el = e.target;
if (this.leadZero && el.value.length > 0 && typeof this.decimalMarker === 'string') {
const maskExpression = this._maskService.maskExpression;
const precision = Number(this._maskService.maskExpression.slice(maskExpression.length - 1, maskExpression.length));
if (precision > 0) {
el.value = this.suffix ? el.value.split(this.suffix).join('') : el.value;
const decimalPart = el.value.split(this.decimalMarker)[1];
el.value = el.value.includes(this.decimalMarker)
? el.value +
"0" /* MaskExpression.NUMBER_ZERO */.repeat(precision - decimalPart.length) +
this.suffix
: el.value +
this.decimalMarker +
"0" /* MaskExpression.NUMBER_ZERO */.repeat(precision) +
this.suffix;
this._maskService.actualValue = el.value;
}
}
this._maskService.clearIfNotMatchFn();
}
this._isFocused = false;
this.onTouch();
}
onClick(e) {
if (!this._maskValue) {
return;
}
const el = e.target;
const posStart = 0;
const posEnd = 0;
if (el !== null &&
el.selectionStart !== null &&
el.selectionStart === el.selectionEnd &&
el.selectionStart > this._maskService.prefix.length &&
// eslint-disable-next-line
e.keyCode !== 38) {
if (this._maskService.showMaskTyped && !this.keepCharacterPositions) {
// We are showing the mask in the input
this._maskService.maskIsShown = this._maskService.showMaskInInput();
if (el.setSelectionRange &&
this._maskService.prefix + this._maskService.maskIsShown === el.value) {
// the input ONLY contains the mask, so position the cursor at the start
el.focus();
el.setSelectionRange(posStart, posEnd);
}
else {
// the input contains some characters already
if (el.selectionStart > this._maskService.actualValue.length) {
// if the user clicked beyond our value's length, position the cursor at the end of our value
el.setSelectionRange(this._maskService.actualValue.length, this._maskService.actualValue.length);
}
}
}
}
const nextValue = el &&
(el.value === this._maskService.prefix
? this._maskService.prefix + this._maskService.maskIsShown
: el.value);
/** Fix of cursor position jumping to end in most browsers no matter where cursor is inserted onFocus */
if (el && el.value !== nextValue) {
el.value = nextValue;
}
/** fix of cursor position with prefix when mouse click occur */
if (el &&
el.type !== 'number' &&
(el.selectionStart || el.selectionEnd) <=
this._maskService.prefix.length) {
el.selectionStart = this._maskService.prefix.length;
return;
}
/** select only inserted text */
if (el && el.selectionEnd > this._getActualInputLength()) {
el.selectionEnd = this._getActualInputLength();
}
}
onKeyDown(e) {
if (!this._maskValue) {
return;
}
if (this._isComposing) {
// User finalize their choice from IME composition, so trigger onInput() for the composed text.
if (e.key === 'Enter')
this.onCompositionEnd(e);
return;
}
this._code = e.code ? e.code : e.key;
const el = e.target;
this._inputValue = el.value;
this._setMask();
if (el.type !== 'number') {
if (e.key === "ArrowUp" /* MaskExpression.ARROW_UP */) {
e.preventDefault();
}
if (e.key === "ArrowLeft" /* MaskExpression.ARROW_LEFT */ ||
e.key === "Backspace" /* MaskExpression.BACKSPACE */ ||
e.key === "Delete" /* MaskExpression.DELETE */) {
if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && el.value.length === 0) {
el.selectionStart = el.selectionEnd;
}
if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && el.selectionStart !== 0) {
// If specialChars is false, (shouldn't ever happen) then set to the defaults
this.specialCharacters = this.specialCharacters?.length
? this.specialCharacters
: this._config.specialCharacters;
if (this.prefix.length > 1 &&
el.selectionStart <= this.prefix.length) {
el.setSelectionRange(this.prefix.length, el.selectionEnd);
}
else {
if (this._inputValue.length !== el.selectionStart &&
el.selectionStart !== 1) {
while (this.specialCharacters.includes((this._inputValue[el.selectionStart - 1] ??
"" /* MaskExpression.EMPTY_STRING */).toString()) &&
((this.prefix.length >= 1 &&
el.selectionStart > this.prefix.length) ||
this.prefix.length === 0)) {
el.setSelectionRange(el.selectionStart - 1, el.selectionEnd);
}
}
}
}
this.checkSelectionOnDeletion(el);
if (this._maskService.prefix.length &&
el.selectionStart <= this._maskService.prefix.length &&
el.selectionEnd <= this._maskService.prefix.length) {
e.preventDefault();
}
const cursorStart = el.selectionStart;
if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ &&
!el.readOnly &&
cursorStart === 0 &&
el.selectionEnd === el.value.length &&
el.value.length !== 0) {
this._position = this._maskService.prefix ? this._maskService.prefix.length : 0;
this._maskService.applyMask(this._maskService.prefix, this._maskService.maskExpression, this._position);
}
}
if (!!this.suffix &&
this.suffix.length > 1 &&
this._inputValue.length - this.suffix.length < el.selectionStart) {
el.setSelectionRange(this._inputValue.length - this.suffix.length, this._inputValue.length);
}
else if ((e.code === 'KeyA' && e.ctrlKey) ||
(e.code === 'KeyA' && e.metaKey) // Cmd + A (Mac)
) {
el.setSelectionRange(0, this._getActualInputLength());
e.preventDefault();
}
this._maskService.selStart = el.selectionStart;
this._maskService.selEnd = el.selectionEnd;
}
}
/** It writes the value in the input */
async writeValue(controlValue) {
if (typeof controlValue === 'object' && controlValue !== null && 'value' in controlValue) {
if ('disable' in controlValue) {
this.setDisabledState(Boolean(controlValue.disable));
}
// eslint-disable-next-line no-param-reassign
controlValue = controlValue.value;
}
if (controlValue !== null) {
// eslint-disable-next-line no-param-reassign
controlValue = this.inputTransformFn
? this.inputTransformFn(controlValue)
: controlValue;
}
if (typeof controlValue === 'string' ||
typeof controlValue === 'number' ||
controlValue === null ||
controlValue === undefined) {
if (controlValue === null || controlValue === undefined || controlValue === '') {
this._maskService._currentValue = '';
this._maskService._previousValue = '';
}
let inputValue = controlValue;
if (typeof inputValue === 'number' ||
this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
inputValue = String(inputValue);
const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker();
if (!Array.isArray(this._maskService.decimalMarker)) {
inputValue =
this._maskService.decimalMarker !== localeDecimalMarker
? inputValue.replace(localeDecimalMarker, this._maskService.decimalMarker)
: inputValue;
}
if (this._maskService.leadZero &&
inputValue &&
this.maskExpression &&
this.dropSpecialCharacters !== false) {
inputValue = this._maskService._checkPrecision(this._maskService.maskExpression, inputValue);
}
if (this.decimalMarker === "," /* MaskExpression.COMMA */ ||
(Array.isArray(this._maskService.decimalMarker) &&
this.thousandSeparator === "." /* MaskExpression.DOT */)) {
inputValue = inputValue
.toString()
.replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
}
if (this.maskExpression?.startsWith("separator" /* MaskExpression.SEPARATOR */) && this.leadZero) {
requestAnimationFrame(() => {
this._maskService.applyMask(inputValue?.toString() ?? '', this._maskService.maskExpression);
});
}
this._maskService.isNumberValue = true;
}
if (typeof inputValue !== 'string') {
inputValue = '';
}
this._inputValue = inputValue;
this._setMask();
if ((inputValue && this._maskService.maskExpression) ||
(this._maskService.maskExpression &&
(this._maskService.prefix || this._maskService.showMaskTyped))) {
// Let the service we know we are writing value so that triggering onChange function won't happen during applyMask
typeof this.inputTransformFn !== 'function'
? (this._maskService.writingValue = true)
: '';
this._maskService.formElementProperty = [
'value',
this._maskService.applyMask(inputValue, this._maskService.maskExpression),
];
// Let the service know we've finished writing value
typeof this.inputTransformFn !== 'function'
? (this._maskService.writingValue = false)
: '';
}
else {
this._maskService.formElementProperty = ['value', inputValue];
}
this._inputValue = inputValue;
}
else {
console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof controlValue);
}
}
registerOnChange(fn) {
this._maskService.onChange = this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouch = fn;
}
_getActiveElement(document = this.document) {
const shadowRootEl = document?.activeElement?.shadowRoot;
if (!shadowRootEl?.activeElement) {
return document.activeElement;
}
else {
return this._getActiveElement(shadowRootEl);
}
}
checkSelectionOnDeletion(el) {
el.selectionStart = Math.min(Math.max(this.prefix.length, el.selectionStart), this._inputValue.length - this.suffix.length);
el.selectionEnd = Math.min(Math.max(this.prefix.length, el.selectionEnd), this._inputValue.length - this.suffix.length);
}
/** It disables the input element */
setDisabledState(isDisabled) {
this._maskService.formElementProperty = ['disabled', isDisabled];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_applyMask() {
this._maskService.maskExpression = this._maskService._repeatPatternSymbols(this._maskValue || '');
this._maskService.formElementProperty = [
'value',
this._maskService.applyMask(this._inputValue, this._maskService.maskExpression),
];
}
_validateTime(value) {
const rowMaskLen = this._maskValue
.split("" /* MaskExpression.EMPTY_STRING */)
.filter((s) => s !== ':').length;
if (!value) {
return null; // Don't validate empty values to allow for optional form control
}
if ((+(value[value.length - 1] ?? -1) === 0 && value.length < rowMaskLen) ||
value.length <= rowMaskLen - 2) {
return this._createValidationError(value);
}
return null;
}
_getActualInputLength() {
return (this._maskService.actualValue.length ||
this._maskService.actualValue.length + this._maskService.prefix.length);
}
_createValidationError(actualValue) {
return {
mask: {
requiredMask: this._maskValue,
actualValue,
},
};
}
_setMask() {
this._maskExpressionArray.some((mask) => {
const specialChart = mask
.split("" /* MaskExpression.EMPTY_STRING */)
.some((char) => this._maskService.specialCharacters.includes(char));
if ((specialChart &&
this._inputValue &&
this._areAllCharactersInEachStringSame(this._maskExpressionArray)) ||
mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)) {
const test = this._maskService.removeMask(this._inputValue)?.length <=
this._maskService.removeMask(mask)?.length;
if (test) {
this._maskValue =
this.maskExpression =
this._maskService.maskExpression =
mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)
? this._maskService._repeatPatternSymbols(mask)
: mask;
return test;
}
else {
if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
this._allowFewMaskChangeMask = true;
}
const expression = this._maskExpressionArray[this._maskExpressionArray.length - 1] ??
"" /* MaskExpression.EMPTY_STRING */;
this._maskValue =
this.maskExpression =
this._maskService.maskExpression =
expression.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)
? this._maskService._repeatPatternSymbols(expression)
: expression;
}
}
else {
const check = this._maskService
.removeMask(this._inputValue)
?.split("" /* MaskExpression.EMPTY_STRING */)
.every((character, index) => {
const indexMask = mask.charAt(index);
return this._maskService._checkSymbolMask(character, indexMask);
});
if (check || this._justPasted) {
this._maskValue = this.maskExpression = this._maskService.maskExpression = mask;
return check;
}
}
});
}
_areAllCharactersInEachStringSame(array) {
const specialCharacters = this._maskService.specialCharacters;
function removeSpecialCharacters(str) {
const regex = new RegExp(`[${specialCharacters.map((ch) => `\\${ch}`).join('')}]`, 'g');
return str.replace(regex, '');
}
const processedArr = array.map(removeSpecialCharacters);
return processedArr.every((str) => {
const uniqueCharacters = new Set(str);
return uniqueCharacters.size === 1;
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: NgxMaskDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.8", type: NgxMaskDirective, isStandalone: true, selector: "input[mask], textarea[mask]", inputs: { maskExpression: ["mask", "maskExpression"], specialCharacters: "specialCharacters", patterns: "patterns", prefix: "prefix", suffix: "suffix", thousandSeparator: "thousandSeparator", decimalMarker: "decimalMarker", dropSpecialCharacters: "dropSpecialCharacters", hiddenInput: "hiddenInput", showMaskTyped: "showMaskTyped", placeHolderCharacter: "placeHolderCharacter", shownMaskExpression: "shownMaskExpression", showTemplate: "showTemplate", clearIfNotMatch: "clearIfNotMatch", validation: "validation", separatorLimit: "separatorLimit", allowNegativeNumbers: "allowNegativeNumbers", leadZeroDateTime: "leadZeroDateTime", leadZero: "leadZero", triggerOnMaskChange: "triggerOnMaskChange", apm: "apm", inputTransformFn: "inputTransformFn", outputTransformFn: "outputTransformFn", keepCharacterPositions: "keepCharacterPositions" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste()", "focus": "onFocus($event)", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "compositionstart": "onCompositionStart($event)", "compositionend": "onCompositionEnd($event)", "blur": "onBlur($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: NgxMaskDirective,
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: NgxMaskDirective,
multi: true,
},
NgxMaskService,
], exportAs: ["mask", "ngxMask"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: NgxMaskDirective, decorators: [{
type: Directive,
args: [{
selector: 'input[mask], textarea[mask]',
standalone: true,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: NgxMaskDirective,
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: NgxMaskDirective,
multi: true,
},
NgxMaskService,
],
exportAs: 'mask,ngxMask',
}]
}], propDecorators: { maskExpression: [{
type: Input,
args: ['mask']
}], specialCharacters: [{
type: Input
}], patterns: [{
type: Input
}], prefix: [{
type: Input
}], suffix: [{
type: Input
}], thousandSeparator: [{
type: Input
}], decimalMarker: [{
type: Input
}], dropSpecialCharacters: [{
type: Input
}], hiddenInput: [{
type: Input
}], showMaskTyped: [{
type: Input
}], placeHolderCharacter: [{
type: Input
}], shownMaskExpression: [{
type: Input
}], showTemplate: [{
type: Input
}], clearIfNotMatch: [{
type: Input
}], validation: [{
type: Input
}], separatorLimit: [{
type: Input
}], allowNegativeNumbers: [{
type: Input
}], leadZeroDateTime: [{
type: Input
}], leadZero: [{
type: Input
}], triggerOnMaskChange: [{
type: Input
}], apm: [{
type: Input
}], inputTransformFn: [{
type: Input
}], outputTransformFn: [{
type: Input
}], keepCharacterPositions: [{
type: Input
}], maskFilled: [{
type: Output
}], onPaste: [{
type: HostListener,
args: ['paste']
}], onFocus: [{
type: HostListener,
args: ['focus', ['$event']]
}], onModelChange: [{
type: HostListener,
args: ['ngModelChange', ['$event']]
}], onInput: [{
type: HostListener,
args: ['input', ['$event']]
}], onCompositionStart: [{
type: HostListener,
args: ['compositionstart', ['$event']]
}], onCompositionEnd: [{
type: HostListener,
args: ['compositionend', ['$event']]
}], onBlur: [{
type: HostListener,
args: ['blur', ['$event']]
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}], onKeyDown: [{
type: HostListener,
args: ['keydown', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW1hc2suZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1hc2stbGliL3NyYy9saWIvbmd4LW1hc2suZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ0gsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFFTixNQUFNLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUdILGFBQWEsRUFDYixpQkFBaUIsR0FHcEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUd4QixPQUFPLEVBQVcsZUFBZSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7QUFxQnBELE1BQU0sT0FBTyxnQkFBZ0I7SUFsQjdCO1FBbUIwQixtQkFBYyxHQUE4QixFQUFFLENBQUM7UUFFckQsc0JBQWlCLEdBQWlDLEVBQUUsQ0FBQztRQUVyRCxhQUFRLEdBQXdCLEVBQUUsQ0FBQztRQUVuQyxXQUFNLEdBQXNCLEVBQUUsQ0FBQztRQUUvQixXQUFNLEdBQXNCLEVBQUUsQ0FBQztRQUUvQixzQkFBaUIsR0FBaUMsR0FBRyxDQUFDO1FBRXRELGtCQUFhLEdBQTZCLEdBQUcsQ0FBQztRQUU5QywwQkFBcUIsR0FBNEMsSUFBSSxDQUFDO1FBRXRFLGdCQUFXLEdBQWtDLElBQUksQ0FBQztRQUVsRCxrQkFBYSxHQUFvQyxJQUFJLENBQUM7UUFFdEQseUJBQW9CLEdBQTJDLElBQUksQ0FBQztRQUVwRSx3QkFBbUIsR0FBMEMsSUFBSSxDQUFDO1FBRWxFLGlCQUFZLEdBQW1DLElBQUksQ0FBQztRQUVwRCxvQkFBZSxHQUFzQyxJQUFJLENBQUM7UUFFMUQsZUFBVSxHQUFpQyxJQUFJLENBQUM7UUFFaEQsbUJBQWMsR0FBcUMsSUFBSSxDQUFDO1FBRXhELHlCQUFvQixHQUEyQyxJQUFJLENBQUM7UUFFcEUscUJBQWdCLEdBQXVDLElBQUksQ0FBQztRQUU1RCxhQUFRLEdBQStCLElBQUksQ0FBQztRQUU1Qyx3QkFBbUIsR0FBMEMsSUFBSSxDQUFDO1FBRWxFLFFBQUcsR0FBMEIsSUFBSSxDQUFDO1FBRWxDLHFCQUFnQixHQUF1QyxJQUFJLENBQUM7UUFFNUQsc0JBQWlCLEdBQXdDLElBQUksQ0FBQztRQUU5RCwyQkFBc0IsR0FBNkMsSUFBSSxDQUFDO1FBRXZFLGVBQVUsR0FBMEIsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUV0RSxlQUFVLEdBQUcsRUFBRSxDQUFDO1FBSWhCLGNBQVMsR0FBa0IsSUFBSSxDQUFDO1FBSWhDLHlCQUFvQixHQUFhLEVBQUUsQ0FBQztRQUVwQyw0QkFBdUIsR0FBWSxLQUFLLENBQUM7UUFFekMsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFcEIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUUzQiwrQkFBK0I7UUFDdkIsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFWixhQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXRDLGlCQUFZLEdBQUcsTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRW5ELFlBQU8sR0FBRyxNQUFNLENBQVUsZUFBZSxDQUFDLENBQUM7UUFFckQsOERBQThEO1FBQ3ZELGFBQVEsR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBRTFCLFlBQU8sR0FBRyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUM7S0F3Z0M3QjtJQXRnQ1UsV0FBVyxDQUFDLE9BQXNCO1FBQ3JDLE1BQU0sRUFDRixjQUFjLEVBQ2QsaUJBQWlCLEVBQ2pCLFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNOLGlCQUFpQixFQUNqQixhQUFhLEVBQ