diff --git a/CHANGELOG.md b/CHANGELOG.md index ea3b81c6..801d874b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 17.1.7(2024-07-18) + +### Fix + +- Fix ([#1399](https://github.com/JsDaddy/ngx-mask/issues/1399)) +- Fix ([#1360](https://github.com/JsDaddy/ngx-mask/issues/1360)) +- Fix ([#1357](https://github.com/JsDaddy/ngx-mask/issues/1357)) +- Fix ([#1364](https://github.com/JsDaddy/ngx-mask/issues/1364)) + # 17.1.6(2024-07-16) ### Fix diff --git a/package.json b/package.json index eb7c7b5b..ef66e2eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ngx-mask", - "version": "17.1.6", + "version": "17.1.7", "description": "Awesome ngx mask", "license": "MIT", "engines": { diff --git a/projects/ngx-mask-lib/package.json b/projects/ngx-mask-lib/package.json index 760bd584..c2fcf93a 100644 --- a/projects/ngx-mask-lib/package.json +++ b/projects/ngx-mask-lib/package.json @@ -1,6 +1,6 @@ { "name": "ngx-mask", - "version": "17.1.6", + "version": "17.1.7", "description": "awesome ngx mask", "keywords": [ "ng2-mask", diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts index d62905e9..a03f34d6 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.directive.ts @@ -283,8 +283,23 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida 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(MaskExpression.PERCENT)) { return null; } @@ -311,26 +326,12 @@ export class NgxMaskDirective implements ControlValueAccessor, OnChanges, Valida } } if ( - this._maskValue.indexOf(MaskExpression.CURLY_BRACKETS_LEFT) === 1 && - value.toString().length === - this._maskValue.length + - Number( - ( - this._maskValue.split(MaskExpression.CURLY_BRACKETS_LEFT)[1] ?? - MaskExpression.EMPTY_STRING - ).split(MaskExpression.CURLY_BRACKETS_RIGHT)[0] - ) - - 4 - ) { - return null; - } else 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)) || - this._maskValue.indexOf(MaskExpression.CURLY_BRACKETS_LEFT) === 1 + this._maskValue.indexOf(MaskExpression.SYMBOL_QUESTION)) ) { return this._createValidationError(value); } diff --git a/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts b/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts index 94ec1d03..ebe03d32 100644 --- a/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts +++ b/projects/ngx-mask-lib/src/lib/ngx-mask.service.ts @@ -208,8 +208,9 @@ export class NgxMaskService extends NgxMaskApplierService { this.maskChanged || (this._previousValue === this._currentValue && justPasted); } + this._emitValue - ? this.writingValue + ? this.writingValue && this.triggerOnMaskChange ? requestAnimationFrame(() => this.formControlResult(result)) : this.formControlResult(result) : ''; @@ -527,7 +528,7 @@ export class NgxMaskService extends NgxMaskApplierService { */ private formControlResult(inputValue: string): void { if (this.writingValue || (!this.triggerOnMaskChange && this.maskChanged)) { - this.maskChanged + this.triggerOnMaskChange && this.maskChanged ? this.onChange( this.outputTransformFn( this._toNumber( diff --git a/projects/ngx-mask-lib/src/test/add-prefix.spec.ts b/projects/ngx-mask-lib/src/test/add-prefix.spec.ts index dbc78b0f..e99eb10a 100644 --- a/projects/ngx-mask-lib/src/test/add-prefix.spec.ts +++ b/projects/ngx-mask-lib/src/test/add-prefix.spec.ts @@ -122,21 +122,43 @@ describe('Directive: Mask (Add prefix)', () => { equal('-123456', '-€1234.56', fixture); }); - it('should remove prefix when setValue', () => { + it('should remove prefix when setValue triggerOnMaskChange = true', () => { component.mask = '000 000'; component.prefix = 'KZ'; component.dropSpecialCharacters = true; + component.triggerOnMaskChange = true; component.form.setValue('KZ123123'); equal('KZ123123', 'KZ123 123', fixture); expect(component.form.value).toBe('123123'); }); - it('should remove prefix when setValue', () => { + it('should remove prefix when setValue triggerOnMaskChange =true', () => { component.mask = '000 000'; component.prefix = 'KZ'; component.dropSpecialCharacters = false; + component.triggerOnMaskChange = true; component.form.setValue('KZ123123'); equal('KZ123123', 'KZ123 123', fixture); - expect(component.form.value).toBe('123123'); + requestAnimationFrame(() => { + expect(component.form.value).toBe('123123'); + }); + }); + + it('should remove prefix when setValue triggerOnMaskChange = false', () => { + component.mask = '000 000'; + component.prefix = 'KZ'; + component.dropSpecialCharacters = true; + component.form.setValue('KZ123123'); + equal('KZ123123', 'KZ123 123', fixture); + expect(component.form.value).toBe('KZ123123'); + }); + + it('should remove prefix when setValue triggerOnMaskChange = false', () => { + component.mask = '000 000'; + component.prefix = 'KZ'; + component.dropSpecialCharacters = false; + component.form.setValue('KZ123123'); + equal('KZ123123', 'KZ123 123', fixture); + expect(component.form.value).toBe('KZ123123'); }); }); diff --git a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts index 01ce9a05..2e7526e6 100644 --- a/projects/ngx-mask-lib/src/test/basic-logic.spec.ts +++ b/projects/ngx-mask-lib/src/test/basic-logic.spec.ts @@ -508,6 +508,7 @@ describe('Directive: Mask', () => { it('should remove ghost character on toggling mask', () => { component.mask = '0000'; + component.triggerOnMaskChange = true; component.form.setValue('1111a'); equal('1111a', '1111', fixture); expect(component.form.value).toBe('1111'); @@ -946,4 +947,25 @@ describe('Directive: Mask', () => { expect(inputTarget.value).toBe('22/22/2222'); }); }); + + it('mask sepator.0 after setValue should be dont dirty', () => { + component.mask = 'separator.0'; + component.form.setValue('2'); + + expect(component.form.dirty).toBe(false); + }); + + it('mask sepator.2 after setValue should be dont dirty', () => { + component.mask = 'separator.0'; + component.form.setValue('2002'); + + expect(component.form.dirty).toBe(false); + }); + + it('mask 00/00/0000 after setValue should be dont dirty', () => { + component.mask = 'separator.0'; + component.form.setValue('12312312'); + + expect(component.form.dirty).toBe(false); + }); }); diff --git a/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts b/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts index 7b103bc1..b5672603 100644 --- a/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/repeat-mask.spec.ts @@ -100,4 +100,91 @@ describe('Directive: Mask (Repeat)', () => { equal('dd213D', 'dd213.D', fixture); equal('dd213DW', 'dd213.DW', fixture); }); + + it('should A{8} be valid if length 8', () => { + component.mask = 'A{8}'; + equal('1', '1', fixture); + expect(component.form.valid).toBe(false); + equal('12', '12', fixture); + expect(component.form.valid).toBe(false); + + equal('123', '123', fixture); + expect(component.form.valid).toBe(false); + + equal('1234', '1234', fixture); + expect(component.form.valid).toBe(false); + + equal('12345', '12345', fixture); + expect(component.form.valid).toBe(false); + + equal('123456', '123456', fixture); + expect(component.form.valid).toBe(false); + + equal('1234567', '1234567', fixture); + expect(component.form.valid).toBe(false); + + equal('12345678', '12345678', fixture); + expect(component.form.valid).toBe(true); + }); + + it('should A{9} be valid if length 9', () => { + component.mask = 'A{9}'; + equal('1', '1', fixture); + expect(component.form.valid).toBe(false); + equal('12', '12', fixture); + expect(component.form.valid).toBe(false); + + equal('123', '123', fixture); + expect(component.form.valid).toBe(false); + + equal('1234', '1234', fixture); + expect(component.form.valid).toBe(false); + + equal('12345', '12345', fixture); + expect(component.form.valid).toBe(false); + + equal('123456', '123456', fixture); + expect(component.form.valid).toBe(false); + + equal('1234567', '1234567', fixture); + expect(component.form.valid).toBe(false); + + equal('12345678', '12345678', fixture); + expect(component.form.valid).toBe(false); + + equal('123456789', '123456789', fixture); + expect(component.form.valid).toBe(true); + }); + + it('should A{10} be valid if length 10', () => { + component.mask = 'A{10}'; + equal('1', '1', fixture); + expect(component.form.valid).toBe(false); + equal('12', '12', fixture); + expect(component.form.valid).toBe(false); + + equal('123', '123', fixture); + expect(component.form.valid).toBe(false); + + equal('1234', '1234', fixture); + expect(component.form.valid).toBe(false); + + equal('12345', '12345', fixture); + expect(component.form.valid).toBe(false); + + equal('123456', '123456', fixture); + expect(component.form.valid).toBe(false); + + equal('1234567', '1234567', fixture); + expect(component.form.valid).toBe(false); + + equal('12345678', '12345678', fixture); + expect(component.form.valid).toBe(false); + + equal('123456789', '123456789', fixture); + expect(component.form.valid).toBe(false); + + equal('1234567890', '1234567890', fixture); + expect(component.form.valid).toBe(true); + }); }); diff --git a/projects/ngx-mask-lib/src/test/secure-mask.spec.ts b/projects/ngx-mask-lib/src/test/secure-mask.spec.ts index 7a6e4c90..4cd3e2e3 100644 --- a/projects/ngx-mask-lib/src/test/secure-mask.spec.ts +++ b/projects/ngx-mask-lib/src/test/secure-mask.spec.ts @@ -93,9 +93,10 @@ describe('Directive: Mask (Secure)', () => { }); }); - it('should be same form state (pristine) after mask change', async () => { + it('should be same form state (pristine) after mask change triggerOnMaskChange = true', async () => { component.mask = 'XXX/X0/0000'; component.hiddenInput = true; + component.triggerOnMaskChange = true; component.form.reset('123456789'); fixture.detectChanges(); expect(component.form.dirty).toBeTruthy(); diff --git a/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts b/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts index 274da63e..70b34e6e 100644 --- a/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts +++ b/projects/ngx-mask-lib/src/test/trigger-on-mask-change.spec.ts @@ -49,6 +49,7 @@ describe('Directive: Mask (Trigger on mask change)', () => { it('should trigger form value update if mask is changed', async () => { component.mask = '00000||00000-0000'; + component.triggerOnMaskChange = true; const debugElement: DebugElement = fixture.debugElement.query(By.css('input')); const inputTarget: HTMLInputElement = debugElement.nativeElement as HTMLInputElement; spyOnProperty(document, 'activeElement').and.returnValue(inputTarget); diff --git a/projects/ngx-mask-lib/src/test/validation.spec.ts b/projects/ngx-mask-lib/src/test/validation.spec.ts index 8af36d5a..1fea7a8f 100644 --- a/projects/ngx-mask-lib/src/test/validation.spec.ts +++ b/projects/ngx-mask-lib/src/test/validation.spec.ts @@ -360,14 +360,14 @@ describe('Directive: Mask (Validation)', () => { it('mask with number value should work as expected mask 000.00', () => { component.mask = '000.00'; - equal('44', '44', fixture); - expect(component.form.invalid).toBe(true); - expect(component.form.value).toBe(44); - equal('', '', fixture); expect(component.form.invalid).toBe(true); expect(component.form.value).toBe(''); + equal('44', '44', fixture); + expect(component.form.invalid).toBe(true); + expect(component.form.value).toBe(44); + equal('1', '1', fixture); expect(component.form.invalid).toBe(true); expect(component.form.value).toBe(1);