ngx-mask 16.2.8 → 16.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,8 @@ const initialConfig = {
27
27
  apm: false,
28
28
  leadZero: false,
29
29
  triggerOnMaskChange: false,
30
+ inputTransformFn: (value) => value,
31
+ outputTransformFn: (value) => value,
30
32
  maskFilled: new EventEmitter(),
31
33
  patterns: {
32
34
  '0': {
@@ -109,6 +111,8 @@ class NgxMaskApplierService {
109
111
  this.leadZeroDateTime = this._config.leadZeroDateTime;
110
112
  this.leadZero = this._config.leadZero;
111
113
  this.apm = this._config.apm;
114
+ this.inputTransformFn = this._config.inputTransformFn;
115
+ this.outputTransformFn = this._config.outputTransformFn;
112
116
  this._shift = new Set();
113
117
  this.maskExpression = '';
114
118
  this.actualValue = '';
@@ -1118,20 +1122,20 @@ class NgxMaskService extends NgxMaskApplierService {
1118
1122
  formControlResult(inputValue) {
1119
1123
  if (this.writingValue || (!this.triggerOnMaskChange && this.maskChanged)) {
1120
1124
  this.maskChanged
1121
- ? this.onChange(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue)))))
1125
+ ? this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue))))))
1122
1126
  : '';
1123
1127
  this.maskChanged = false;
1124
1128
  return;
1125
1129
  }
1126
1130
  if (Array.isArray(this.dropSpecialCharacters)) {
1127
- this.onChange(this._toNumber(this._checkSymbols(this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.dropSpecialCharacters))));
1131
+ this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.dropSpecialCharacters)))));
1128
1132
  }
1129
1133
  else if (this.dropSpecialCharacters ||
1130
1134
  (!this.dropSpecialCharacters && this.prefix === inputValue)) {
1131
- this.onChange(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue)))));
1135
+ this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue))))));
1132
1136
  }
1133
1137
  else {
1134
- this.onChange(this._toNumber(inputValue));
1138
+ this.onChange(this.outputTransformFn(this._toNumber(inputValue)));
1135
1139
  }
1136
1140
  }
