Skip to content

Commit 9f1d554

Browse files
ColinMorris83NepipenkoIgor
authored andcommitted
fix: fix for JsDaddy#560 dynamic value for patterns attribute (JsDaddy#619)
* fix: fix for JsDaddy#560 dynamic value for patterns attribute * fix: fix for JsDaddy#620 allow delete to work when no prefix * fix: fix for JsDaddy#621 validation config value is now used correctly * test: unit test for validation attribute
1 parent 2e58684 commit 9f1d554

File tree

11 files changed

+189
-19
lines changed

11 files changed

+189
-19
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
<a name="8.1.6">
2+
3+
# [8.1.6 bugfix](2019-10-30)
4+
5+
Fix for #560 - do not overwrite the mask available patterns when patterns attribute passed in value is a falsey value i.e null/undefined/false
6+
7+
Fix for #620 - allow delete button to work when at beginning of input and no prefix exists
8+
9+
Fix for #621 - validation config value now works correctly
10+
111
<a name="8.1.5">
212

313
# [8.1.5 bugfix](2019-10-25)

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-mask",
3-
"version": "8.1.5",
3+
"version": "8.1.6",
44
"description": "awesome ngx mask",
55
"license": "MIT",
66
"angular-cli": {},

projects/ngx-mask-lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-mask",
3-
"version": "8.1.5",
3+
"version": "8.1.6",
44
"description": "awesome ngx mask",
55
"keywords": [
66
"ng2-mask",

projects/ngx-mask-lib/src/lib/mask.directive.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ export class MaskDirective implements ControlValueAccessor, OnChanges {
4343
private _maskValue: string = '';
4444
private _inputValue!: string;
4545
private _position: number | null = null;
46-
// tslint:disable-next-line
4746
private _start!: number;
4847
private _end!: number;
4948
private _code!: string;
@@ -86,7 +85,8 @@ export class MaskDirective implements ControlValueAccessor, OnChanges {
8685
this._maskService.maskSpecialCharacters = changes.specialCharacters.currentValue || [];
8786
}
8887
}
89-
if (patterns) {
88+
// Only overwrite the mask available patterns if a pattern has actually been passed in
89+
if (patterns && patterns.currentValue) {
9090
this._maskService.maskAvailablePatterns = patterns.currentValue;
9191
}
9292
if (prefix) {
@@ -323,7 +323,7 @@ export class MaskDirective implements ControlValueAccessor, OnChanges {
323323
}
324324
}
325325
this.suffixCheckOnPressDelete(e.keyCode, el);
326-
if (
326+
if (this._maskService.prefix.length &&
327327
(el.selectionStart as number) <= this._maskService.prefix.length &&
328328
(el.selectionEnd as number) <= this._maskService.prefix.length
329329
) {

projects/ngx-mask-lib/src/lib/mask.service.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { MaskApplierService } from './mask-applier.service';
66

77
@Injectable()
88
export class MaskService extends MaskApplierService {
9-
public validation: boolean = true;
109
public maskExpression: string = '';
1110
public isNumberValue: boolean = false;
1211
public showMaskTyped: boolean = false;
@@ -15,11 +14,10 @@ export class MaskService extends MaskApplierService {
1514
public selStart: number | null = null;
1615
public selEnd: number | null = null;
1716
protected _formElement: HTMLInputElement;
18-
// tslint:disable-next-line
17+
1918
public onChange = (_: any) => { };
2019

2120
public constructor(
22-
// tslint:disable-next-line
2321
@Inject(DOCUMENT) private document: any,
2422
@Inject(config) protected _config: IConfig,
2523
private _elementRef: ElementRef,
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { Component } from '@angular/core';
3+
import { ReactiveFormsModule, FormControl } from '@angular/forms';
4+
5+
import { NgxMaskModule } from '../lib/ngx-mask.module';
6+
import { equal } from './utils/test-functions.component';
7+
8+
@Component({
9+
selector: 'mask-test-no-validation-attr',
10+
template: `<input
11+
id="maska"
12+
mask="0000"
13+
[formControl]="form" />`,
14+
})
15+
export class TestMaskNoValidationAttributeComponent {
16+
public form: FormControl = new FormControl('');
17+
}
18+
19+
@Component({
20+
selector: 'mask-test-validation-attr',
21+
template: `<input
22+
id="maska"
23+
mask="0000"
24+
[validation]="validate"
25+
[formControl]="form" />`,
26+
})
27+
export class TestMaskValidationAttributeComponent {
28+
public form: FormControl = new FormControl('');
29+
public validate: boolean = true;
30+
}
31+
32+
describe('Directive: Mask (Validation)', () => {
33+
34+
describe('Global validation true, validation attribute on input not specified', () => {
35+
let fixture: ComponentFixture<TestMaskNoValidationAttributeComponent>;
36+
let component: TestMaskNoValidationAttributeComponent;
37+
38+
beforeEach(() => {
39+
TestBed.configureTestingModule({
40+
declarations: [TestMaskNoValidationAttributeComponent],
41+
imports: [ReactiveFormsModule, NgxMaskModule.forRoot({
42+
validation: true,
43+
})],
44+
});
45+
fixture = TestBed.createComponent(TestMaskNoValidationAttributeComponent);
46+
component = fixture.componentInstance;
47+
fixture.detectChanges();
48+
});
49+
50+
it('should be marked as not valid if not valid', () => {
51+
equal('12', '12', fixture);
52+
expect(component.form.valid).toBeFalse();
53+
expect(component.form.hasError('Mask error')).toBeTrue();
54+
});
55+
56+
it('should be marked as valid if valid', () => {
57+
equal('1234', '1234', fixture);
58+
expect(component.form.valid).toBeTrue();
59+
});
60+
});
61+
62+
describe('Global validation true, validation attribute on input specified', () => {
63+
let fixture: ComponentFixture<TestMaskValidationAttributeComponent>;
64+
let component: TestMaskValidationAttributeComponent;
65+
66+
beforeEach(() => {
67+
TestBed.configureTestingModule({
68+
declarations: [TestMaskValidationAttributeComponent],
69+
imports: [ReactiveFormsModule, NgxMaskModule.forRoot({
70+
validation: true,
71+
})],
72+
});
73+
fixture = TestBed.createComponent(TestMaskValidationAttributeComponent);
74+
component = fixture.componentInstance;
75+
fixture.detectChanges();
76+
});
77+
78+
it('should be marked as not valid if not valid and validation attribute true', () => {
79+
equal('12', '12', fixture);
80+
expect(component.form.valid).toBeFalse();
81+
expect(component.form.hasError('Mask error')).toBeTrue();
82+
});
83+
84+
it('should be marked as valid if valid and validation attribute true', () => {
85+
equal('1234', '1234', fixture);
86+
expect(component.form.valid).toBeTrue();
87+
});
88+
89+
it('should be marked as valid if not valid and validation attribute false', () => {
90+
component.validate = false;
91+
equal('12', '12', fixture);
92+
expect(component.form.valid).toBeTrue();
93+
});
94+
});
95+
96+
describe('Global validation false, validation attribute on input not specified', () => {
97+
let fixture: ComponentFixture<TestMaskNoValidationAttributeComponent>;
98+
let component: TestMaskNoValidationAttributeComponent;
99+
100+
beforeEach(() => {
101+
TestBed.configureTestingModule({
102+
declarations: [TestMaskNoValidationAttributeComponent],
103+
imports: [ReactiveFormsModule, NgxMaskModule.forRoot({
104+
validation: false,
105+
})],
106+
});
107+
fixture = TestBed.createComponent(TestMaskNoValidationAttributeComponent);
108+
component = fixture.componentInstance;
109+
fixture.detectChanges();
110+
});
111+
112+
it('should be marked as valid if not valid', () => {
113+
equal('12', '12', fixture);
114+
expect(component.form.valid).toBeTrue();
115+
});
116+
117+
});
118+
119+
describe('Global validation false, validation attribute on input specified', () => {
120+
let fixture: ComponentFixture<TestMaskValidationAttributeComponent>;
121+
let component: TestMaskValidationAttributeComponent;
122+
123+
beforeEach(() => {
124+
TestBed.configureTestingModule({
125+
declarations: [TestMaskValidationAttributeComponent],
126+
imports: [ReactiveFormsModule, NgxMaskModule.forRoot({
127+
validation: false,
128+
})],
129+
});
130+
fixture = TestBed.createComponent(TestMaskValidationAttributeComponent);
131+
component = fixture.componentInstance;
132+
fixture.detectChanges();
133+
});
134+
135+
it('should be marked as not valid if not valid and validation attribute true', () => {
136+
equal('12', '12', fixture);
137+
expect(component.form.valid).toBeFalse();
138+
expect(component.form.hasError('Mask error')).toBeTrue();
139+
});
140+
141+
it('should be marked as valid if not valid and validation attribute false', () => {
142+
component.validate = false;
143+
equal('12', '12', fixture);
144+
expect(component.form.valid).toBeTrue();
145+
});
146+
});
147+
148+
});

src/app/app.component.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,31 +86,31 @@ <h1 class="title">
8686
<div class="col-mat-3">
8787
<div class="mat-form-wr">
8888
<mat-form-field>
89-
<input matInput placeholder="Date and Hour" mask="00/00/00 00:00:00" />
89+
<input matInput placeholder="Date and Hour" mask="00/00/00 00:00:00" [formControl]="hourTimeForm" />
9090
<mat-hint> <b>Mask:</b> 00/00/00 00:00:00</mat-hint>
9191
</mat-form-field>
9292
</div>
9393
</div>
9494
<div class="col-mat-3">
9595
<div class="mat-form-wr">
9696
<mat-form-field>
97-
<input matInput placeholder="Hour" mask="00:00:00" />
97+
<input matInput placeholder="Hour" mask="00:00:00" [formControl]="hourForm" />
9898
<mat-hint> <b>Mask:</b> 00:00:00</mat-hint>
9999
</mat-form-field>
100100
</div>
101101
</div>
102102
<div class="col-mat-3">
103103
<div class="mat-form-wr">
104104
<mat-form-field>
105-
<input matInput placeholder="Valid 24 hour format" mask="Hh:m0:s0" />
105+
<input matInput placeholder="Valid 24 hour format" mask="Hh:m0:s0" [formControl]="hour24Form" />
106106
<mat-hint> <b>Mask:</b> Hh:m0:s0</mat-hint>
107107
</mat-form-field>
108108
</div>
109109
</div>
110110
<div class="col-mat-3">
111111
<div class="mat-form-wr">
112112
<mat-form-field>
113-
<input matInput placeholder="Mixed Type" mask="AAA 000-S0S" />
113+
<input matInput placeholder="Mixed Type" mask="AAA 000-S0S" [formControl]="mixedTypeForm" />
114114
<mat-hint> <b>Mask:</b> AAA 000-S0S</mat-hint>
115115
</mat-form-field>
116116
</div>
@@ -123,7 +123,7 @@ <h1 class="title">
123123
placeholder="Valid date and month"
124124
mask="d0/M0/0000"
125125
[dropSpecialCharacters]="true"
126-
/>
126+
[formControl]="dateMonthForm" />
127127
<mat-hint> <b>Mask:</b> d0/M0/0000</mat-hint>
128128
</mat-form-field>
129129
</div>
@@ -274,6 +274,7 @@ <h1 class="title">
274274
matInput
275275
placeholder="Phone number"
276276
mask="(000) 000-0000"
277+
prefix="+7 "
277278
[formControl]="form"
278279
[(ngModel)]="dateModel"
279280
/>
@@ -312,7 +313,7 @@ <h1 class="title">
312313
placeholder="Phone number"
313314
mask="(000) 000-0000"
314315
[formControl]="form1"
315-
prefix="+5"
316+
prefix="+5 "
316317
[(ngModel)]="showMaskModel"
317318
[showMaskTyped]="true"
318319
/>
@@ -351,7 +352,7 @@ <h1 class="title">
351352
placeholder="Phone number"
352353
mask="(000) 000-0000"
353354
[formControl]="form1"
354-
prefix="+5"
355+
prefix="+5 "
355356
[(ngModel)]="showMaskModel"
356357
[showMaskTyped]="true"
357358
placeHolderCharacter="*"

src/app/app.component.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ export class AppComponent {
3030
public percent: FormControl;
3131
public formSecureInput: FormControl;
3232
public customPatternForm: FormControl;
33+
public hourTimeForm: FormControl;
34+
public hourForm: FormControl;
35+
public hour24Form: FormControl;
36+
public mixedTypeForm: FormControl;
37+
public dateMonthForm: FormControl;
3338

3439
public pattern: Pattern = {
3540
P: {
@@ -89,6 +94,11 @@ export class AppComponent {
8994
this.commaZeroPrecisionSeparatorForm = new FormControl('');
9095
this.percent = new FormControl('');
9196
this.customPatternForm = new FormControl('');
97+
this.hourTimeForm = new FormControl('');
98+
this.hourForm = new FormControl('');
99+
this.hour24Form = new FormControl('');
100+
this.mixedTypeForm = new FormControl('');
101+
this.dateMonthForm = new FormControl('');
92102

93103
this.customMaska = ['PPP-PPP-PPP', this.pattern];
94104
}

src/app/app.module.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
1616
import { BrowserModule } from '@angular/platform-browser';
1717
import { NgModule } from '@angular/core';
1818
import 'hammerjs';
19+
import { NgxMaskModule } from 'ngx-mask';
1920

2021
import { AppComponent } from './app.component';
21-
import { NgxMaskModule } from 'ngx-mask';
2222

2323
@NgModule({
2424
declarations: [AppComponent, TestMaskComponent],
@@ -33,7 +33,9 @@ import { NgxMaskModule } from 'ngx-mask';
3333
MatButtonModule,
3434
MatFormFieldModule,
3535
MatInputModule,
36-
NgxMaskModule.forRoot(),
36+
NgxMaskModule.forRoot({
37+
validation: true,
38+
}),
3739
MatIconModule,
3840
MatListModule,
3941
MatCardModule,
@@ -42,4 +44,4 @@ import { NgxMaskModule } from 'ngx-mask';
4244
providers: [],
4345
bootstrap: [AppComponent],
4446
})
45-
export class AppModule {}
47+
export class AppModule { }

0 commit comments

Comments
 (0)