aboutsummaryrefslogtreecommitdiffstats
path: root/src/angular/form-elements/validation
diff options
context:
space:
mode:
Diffstat (limited to 'src/angular/form-elements/validation')
-rw-r--r--src/angular/form-elements/validation/validatable.component.ts25
-rw-r--r--src/angular/form-elements/validation/validatable.interface.ts5
-rw-r--r--src/angular/form-elements/validation/validation-group.component.html.ts3
-rw-r--r--src/angular/form-elements/validation/validation-group.component.ts47
-rw-r--r--src/angular/form-elements/validation/validation.component.html.ts3
-rw-r--r--src/angular/form-elements/validation/validation.component.ts79
-rw-r--r--src/angular/form-elements/validation/validation.module.ts35
-rw-r--r--src/angular/form-elements/validation/validators/base.validator.component.html.ts10
-rw-r--r--src/angular/form-elements/validation/validators/base.validator.component.ts25
-rw-r--r--src/angular/form-elements/validation/validators/custom.validator.component.ts23
-rw-r--r--src/angular/form-elements/validation/validators/regex.validator.component.ts24
-rw-r--r--src/angular/form-elements/validation/validators/required.validator.component.ts25
-rw-r--r--src/angular/form-elements/validation/validators/validator.interface.ts3
13 files changed, 307 insertions, 0 deletions
diff --git a/src/angular/form-elements/validation/validatable.component.ts b/src/angular/form-elements/validation/validatable.component.ts
new file mode 100644
index 0000000..4817dea
--- /dev/null
+++ b/src/angular/form-elements/validation/validatable.component.ts
@@ -0,0 +1,25 @@
+import { Input, Component } from "@angular/core";
+import { ValidationComponent } from './validation.component';
+import { Subject } from 'rxjs/Subject';
+import { IValidatableComponent } from './validatable.interface';
+
+export abstract class ValidatableComponent implements IValidatableComponent {
+
+ // Each ValidatableComponent should handle the style in case of error, according to this boolean
+ public valid = true;
+
+ // Each ValidatableComponent will notify when the value is changed.
+ public notifier: Subject<string>;
+
+ constructor() {
+ this.notifier = new Subject();
+ }
+
+ public abstract getValue(): any;
+
+ // Each ValidatableComponent should call the valueChanged on value changed function.
+ protected valueChanged = (value: any): void => {
+ this.notifier.next(value);
+ }
+
+}
diff --git a/src/angular/form-elements/validation/validatable.interface.ts b/src/angular/form-elements/validation/validatable.interface.ts
new file mode 100644
index 0000000..6aceafe
--- /dev/null
+++ b/src/angular/form-elements/validation/validatable.interface.ts
@@ -0,0 +1,5 @@
+export interface IValidatableComponent {
+
+ getValue(): any;
+
+}
diff --git a/src/angular/form-elements/validation/validation-group.component.html.ts b/src/angular/form-elements/validation/validation-group.component.html.ts
new file mode 100644
index 0000000..dff591e
--- /dev/null
+++ b/src/angular/form-elements/validation/validation-group.component.html.ts
@@ -0,0 +1,3 @@
+export default `
+<ng-content></ng-content>
+`;
diff --git a/src/angular/form-elements/validation/validation-group.component.ts b/src/angular/form-elements/validation/validation-group.component.ts
new file mode 100644
index 0000000..59ecf4c
--- /dev/null
+++ b/src/angular/form-elements/validation/validation-group.component.ts
@@ -0,0 +1,47 @@
+import { Input, Component, ContentChildren, EventEmitter, Output, QueryList, SimpleChanges, HostBinding, AfterContentInit } from "@angular/core";
+import { AbstractControl, FormControl } from "@angular/forms";
+import { Subscribable } from "rxjs/Observable";
+import { AnonymousSubscription } from "rxjs/Subscription";
+import { IValidator } from './validators/validator.interface';
+import { ValidatorComponent } from './validators/base.validator.component';
+import { RegexValidatorComponent } from './validators/regex.validator.component';
+import { RequiredValidatorComponent } from './validators/required.validator.component';
+import { ValidatableComponent } from './validatable.component';
+import { ValidationComponent } from './validation.component';
+import { CustomValidatorComponent } from './validators/custom.validator.component';
+import template from "./validation.component.html";
+
+@Component({
+ selector: 'sdc-validation-group',
+ template
+})
+export class ValidationGroupComponent implements AfterContentInit {
+
+ @Input() public disabled: boolean;
+ @HostBinding('class') classes;
+
+ @ContentChildren(ValidationComponent) public validationsComponents: QueryList<ValidationComponent>;
+
+ private supportedValidator: Array<QueryList<ValidatorComponent>>;
+
+ constructor() {
+ this.disabled = false;
+ this.classes = 'sdc-validation-group';
+ }
+
+ ngAfterContentInit(): void {
+
+ }
+
+ public validate(): boolean {
+ let validationResult = true;
+ // Iterate over all validationComponent inside the group and return boolean result true in case all validations passed.
+ this.validationsComponents.forEach((validationComponent) => {
+ if (validationComponent.validate()) {
+ validationResult = false;
+ }
+ });
+ return validationResult;
+ }
+
+}
diff --git a/src/angular/form-elements/validation/validation.component.html.ts b/src/angular/form-elements/validation/validation.component.html.ts
new file mode 100644
index 0000000..0f11a23
--- /dev/null
+++ b/src/angular/form-elements/validation/validation.component.html.ts
@@ -0,0 +1,3 @@
+export default `
+<ng-content *ngIf="!disabled"></ng-content>
+`;
diff --git a/src/angular/form-elements/validation/validation.component.ts b/src/angular/form-elements/validation/validation.component.ts
new file mode 100644
index 0000000..4abdd12
--- /dev/null
+++ b/src/angular/form-elements/validation/validation.component.ts
@@ -0,0 +1,79 @@
+import { Input, Component, ContentChildren, EventEmitter, Output, QueryList, SimpleChanges, HostBinding, AfterContentInit } from "@angular/core";
+import { AbstractControl, FormControl } from "@angular/forms";
+import { Subscribable } from "rxjs/Observable";
+import { AnonymousSubscription } from "rxjs/Subscription";
+import { IValidator } from './validators/validator.interface';
+import { ValidatorComponent } from './validators/base.validator.component';
+import { RegexValidatorComponent } from './validators/regex.validator.component';
+import { RequiredValidatorComponent } from './validators/required.validator.component';
+import { ValidatableComponent } from './validatable.component';
+import { CustomValidatorComponent } from './validators/custom.validator.component';
+import template from "./validation.component.html";
+
+@Component({
+ selector: 'sdc-validation',
+ template
+})
+export class ValidationComponent implements AfterContentInit {
+
+ @Input() public validateElement: ValidatableComponent;
+ @Input() public disabled: boolean;
+ @Output() public validityChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
+ @HostBinding('class') classes;
+
+ // @ContentChildren does not recieve type any or IValidator or ValidatorComponent, so need to create @ContentChildren for each validator type.
+ @ContentChildren(RegexValidatorComponent) public regexValidator: QueryList<ValidatorComponent>;
+ @ContentChildren(RequiredValidatorComponent) public requireValidator: QueryList<ValidatorComponent>;
+ @ContentChildren(CustomValidatorComponent) public customValidator: QueryList<ValidatorComponent>;
+
+ private supportedValidator: Array<QueryList<ValidatorComponent>>;
+
+ constructor() {
+ this.disabled = false;
+ this.classes = 'sdc-validation';
+ }
+
+ ngAfterContentInit(): void {
+ this.supportedValidator = [
+ this.regexValidator,
+ this.requireValidator,
+ this.customValidator
+ ];
+
+ this.validateElement.notifier.subscribe(
+ (value) => {
+ const validationResult = this.validateOnChange(value);
+ this.validateElement.valid = validationResult;
+ },
+ (error) => console.log('Validation subscribe error')
+ );
+ }
+
+ public validate = (): boolean => {
+ const value = this.validateElement.getValue();
+ return this.validateOnChange(value);
+ }
+
+ private validateOnChange(value: any): boolean {
+ if (this.disabled) { return true; }
+
+ /**
+ * Iterate over all validators types (required, regex, etc...), and inside each iterate over
+ * all validators with same type, and return boolean result true in case all validations passed.
+ */
+ const validationResult: boolean = this.supportedValidator.reduce((sum, validatorName) => {
+ const response: boolean = validatorName.reduce((_sum, validator) => {
+ return _sum && validator.validate(value);
+ }, true);
+ return sum && response;
+ }, true);
+
+ if (this.validateElement.valid !== validationResult) {
+ this.validityChanged.emit(validationResult);
+ }
+
+ return validationResult;
+
+ }
+
+}
diff --git a/src/angular/form-elements/validation/validation.module.ts b/src/angular/form-elements/validation/validation.module.ts
new file mode 100644
index 0000000..4213f76
--- /dev/null
+++ b/src/angular/form-elements/validation/validation.module.ts
@@ -0,0 +1,35 @@
+import { NgModule } from "@angular/core";
+import { FormsModule, ReactiveFormsModule } from "@angular/forms";
+import { CommonModule } from "@angular/common";
+import { SvgIconModule } from './../../svg-icon/svg-icon.module';
+import { ValidationComponent } from './validation.component';
+import { ValidatorComponent } from './validators/base.validator.component';
+import { RequiredValidatorComponent } from './validators/required.validator.component';
+import { RegexValidatorComponent } from './validators/regex.validator.component';
+import { CustomValidatorComponent } from './validators/custom.validator.component';
+import { ValidationGroupComponent } from './validation-group.component';
+
+@NgModule({
+ imports: [
+ FormsModule,
+ CommonModule,
+ ReactiveFormsModule,
+ SvgIconModule
+ ],
+ declarations: [
+ ValidationComponent,
+ RegexValidatorComponent,
+ RequiredValidatorComponent,
+ CustomValidatorComponent,
+ ValidationGroupComponent
+ ],
+ exports: [
+ ValidationComponent,
+ RegexValidatorComponent,
+ RequiredValidatorComponent,
+ CustomValidatorComponent,
+ ValidationGroupComponent
+ ]
+})
+export class ValidationModule {
+}
diff --git a/src/angular/form-elements/validation/validators/base.validator.component.html.ts b/src/angular/form-elements/validation/validators/base.validator.component.html.ts
new file mode 100644
index 0000000..aba8eed
--- /dev/null
+++ b/src/angular/form-elements/validation/validators/base.validator.component.html.ts
@@ -0,0 +1,10 @@
+export default `
+<svg-icon-label
+ *ngIf="!isValid"
+ name="alert-triangle"
+ mode="error"
+ size="small"
+ [label]="message"
+ labelPlacement="right">
+</svg-icon-label>
+`;
diff --git a/src/angular/form-elements/validation/validators/base.validator.component.ts b/src/angular/form-elements/validation/validators/base.validator.component.ts
new file mode 100644
index 0000000..3d751af
--- /dev/null
+++ b/src/angular/form-elements/validation/validators/base.validator.component.ts
@@ -0,0 +1,25 @@
+import { Input, Component, ContentChildren, EventEmitter, Output, QueryList, SimpleChanges, HostBinding } from "@angular/core";
+import { IValidator } from './validator.interface';
+import template from "./base.validator.component.html";
+
+@Component({
+ selector: 'sdc-validator',
+ template: template
+})
+export abstract class ValidatorComponent {
+
+ @Input() public message: any;
+ @Input() public disabled: boolean;
+ @HostBinding('class') classes;
+
+ protected isValid: boolean;
+
+ constructor() {
+ this.disabled = false;
+ this.isValid = true;
+ this.classes = 'sdc-validator sdc-label__error';
+ }
+
+ public abstract validate(value: any): boolean;
+
+}
diff --git a/src/angular/form-elements/validation/validators/custom.validator.component.ts b/src/angular/form-elements/validation/validators/custom.validator.component.ts
new file mode 100644
index 0000000..eb09636
--- /dev/null
+++ b/src/angular/form-elements/validation/validators/custom.validator.component.ts
@@ -0,0 +1,23 @@
+import { Input, Component } from "@angular/core";
+import { ValidatorComponent } from "./base.validator.component";
+import { IValidator } from './validator.interface';
+import template from "./base.validator.component.html";
+
+@Component({
+ selector: 'sdc-custom-validator',
+ template: template
+})
+export class CustomValidatorComponent extends ValidatorComponent implements IValidator {
+
+ @Input() public callback: (...args) => boolean;
+
+ constructor() {
+ super();
+ }
+
+ public validate(value: any): boolean {
+ this.isValid = this.callback(value);
+ return this.isValid;
+ }
+
+}
diff --git a/src/angular/form-elements/validation/validators/regex.validator.component.ts b/src/angular/form-elements/validation/validators/regex.validator.component.ts
new file mode 100644
index 0000000..5929016
--- /dev/null
+++ b/src/angular/form-elements/validation/validators/regex.validator.component.ts
@@ -0,0 +1,24 @@
+import { Input, Component } from "@angular/core";
+import { ValidatorComponent } from "./base.validator.component";
+import { IValidator } from './validator.interface';
+import template from "./base.validator.component.html";
+
+@Component({
+ selector: 'sdc-regex-validator',
+ template: template
+})
+export class RegexValidatorComponent extends ValidatorComponent implements IValidator {
+
+ @Input() public pattern: RegExp;
+
+ constructor() {
+ super();
+ }
+
+ public validate(value: any): boolean {
+ const regexp = new RegExp(this.pattern);
+ this.isValid = regexp.test(value);
+ return this.isValid;
+ }
+
+}
diff --git a/src/angular/form-elements/validation/validators/required.validator.component.ts b/src/angular/form-elements/validation/validators/required.validator.component.ts
new file mode 100644
index 0000000..7eee932
--- /dev/null
+++ b/src/angular/form-elements/validation/validators/required.validator.component.ts
@@ -0,0 +1,25 @@
+import { Input, Component } from "@angular/core";
+import { ValidatorComponent } from "./base.validator.component";
+import { IValidator } from './validator.interface';
+import template from "./base.validator.component.html";
+
+@Component({
+ selector: 'sdc-required-validator',
+ template: template
+})
+export class RequiredValidatorComponent extends ValidatorComponent implements IValidator {
+
+ constructor() {
+ super();
+ }
+
+ public validate(value: any): boolean {
+ if (value) {
+ this.isValid = true;
+ } else {
+ this.isValid = false;
+ }
+ return this.isValid;
+ }
+
+}
diff --git a/src/angular/form-elements/validation/validators/validator.interface.ts b/src/angular/form-elements/validation/validators/validator.interface.ts
new file mode 100644
index 0000000..c0adc24
--- /dev/null
+++ b/src/angular/form-elements/validation/validators/validator.interface.ts
@@ -0,0 +1,3 @@
+export interface IValidator {
+ validate(value: any): void;
+}