Skip to content

Commit

Permalink
fix(directives): don't trigger validation changed on the first ngOnCh…
Browse files Browse the repository at this point in the history
…anges call
  • Loading branch information
Nightapes committed Apr 20, 2020
1 parent e0595ff commit 221fda2
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 220 deletions.
21 changes: 0 additions & 21 deletions examples/package-lock.json

This file was deleted.

2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"core-js": "^2.4.1",
"hammerjs": "^2.0.8",
"ngx-highlightjs": "^2.1.1",
"ngx-validators": "5.2.0",
"ngx-validators": "file:../dist",
"rxjs": "^6.2.2",
"zone.js": "^0.8.5"
},
Expand Down
31 changes: 9 additions & 22 deletions src/components/creditcard/creditcard.directive.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
import {
Directive,
Input,
forwardRef,
OnInit,
SimpleChanges
} from "@angular/core";
import {
NG_VALIDATORS,
Validator,
ValidatorFn,
AbstractControl,
ValidationErrors
} from "@angular/forms";
import { Directive, Input, forwardRef, OnInit, SimpleChanges, OnChanges } from "@angular/core";
import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl, ValidationErrors } from "@angular/forms";

import { CreditCardValidators } from "./creditcard-validators";

@Directive({
selector:
"[creditCard][formControlName],[creditCard][formControl],[creditCard][ngModel]",
selector: "[creditCard][formControlName],[creditCard][formControl],[creditCard][ngModel]",
providers: [
{
provide: NG_VALIDATORS,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
useExisting: forwardRef(() => CreditCardValidatorDirective),
multi: true
}
]
multi: true,
},
],
})
export class CreditCardValidatorDirective implements Validator, OnInit {
export class CreditCardValidatorDirective implements Validator, OnInit, OnChanges {
@Input() creditCard = "all";

private validator: ValidatorFn;
Expand Down Expand Up @@ -70,8 +57,8 @@ export class CreditCardValidatorDirective implements Validator, OnInit {
}

ngOnChanges(changes: SimpleChanges): void {
if (changes["creditCard"]) {
this.setCreditcardValidator(changes["creditCard"].currentValue);
if (changes.creditCard && !changes.creditCard.isFirstChange()) {
this.setCreditcardValidator(changes.creditCard.currentValue);
this.onChange();
}
}
Expand Down
44 changes: 14 additions & 30 deletions src/components/email/email.directive.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import { EmailOptions } from "./email-util";
import {
Directive,
Input,
forwardRef,
OnInit,
OnChanges,
SimpleChanges
} from "@angular/core";
import {
NG_VALIDATORS,
Validator,
ValidatorFn,
AbstractControl,
ValidationErrors
} from "@angular/forms";
import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from "@angular/core";
import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl, ValidationErrors } from "@angular/forms";

import { EmailValidators } from "./email-validators";

Expand All @@ -24,9 +11,9 @@ import { EmailValidators } from "./email-validators";
provide: NG_VALIDATORS,
// tslint:disable-next-line:no-forward-ref
useExisting: forwardRef(() => EmailValidatorDirective),
multi: true
}
]
multi: true,
},
],
})
export class EmailValidatorDirective implements Validator, OnInit, OnChanges {
@Input() email: "normal" | "simple" = "normal";
Expand All @@ -53,8 +40,8 @@ export class EmailValidatorDirective implements Validator, OnInit, OnChanges {
}

ngOnChanges(changes: SimpleChanges): void {
if (changes["email"]) {
this.setValidator(changes["email"].currentValue);
if (changes.email && !changes.email.isFirstChange()) {
this.setValidator(changes.email.currentValue);
this.onChange();
}
}
Expand All @@ -69,18 +56,17 @@ export class EmailValidatorDirective implements Validator, OnInit, OnChanges {
}

@Directive({
selector:
"[emailSuggest][formControlName],[emailSuggest][formControl],[emailSuggest][ngModel]",
selector: "[emailSuggest][formControlName],[emailSuggest][formControl],[emailSuggest][ngModel]",
providers: [
{
provide: NG_VALIDATORS,
// tslint:disable-next-line:no-forward-ref
useExisting: forwardRef(() => EmailSuggestValidatorDirective),
multi: true
}
]
multi: true,
},
],
})
export class EmailSuggestValidatorDirective implements Validator, OnInit {
export class EmailSuggestValidatorDirective implements Validator, OnInit, OnChanges {
@Input() emailSuggest: EmailOptions;

private validator: ValidatorFn;
Expand All @@ -91,10 +77,8 @@ export class EmailSuggestValidatorDirective implements Validator, OnInit {
}

ngOnChanges(changes: SimpleChanges): void {
if (changes["emailSuggest"]) {
this.validator = EmailValidators.suggest(
changes["emailSuggest"].currentValue
);
if (changes.emailSuggest && !changes.emailSuggest.isFirstChange()) {
this.validator = EmailValidators.suggest(changes.emailSuggest.currentValue);
this.onChange();
}
}
Expand Down
40 changes: 11 additions & 29 deletions src/components/equal-to/equal-to.directive.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
import {
Directive,
forwardRef,
Input,
OnDestroy,
SimpleChanges,
OnChanges
} from "@angular/core";
import {
AbstractControl,
NG_VALIDATORS,
ValidationErrors,
Validator
} from "@angular/forms";
import { Directive, forwardRef, Input, OnDestroy, SimpleChanges, OnChanges } from "@angular/core";
import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from "@angular/forms";
import { Subscription } from "rxjs";
import { delay } from "rxjs/operators";

@Directive({
selector:
"[equalTo][ngModel], [equalTo][formControlName], [equalTo][formControl]",
selector: "[equalTo][ngModel], [equalTo][formControlName], [equalTo][formControl]",
providers: [
{
provide: NG_VALIDATORS,
// tslint:disable-next-line:no-forward-ref
useExisting: forwardRef(() => EqualToDirective),
multi: true
}
]
multi: true,
},
],
})
export class EqualToDirective implements Validator, OnDestroy, OnChanges {
@Input() equalTo: string | AbstractControl;
Expand All @@ -34,17 +21,12 @@ export class EqualToDirective implements Validator, OnDestroy, OnChanges {
private onChange: () => void;

validate(c: AbstractControl): ValidationErrors | null {
const otherControl =
typeof this.equalTo === "string"
? c.parent.get(this.equalTo)
: this.equalTo;
const otherControl = typeof this.equalTo === "string" ? c.parent.get(this.equalTo) : this.equalTo;

if (!this.subscription) {
this.subscription = otherControl.valueChanges
.pipe(delay(1))
.subscribe(() => {
c.updateValueAndValidity();
});
this.subscription = otherControl.valueChanges.pipe(delay(1)).subscribe(() => {
c.updateValueAndValidity();
});
}
return c.value !== otherControl.value ? { notEqualTo: true } : null;
}
Expand All @@ -54,7 +36,7 @@ export class EqualToDirective implements Validator, OnDestroy, OnChanges {
}

ngOnChanges(changes: SimpleChanges): void {
if (changes["equalTo"]) {
if (changes.equalTo && !changes.equalTo.isFirstChange()) {
this.onChange();
}
}
Expand Down
86 changes: 28 additions & 58 deletions src/components/password/password.directive.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,20 @@
import {
Directive,
Input,
forwardRef,
OnInit,
SimpleChanges,
OnChanges
} from "@angular/core";
import {
NG_VALIDATORS,
Validator,
Validators,
ValidatorFn,
AbstractControl,
ValidationErrors
} from "@angular/forms";
import { Directive, Input, forwardRef, OnInit, SimpleChanges, OnChanges } from "@angular/core";
import { NG_VALIDATORS, Validator, Validators, ValidatorFn, AbstractControl, ValidationErrors } from "@angular/forms";

import { PasswordValidators } from "./password-validators";

@Directive({
selector:
"[password][formControlName],[password][formControl],[password][ngModel]",
selector: "[password][formControlName],[password][formControl],[password][ngModel]",
providers: [
{
provide: NG_VALIDATORS,
// tslint:disable-next-line:no-forward-ref
useExisting: forwardRef(() => PasswordValidatorDirective),
multi: true
}
]
multi: true,
},
],
})
export class PasswordValidatorDirective
implements Validator, OnInit, OnChanges {
export class PasswordValidatorDirective implements Validator, OnInit, OnChanges {
@Input() repeatCharacter = 4;
@Input() alphabeticalCharacter = 1;
@Input() digitCharacter = 1;
Expand All @@ -45,58 +29,44 @@ export class PasswordValidatorDirective
private onChange: () => void;

ngOnInit() {
this.repeatCharacterValidator = PasswordValidators.repeatCharacterRegexRule(
this.repeatCharacter
);
this.alphabeticalCharacterValidator = PasswordValidators.alphabeticalCharacterRule(
this.alphabeticalCharacter
);
this.digitCharacterValidator = PasswordValidators.digitCharacterRule(
this.digitCharacter
);
this.lowercaseCharacterValidator = PasswordValidators.lowercaseCharacterRule(
this.lowercaseCharacter
);
this.uppercaseCharacterValidator = PasswordValidators.uppercaseCharacterRule(
this.uppercaseCharacter
);
this.repeatCharacterValidator = PasswordValidators.repeatCharacterRegexRule(this.repeatCharacter);
this.alphabeticalCharacterValidator = PasswordValidators.alphabeticalCharacterRule(this.alphabeticalCharacter);
this.digitCharacterValidator = PasswordValidators.digitCharacterRule(this.digitCharacter);
this.lowercaseCharacterValidator = PasswordValidators.lowercaseCharacterRule(this.lowercaseCharacter);
this.uppercaseCharacterValidator = PasswordValidators.uppercaseCharacterRule(this.uppercaseCharacter);
}

ngOnChanges(changes: SimpleChanges): void {
let inputChanged = false;
if (changes["repeatCharacter"]) {
this.repeatCharacterValidator = PasswordValidators.repeatCharacterRegexRule(
changes["repeatCharacter"].currentValue
);
inputChanged = true;
if (changes.repeatCharacter) {
this.repeatCharacterValidator = PasswordValidators.repeatCharacterRegexRule(changes.repeatCharacter.currentValue);
inputChanged = changes.repeatCharacter.isFirstChange() ? false : true;
}

if (changes["alphabeticalCharacter"]) {
if (changes.alphabeticalCharacter) {
this.alphabeticalCharacterValidator = PasswordValidators.alphabeticalCharacterRule(
changes["alphabeticalCharacter"].currentValue
changes.alphabeticalCharacter.currentValue
);
inputChanged = true;
inputChanged = changes.alphabeticalCharacter.isFirstChange() ? false : true;
}

if (changes["digitCharacter"]) {
this.digitCharacterValidator = PasswordValidators.digitCharacterRule(
changes["digitCharacter"].currentValue
);
inputChanged = true;
if (changes.digitCharacter) {
this.digitCharacterValidator = PasswordValidators.digitCharacterRule(changes.digitCharacter.currentValue);
inputChanged = changes.digitCharacter.isFirstChange() ? false : true;
}

if (changes["lowercaseCharacter"]) {
if (changes.lowercaseCharacter) {
this.lowercaseCharacterValidator = PasswordValidators.lowercaseCharacterRule(
changes["lowercaseCharacter"].currentValue
changes.lowercaseCharacter.currentValue
);
inputChanged = true;
inputChanged = changes.lowercaseCharacter.isFirstChange() ? false : true;
}

if (changes["uppercaseCharacter"]) {
if (changes.uppercaseCharacter) {
this.uppercaseCharacterValidator = PasswordValidators.uppercaseCharacterRule(
changes["uppercaseCharacter"].currentValue
changes.uppercaseCharacter.currentValue
);
inputChanged = true;
inputChanged = changes.uppercaseCharacter.isFirstChange() ? false : true;
}

if (inputChanged) {
Expand All @@ -110,7 +80,7 @@ export class PasswordValidatorDirective
this.digitCharacterValidator,
this.alphabeticalCharacterValidator,
this.lowercaseCharacterValidator,
this.uppercaseCharacterValidator
this.uppercaseCharacterValidator,
]);
return compose(c);
}
Expand Down
Loading

0 comments on commit 221fda2

Please sign in to comment.