1137
1141
  _toNumber(value) {
@@ -1319,6 +1323,8 @@ class NgxMaskDirective {
1319
1323
  this.leadZero = null;
1320
1324
  this.triggerOnMaskChange = null;
1321
1325
  this.apm = null;
1326
+ this.inputTransformFn = null;
1327
+ this.outputTransformFn = null;
1322
1328
  this.maskFilled = new EventEmitter();
1323
1329
  this._maskValue = '';
1324
1330
  this._position = null;
@@ -1335,7 +1341,7 @@ class NgxMaskDirective {
1335
1341
  this.onTouch = () => { };
1336
1342
  }
1337
1343
  ngOnChanges(changes) {
1338
- const { maskExpression, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, showTemplate, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, leadZero, triggerOnMaskChange, apm, } = changes;
1344
+ const { maskExpression, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, showTemplate, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, leadZero, triggerOnMaskChange, apm, inputTransformFn, outputTransformFn, } = changes;
1339
1345
  if (maskExpression) {
1340
1346
  if (maskExpression.currentValue !== maskExpression.previousValue &&
1341
1347
  !maskExpression.firstChange) {
@@ -1426,6 +1432,12 @@ class NgxMaskDirective {
1426
1432
  if (triggerOnMaskChange) {
1427
1433
  this._maskService.triggerOnMaskChange = triggerOnMaskChange.currentValue;
1428
1434
  }
1435
+ if (inputTransformFn) {
1436
+ this._maskService.inputTransformFn = inputTransformFn.currentValue;
1437
+ }
1438
+ if (outputTransformFn) {
1439
+ this._maskService.outputTransformFn = outputTransformFn.currentValue;
1440
+ }
1429
1441
  this._applyMask();
1430
1442
  }
1431
1443
  // eslint-disable-next-line complexity
@@ -1558,67 +1570,74 @@ class NgxMaskDirective {
1558
1570
  if (this._isComposing)
1559
1571
  return;
1560
1572
  const el = e.target;
1561
- this._inputValue = el.value;
1562
- this._setMask();
1563
- if (!this._maskValue) {
1564
- this.onChange(el.value);
1565
- return;
1566
- }
1567
- let position = el.selectionStart === 1
1568
- ? el.selectionStart + this._maskService.prefix.length
1569
- : el.selectionStart;
1570
- let caretShift = 0;
1571
- let backspaceShift = false;
1572
- if (this._code === "Delete" /* MaskExpression.DELETE */ && "separator" /* MaskExpression.SEPARATOR */) {
1573
- this._maskService.deletedSpecialCharacter = true;
1574
- }
1575
- if (this._inputValue.length >= this._maskService.maskExpression.length - 1 &&
1576
- this._code !== "Backspace" /* MaskExpression.BACKSPACE */ &&
1577
- this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ &&
1578
- position < 10) {
1579
- const inputSymbol = this._inputValue.slice(position - 1, position);
1580
- el.value =
1581
- this._inputValue.slice(0, position - 1) +
1582
- inputSymbol +
1583
- this._inputValue.slice(position + 1);
1584
- }
1585
- this._maskService.applyValueChanges(position, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */, (shift, _backspaceShift) => {
1586
- this._justPasted = false;
1587
- caretShift = shift;
1588
- backspaceShift = _backspaceShift;
1589
- });
1590
- // only set the selection if the element is active
1591
- if (this._getActiveElement() !== el) {
1592
- return;
1593
- }
1594
- // update position after applyValueChanges to prevent cursor on wrong position when it has an array of maskExpression
1595
- if (this._maskExpressionArray.length) {
1596
- if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
1597
- position = this.specialCharacters.includes(this._inputValue.slice(position - 1, position))
1598
- ? position - 1
1599
- : position;
1573
+ const transformedValue = this._maskService.inputTransformFn(el.value);
1574
+ if (typeof transformedValue === 'string' || typeof transformedValue === 'number') {
1575
+ el.value = transformedValue.toString();
1576
+ this._inputValue = el.value;
1577
+ this._setMask();
1578
+ if (!this._maskValue) {
1579
+ this.onChange(el.value);
1580
+ return;
1600
1581
  }
1601
- else {
1602
- position =
1603
- el.selectionStart === 1
1604
- ? el.selectionStart + this._maskService.prefix.length
1605
- : el.selectionStart;
1582
+ let position = el.selectionStart === 1
1583
+ ? el.selectionStart + this._maskService.prefix.length
1584
+ : el.selectionStart;
1585
+ let caretShift = 0;
1586
+ let backspaceShift = false;
1587
+ if (this._code === "Delete" /* MaskExpression.DELETE */ && "separator" /* MaskExpression.SEPARATOR */) {
1588
+ this._maskService.deletedSpecialCharacter = true;
1589
+ }
1590
+ if (this._inputValue.length >= this._maskService.maskExpression.length - 1 &&
1591
+ this._code !== "Backspace" /* MaskExpression.BACKSPACE */ &&
1592
+ this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ &&
1593
+ position < 10) {
1594
+ const inputSymbol = this._inputValue.slice(position - 1, position);
1595
+ el.value =
1596
+ this._inputValue.slice(0, position - 1) +
1597
+ inputSymbol +
1598
+ this._inputValue.slice(position + 1);
1599
+ }
1600
+ this._maskService.applyValueChanges(position, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */, (shift, _backspaceShift) => {
1601
+ this._justPasted = false;
1602
+ caretShift = shift;
1603
+ backspaceShift = _backspaceShift;
1604
+ });
1605
+ // only set the selection if the element is active
1606
+ if (this._getActiveElement() !== el) {
1607
+ return;
1606
1608
  }
1609
+ // update position after applyValueChanges to prevent cursor on wrong position when it has an array of maskExpression
1610
+ if (this._maskExpressionArray.length) {
1611
+ if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
1612
+ position = this.specialCharacters.includes(this._inputValue.slice(position - 1, position))
1613
+ ? position - 1
1614
+ : position;
1615
+ }
1616
+ else {
1617
+ position =
1618
+ el.selectionStart === 1
1619
+ ? el.selectionStart + this._maskService.prefix.length
1620
+ : el.selectionStart;
1621
+ }
1622
+ }
1623
+ this._position =
1624
+ this._position === 1 && this._inputValue.length === 1 ? null : this._position;
1625
+ let positionToApply = this._position
1626
+ ? this._inputValue.length + position + caretShift
1627
+ : position +
1628
+ (this._code === "Backspace" /* MaskExpression.BACKSPACE */ && !backspaceShift ? 0 : caretShift);
1629
+ if (positionToApply > this._getActualInputLength()) {
1630
+ positionToApply = this._getActualInputLength();
1631
+ }
1632
+ if (positionToApply < 0) {
1633
+ positionToApply = 0;
1634
+ }
1635
+ el.setSelectionRange(positionToApply, positionToApply);
1636
+ this._position = null;
1607
1637
  }
1608
- this._position =
1609
- this._position === 1 && this._inputValue.length === 1 ? null : this._position;
1610
- let positionToApply = this._position
1611
- ? this._inputValue.length + position + caretShift
1612
- : position +
1613
- (this._code === "Backspace" /* MaskExpression.BACKSPACE */ && !backspaceShift ? 0 : caretShift);
1614
- if (positionToApply > this._getActualInputLength()) {
1615
- positionToApply = this._getActualInputLength();
1616
- }
1617
- if (positionToApply < 0) {
1618
- positionToApply = 0;
1638
+ else {
1639
+ console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof transformedValue);
1619
1640
  }
1620
- el.setSelectionRange(positionToApply, positionToApply);
1621
- this._position = null;
1622
1641
  }
1623
1642
  // IME starts
1624
1643
  onCompositionStart() {
@@ -1781,68 +1800,87 @@ class NgxMaskDirective {
1781
1800
  this._maskService.selEnd = el.selectionEnd;
1782
1801
  }
1783
1802
  /** It writes the value in the input */
1784
- async writeValue(inputValue) {
1785
- if (typeof inputValue === 'object' && inputValue !== null && 'value' in inputValue) {
1786
- if ('disable' in inputValue) {
1787
- this.setDisabledState(Boolean(inputValue.disable));
1803
+ async writeValue(controlValue) {
1804
+ if (typeof controlValue === 'object' && controlValue !== null && 'value' in controlValue) {
1805
+ if ('disable' in controlValue) {
1806
+ this.setDisabledState(Boolean(controlValue.disable));
1788
1807
  }
1789
1808
  // eslint-disable-next-line no-param-reassign
1790
- inputValue = inputValue.value;
1809
+ controlValue = controlValue.value;
1791
1810
  }
1792
- if (typeof inputValue === 'number' ||
1793
- this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
1811
+ if (controlValue !== null) {
1794
1812
  // eslint-disable-next-line no-param-reassign
1795
- inputValue = String(inputValue);
1796
- const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker();
1797
- if (!Array.isArray(this._maskService.decimalMarker)) {
1798
- // eslint-disable-next-line no-param-reassign
1799
- inputValue =
1800
- this._maskService.decimalMarker !== localeDecimalMarker
1801
- ? inputValue.replace(localeDecimalMarker, this._maskService.decimalMarker)
1802
- : inputValue;
1803
- }
1804
- if (this._maskService.leadZero &&
1805
- inputValue &&
1806
- this.maskExpression &&
1807
- this.dropSpecialCharacters !== false) {
1813
+ controlValue = this.inputTransformFn
1814
+ ? this.inputTransformFn(controlValue)
1815
+ : controlValue;
1816
+ }
1817
+ if (typeof controlValue === 'string' ||
1818
+ typeof controlValue === 'number' ||
1819
+ controlValue === null) {
1820
+ // eslint-disable-next-line no-param-reassign
1821
+ let inputValue = controlValue;
1822
+ if (typeof inputValue === 'number' ||
1823
+ this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
1808
1824
  // eslint-disable-next-line no-param-reassign
1809
- inputValue = this._maskService._checkPrecision(this.maskExpression.toString(), inputValue);
1825
+ inputValue = String(inputValue);
1826
+ const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker();
1827
+ if (!Array.isArray(this._maskService.decimalMarker)) {
1828
+ // eslint-disable-next-line no-param-reassign
1829
+ inputValue =
1830
+ this._maskService.decimalMarker !== localeDecimalMarker
1831
+ ? inputValue.replace(localeDecimalMarker, this._maskService.decimalMarker)
1832
+ : inputValue;
1833
+ }
1834
+ if (this._maskService.leadZero &&
1835
+ inputValue &&
1836
+ this.maskExpression &&
1837
+ this.dropSpecialCharacters !== false) {
1838
+ // eslint-disable-next-line no-param-reassign
1839
+ inputValue = this._maskService._checkPrecision(this.maskExpression.toString(), inputValue);
1840
+ }
1841
+ if (this._maskService.decimalMarker === "," /* MaskExpression.COMMA */) {
1842
+ // eslint-disable-next-line no-param-reassign
1843
+ inputValue = inputValue
1844
+ .toString()
1845
+ .replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
1846
+ }
1847
+ if (this.maskExpression?.startsWith("separator" /* MaskExpression.SEPARATOR */) && this.leadZero) {
1848
+ requestAnimationFrame(() => {
1849
+ this._maskService.applyMask(inputValue?.toString() ?? '', this._maskService.maskExpression);
1850
+ });
1851
+ }
1852
+ this._maskService.isNumberValue = true;
1810
1853
  }
1811
- if (this._maskService.decimalMarker === "," /* MaskExpression.COMMA */) {
1854
+ if (typeof inputValue !== 'string') {
1812
1855
  // eslint-disable-next-line no-param-reassign
1813
- inputValue = inputValue
1814
- .toString()
1815
- .replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
1856
+ inputValue = '';
1857
+ }
1858
+ this._inputValue = inputValue;
1859
+ this._setMask();
1860
+ if ((inputValue && this._maskService.maskExpression) ||
1861
+ (this._maskService.maskExpression &&
1862
+ (this._maskService.prefix || this._maskService.showMaskTyped))) {
1863
+ // Let the service we know we are writing value so that triggering onChange function won't happen during applyMask
1864
+ typeof this.inputTransformFn !== 'function'
1865
+ ? (this._maskService.writingValue = true)
1866
+ : '';
1867
+ this._maskService.formElementProperty = [
1868
+ 'value',
1869
+ this._maskService.applyMask(inputValue, this._maskService.maskExpression),
1870
+ ];
1871
+ // Let the service know we've finished writing value
1872
+ typeof this.inputTransformFn !== 'function'
1873
+ ? (this._maskService.writingValue = false)
1874
+ : '';
1816
1875
  }
1817
- if (this.maskExpression?.startsWith("separator" /* MaskExpression.SEPARATOR */) && this.leadZero) {
1818
- requestAnimationFrame(() => {
1819
- this._maskService.applyMask(inputValue.toString(), this._maskService.maskExpression);
1820
- });
1876
+ else {
1877
+ this._maskService.formElementProperty = ['value', inputValue];
1821
1878
  }
1822
- this._maskService.isNumberValue = true;
1823
- }
1824
- if (typeof inputValue !== 'string') {
1825
- // eslint-disable-next-line no-param-reassign
1826
- inputValue = '';
1827
- }
1828
- this._inputValue = inputValue;
1829
- this._setMask();
1830
- if ((inputValue && this._maskService.maskExpression) ||
1831
- (this._maskService.maskExpression &&
1832
- (this._maskService.prefix || this._maskService.showMaskTyped))) {
1833
- // Let the service we know we are writing value so that triggering onChange function won't happen during applyMask
1834
- this._maskService.writingValue = true;
1835
- this._maskService.formElementProperty = [
1836
- 'value',
1837
- this._maskService.applyMask(inputValue, this._maskService.maskExpression),
1838
- ];
1839
- // Let the service know we've finished writing value
1840
- this._maskService.writingValue = false;
1879
+ this._inputValue = inputValue;
1841
1880
  }
1842
1881
  else {
1843
- this._maskService.formElementProperty = ['value', inputValue];
1882
+ console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof controlValue);
1844
1883
  }
1845
- this._inputValue = inputValue;
1846
1884
  }
1847
1885
  registerOnChange(fn) {
1848
1886
  this._maskService.onChange = this.onChange = fn;
@@ -1944,7 +1982,7 @@ class NgxMaskDirective {
1944
1982
  });
1945
1983
  }
1946
1984
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: NgxMaskDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1947
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.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" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste()", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "compositionstart": "onCompositionStart($event)", "compositionend": "onCompositionEnd($event)", "blur": "onBlur($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" } }, providers: [
1985
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.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" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste()", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "compositionstart": "onCompositionStart($event)", "compositionend": "onCompositionEnd($event)", "blur": "onBlur($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" } }, providers: [
1948
1986
  {
1949
1987
  provide: NG_VALUE_ACCESSOR,
1950
1988
  useExisting: NgxMaskDirective,
@@ -2021,6 +2059,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImpor
2021
2059
  type: Input
2022
2060
  }], apm: [{
2023
2061
  type: Input
2062
+ }], inputTransformFn: [{
2063
+ type: Input
2064
+ }], outputTransformFn: [{
2065
+ type: Input
2024
2066
  }], maskFilled: [{
2025
2067
  type: Output
2026
2068
  }], onPaste: [{