├── src
├── date
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── json
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.spec.ts
│ ├── validator.ts
│ └── directive.ts
├── max
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── min
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.spec.ts
│ ├── validator.ts
│ └── directive.ts
├── url
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── directive.ts
│ ├── validator.spec.ts
│ └── validator.ts
├── uuid
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.spec.ts
│ ├── validator.ts
│ └── directive.ts
├── base64
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── date-ios
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── digits
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── email
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── equal-to
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── equal
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── less-than
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.spec.ts
│ ├── validator.ts
│ └── directive.ts
├── max-date
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── min-date
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── not-equal
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── number
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── phone
│ ├── directive.spec.ts
│ ├── validator.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ └── directive.ts
├── range
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── credit-card
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── directive.ts
│ ├── validator.spec.ts
│ └── validator.ts
├── greater-than
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.spec.ts
│ ├── validator.ts
│ └── directive.ts
├── not-equal-to
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── directive.ts
│ └── validator.spec.ts
├── range-length
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── greater-than-equal
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── less-than-equal
│ ├── directive.spec.ts
│ ├── index.ts
│ ├── validator.ts
│ ├── validator.spec.ts
│ └── directive.ts
├── util
│ └── lang.ts
└── index.ts
├── .travis.yml
├── example
├── polyfills.ts
├── main.ts
├── src
│ ├── app.less
│ ├── app.module.ts
│ ├── app.component.ts
│ └── app.html
├── vendor.ts
└── dist
│ └── polyfills.js
├── .gitignore
├── .npmignore
├── .editorconfig
├── index.html
├── rollup.config.js
├── tsconfig.json
├── karma-test-shim.js
├── CHANGELOG.md
├── webpack.config.js
├── karma.conf.js
├── LICENSE
├── package.json
├── README.md
└── bundles
└── ng2-validation.umd.js
/src/date/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/json/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/max/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/min/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/url/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/uuid/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/base64/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/date-ios/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/digits/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/email/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/equal-to/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/equal/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/less-than/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/max-date/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/min-date/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/not-equal/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/number/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/phone/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/phone/validator.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/range/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/credit-card/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/greater-than/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/not-equal-to/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/range-length/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/greater-than-equal/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/src/less-than-equal/directive.spec.ts:
--------------------------------------------------------------------------------
1 | // todo
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "4"
4 | - "5"
5 | - "6"
--------------------------------------------------------------------------------
/example/polyfills.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata';
2 | import 'zone.js/dist/zone';
--------------------------------------------------------------------------------
/src/json/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
--------------------------------------------------------------------------------
/src/date/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/digits/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
--------------------------------------------------------------------------------
/src/max/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/min/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/phone/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
--------------------------------------------------------------------------------
/src/url/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/uuid/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/base64/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/date-ios/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/email/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/equal-to/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/equal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/less-than/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/max-date/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/min-date/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/not-equal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/number/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/range/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/credit-card/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/greater-than/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/not-equal-to/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/range-length/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | typings/
3 | node_modules/
4 | dist/
5 | .DS_Store
6 | aot/
7 | !example/dist
--------------------------------------------------------------------------------
/src/greater-than-equal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/src/less-than-equal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './directive';
2 | export * from './validator';
3 |
--------------------------------------------------------------------------------
/example/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './src/app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
--------------------------------------------------------------------------------
/example/src/app.less:
--------------------------------------------------------------------------------
1 | @import "~bootstrap/less/bootstrap";
2 |
3 | .container {
4 | margin-top: 50px;
5 | margin-bottom: 50px;
6 | width: 600px;
7 | }
8 |
9 | .alert {
10 | padding: 5px;
11 | }
--------------------------------------------------------------------------------
/src/util/lang.ts:
--------------------------------------------------------------------------------
1 | export function isPresent(obj: any): boolean {
2 | return obj !== undefined && obj !== null;
3 | }
4 |
5 | export function isDate(obj: any): boolean {
6 | return !/Invalid|NaN/.test(new Date(obj).toString());
7 | }
--------------------------------------------------------------------------------
/example/vendor.ts:
--------------------------------------------------------------------------------
1 | import '@angular/platform-browser';
2 | import '@angular/platform-browser-dynamic';
3 | import '@angular/core';
4 | import '@angular/compiler';
5 | import '@angular/common';
6 | import '@angular/http';
7 | import '@angular/forms';
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | example/
2 | typings/
3 | .idea/
4 | .gitignore
5 | index.html
6 | tsconfig.json
7 | typings.json
8 | webpack.config.js
9 | src/
10 | aot/
11 | .npmignore
12 | karma-test-shim.js
13 | karma.conf.js
14 | CHANGELOG.md
15 | rollup.config.js
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/date/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent, isDate } from '../util/lang';
4 |
5 | export const date: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return isDate(v) ? null : {date: true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/digits/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const digits: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return /^\d+$/.test(v) ? null : {digits: true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/equal/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const equal = (val: any): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: any} => {
7 | if (isPresent(Validators.required(control))) return null;
8 |
9 | let v: any = control.value;
10 |
11 | return val === v ? null : {equal: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/number/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const number: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(v) ? null : {'number': true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/not-equal/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const notEqual = (val: any): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (isPresent(Validators.required(control))) return null;
8 |
9 | let v: any = control.value;
10 |
11 | return val !== v ? null : {notEqual: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/base64/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const base64: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i.test(v) ? null : {'base64': true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/date-ios/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent, isDate } from '../util/lang';
4 |
5 | export const dateISO: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(v) ? null : {dateISO: true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/greater-than/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { gt } from './';
4 |
5 | describe('GT', () => {
6 | const error = {gt: true};
7 |
8 | it('5 should be gt 3', () => {
9 | let control = new FormControl(5);
10 |
11 | expect(gt(3)(control)).toBeNull();
12 | });
13 |
14 | it('3 should not be gt 5', () => {
15 | let control = new FormControl(3);
16 |
17 | expect(gt(5)(control)).toEqual(error);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/less-than/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { lt } from './';
4 |
5 | describe('LT', () => {
6 | const error = {lt: true};
7 |
8 | it('3 should be lt 5', () => {
9 | let control = new FormControl(3);
10 |
11 | expect(lt(5)(control)).toBeNull();
12 | });
13 |
14 | it('5 should not be lt 3', () => {
15 | let control = new FormControl(5);
16 |
17 | expect(lt(3)(control)).toEqual(error);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/min/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { min } from './';
4 |
5 | describe('Min', () => {
6 | it('6 should be over 5', () => {
7 | let control = new FormControl(6);
8 |
9 | expect(min(5)(control)).toBeNull();
10 | });
11 |
12 | it('9 should not be over 10', () => {
13 | let control = new FormControl(9);
14 |
15 | expect(min(10)(control)).toEqual({min: true, actualValue: 9, requiredValue: 10});
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/less-than/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const lt = (lt: number): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (!isPresent(lt)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v < +lt ? null : {lt: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/greater-than/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const gt = (gt: number): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (!isPresent(gt)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v > +gt ? null : {gt: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/less-than-equal/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const lte = (lte: number): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (!isPresent(lte)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v <= +lte ? null : {lte: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/greater-than-equal/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const gte = (gte: number): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (!isPresent(gte)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v >= +gte ? null : {gte: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/json/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { json } from './';
4 |
5 | describe('JSON', () => {
6 | const error = {json: true};
7 |
8 | it('"{"name": "xxx"}" should be json', () => {
9 | let control = new FormControl('{"name": "xxx"}');
10 | expect(json(control)).toBeNull();
11 | });
12 |
13 | it('"123a" should not be json', () => {
14 | let control = new FormControl('123a');
15 | expect(json(control)).toEqual(error);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/example/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { ReactiveFormsModule, FormsModule } from '@angular/forms';
4 |
5 | import { AppComponent } from './app.component';
6 | import { CustomFormsModule } from '../../src';
7 |
8 | @NgModule({
9 | imports: [BrowserModule, ReactiveFormsModule, FormsModule, CustomFormsModule],
10 | declarations: [AppComponent],
11 | bootstrap: [AppComponent]
12 | })
13 | export class AppModule {
14 | }
--------------------------------------------------------------------------------
/src/base64/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { base64 } from './';
4 |
5 | describe('Base64', () => {
6 | const error = {base64: true};
7 |
8 | it('"ZGFua29nYWk=" should be base64', () => {
9 | let control = new FormControl('ZGFua29nYWk=');
10 | expect(base64(control)).toBeNull();
11 | });
12 |
13 | it('"ZGFua" should not be base64', () => {
14 | let control = new FormControl('ZGFua');
15 | expect(base64(control)).toEqual(error);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/equal/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { equal } from './';
4 |
5 | describe('Equal', () => {
6 | const error = {equal: true};
7 |
8 | it('"aaa" and "aaa" should be equal', () => {
9 | let control = new FormControl('aaa');
10 | expect(equal('aaa')(control)).toBeNull();
11 | });
12 |
13 | it('"aaa" and "bbb" should not be email', () => {
14 | let control = new FormControl('bbb');
15 | expect(equal('aaa')(control)).toEqual(error);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/max/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const max = (max: number): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: any} => {
7 | if (!isPresent(max)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v <= +max ? null : {actualValue: v, requiredValue: +max, max: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/min/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const min = (min: number): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: any} => {
7 | if (!isPresent(min)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v >= +min ? null : {actualValue: v, requiredValue: +min, min: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/date-ios/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { dateISO } from './';
4 |
5 | describe('DateISO', () => {
6 | const error = {dateISO: true};
7 |
8 | it('"2013-11-12" should be dateISO', () => {
9 | let control = new FormControl('2013-11-12');
10 | expect(dateISO(control)).toBeNull();
11 | });
12 |
13 | it('"2013-13-12" should not be dateISO', () => {
14 | let control = new FormControl('2013-13-12');
15 | expect(dateISO(control)).toEqual(error);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/uuid/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { uuid } from './';
4 |
5 | describe('Uuid', () => {
6 | // it('"AAAAAAAA-BBBB-3CCCC-DDDD-EEEEEEEEEEEE" should be uuid', () => {
7 | // let control = new FormControl('AAAAAAAA-BBBB-3CCCC-DDDD-EEEEEEEEEEEE');
8 | // expect(uuid('3')(control)).toBeNull();
9 | // });
10 |
11 | it('"abc" should not be uuid', () => {
12 | let control = new FormControl('abc');
13 | expect(uuid('4')(control)).toEqual({uuid: true});
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/src/phone/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 | import { isValidNumber } from 'libphonenumber-js';
3 |
4 | import { isPresent } from '../util/lang';
5 |
6 | export const phone = (country: string): ValidatorFn => {
7 | return (control: AbstractControl): { [key: string]: boolean } => {
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: string = control.value;
11 |
12 | return isValidNumber({phone: v, country}) ? null : {phone: true};
13 | };
14 | };
15 |
--------------------------------------------------------------------------------
/src/not-equal/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { notEqual } from './';
4 |
5 | describe('NotEqual', () => {
6 | const error = {notEqual: true};
7 |
8 | it('"aaa" and "bbb" should be notEqual', () => {
9 | let control = new FormControl('bbb');
10 | expect(notEqual('aaa')(control)).toBeNull();
11 | });
12 |
13 | it('"aaa" and "aaa" should not be notEqual', () => {
14 | let control = new FormControl('aaa');
15 | expect(notEqual('aaa')(control)).toEqual(error);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/email/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const email: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(v) ? null : {'email': true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/json/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const json: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 |
10 | try {
11 | let obj = JSON.parse(v);
12 |
13 | if (Boolean(obj) && typeof obj === 'object') {
14 | return null;
15 | }
16 | } catch (e) {
17 | }
18 | return {json: true};
19 | };
20 |
--------------------------------------------------------------------------------
/src/range/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const range = (range: Array): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: any} => {
7 | if (!isPresent(range)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: number = +control.value;
11 | return v >= range[0] && v <= range[1] ? null : {actualValue: v, requiredValue: range, range: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | const pluginTypescript = require('rollup-plugin-typescript');
2 | const typescript = require('typescript');
3 |
4 | module.exports = {
5 | entry: 'src/index.ts',
6 | dest: 'bundles/ng2-validation.umd.js',
7 | format: 'umd',
8 | sourceMap: true,
9 | moduleName: 'ng.validation',
10 | plugins: [
11 | pluginTypescript({
12 | typescript: typescript
13 | })
14 | ],
15 | globals: {
16 | '@angular/core': 'ng.core',
17 | '@angular/forms': 'ng.forms'
18 | },
19 | external: [ '@angular/core', '@angular/forms' ]
20 | };
21 |
--------------------------------------------------------------------------------
/src/range-length/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const rangeLength = (rangeLength: Array): ValidatorFn => {
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (!isPresent(rangeLength)) return null;
8 | if (isPresent(Validators.required(control))) return null;
9 |
10 | let v: string = control.value;
11 | return v.length >= rangeLength[0] && v.length <= rangeLength[1] ? null : {rangeLength: true};
12 | };
13 | };
14 |
--------------------------------------------------------------------------------
/src/equal-to/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, ValidatorFn } from '@angular/forms';
2 |
3 | export const equalTo = (equalControl: AbstractControl): ValidatorFn => {
4 | let subscribe: boolean = false;
5 |
6 | return (control: AbstractControl): {[key: string]: boolean} => {
7 | if (!subscribe) {
8 | subscribe = true;
9 | equalControl.valueChanges.subscribe(() => {
10 | control.updateValueAndValidity();
11 | });
12 | }
13 |
14 | let v: string = control.value;
15 |
16 | return equalControl.value === v ? null : {equalTo: true};
17 | };
18 | };
19 |
--------------------------------------------------------------------------------
/src/not-equal-to/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, ValidatorFn } from '@angular/forms';
2 |
3 | export const notEqualTo = (notEqualControl: AbstractControl): ValidatorFn => {
4 | let subscribe: boolean = false;
5 | return (control: AbstractControl): {[key: string]: boolean} => {
6 | if (!subscribe) {
7 | subscribe = true;
8 | notEqualControl.valueChanges.subscribe(() => {
9 | control.updateValueAndValidity();
10 | });
11 | }
12 |
13 | let v: string = control.value;
14 |
15 | return notEqualControl.value !== v ? null : {notEqualTo: true};
16 | };
17 | };
18 |
--------------------------------------------------------------------------------
/src/url/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { url } from './';
5 |
6 | const URL_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => UrlValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[url][formControlName],[url][formControl],[url][ngModel]',
14 | providers: [URL_VALIDATOR]
15 | })
16 | export class UrlValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return url(c);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/json/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { json } from './';
5 |
6 | const JSON_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => JSONValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[json][formControlName],[json][formControl],[json][ngModel]',
14 | providers: [JSON_VALIDATOR]
15 | })
16 | export class JSONValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return json(c);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/date/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { date } from './';
5 |
6 | const DATE_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => DateValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[date][formControlName],[date][formControl],[date][ngModel]',
14 | providers: [DATE_VALIDATOR]
15 | })
16 | export class DateValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return date(c);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/less-than-equal/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { lte } from './';
4 |
5 | describe('LTE', () => {
6 | const error = {lte: true};
7 |
8 | it('3 should be lte 5', () => {
9 | let control = new FormControl(3);
10 |
11 | expect(lte(5)(control)).toBeNull();
12 | });
13 |
14 | it('5 should be lte 5', () => {
15 | let control = new FormControl(5);
16 |
17 | expect(lte(5)(control)).toBeNull();
18 | });
19 |
20 | it('5 should not be lte 3', () => {
21 | let control = new FormControl(5);
22 |
23 | expect(lte(3)(control)).toEqual(error);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/greater-than-equal/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { gte } from './';
4 |
5 | describe('GTE', () => {
6 | const error = {gte: true};
7 |
8 | it('5 should be gte 3', () => {
9 | let control = new FormControl(5);
10 |
11 | expect(gte(3)(control)).toBeNull();
12 | });
13 |
14 | it('5 should be gte 5', () => {
15 | let control = new FormControl(5);
16 |
17 | expect(gte(5)(control)).toBeNull();
18 | });
19 |
20 | it('3 should not be gte 5', () => {
21 | let control = new FormControl(3);
22 |
23 | expect(gte(5)(control)).toEqual(error);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/email/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { email } from './index';
5 |
6 | const EMAIL_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => EmailValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[email][formControlName],[email][formControl],[email][ngModel]',
14 | providers: [EMAIL_VALIDATOR]
15 | })
16 | export class EmailValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return email(c);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/number/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { number } from './';
5 |
6 | const NUMBER_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => NumberValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[number][formControlName],[number][formControl],[number][ngModel]',
14 | providers: [NUMBER_VALIDATOR]
15 | })
16 | export class NumberValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return number(c);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/base64/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { base64 } from './';
5 |
6 | const BASE64_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => Base64Validator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[base64][formControlName],[base64][formControl],[base64][ngModel]',
14 | providers: [BASE64_VALIDATOR]
15 | })
16 | export class Base64Validator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return base64(c);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/digits/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { digits } from './';
5 |
6 | const DIGITS_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => DigitsValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[digits][formControlName],[digits][formControl],[digits][ngModel]',
14 | providers: [DIGITS_VALIDATOR]
15 | })
16 | export class DigitsValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return digits(c);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/equal-to/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { equalTo } from './';
4 |
5 | describe('EqualTo', () => {
6 | const error = {equalTo: true};
7 |
8 | it('"aaa" and "aaa" should be equalTo', () => {
9 | let control = new FormControl('aaa');
10 | let control1 = new FormControl('aaa');
11 |
12 | expect(equalTo(control1)(control)).toBeNull();
13 | });
14 |
15 | it('"aaa" and "bbb" should not be equalTo', () => {
16 | let control = new FormControl('aaa');
17 | let control1 = new FormControl('bbb');
18 |
19 | expect(equalTo(control1)(control)).toEqual(error);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/src/date-ios/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { dateISO } from './';
5 |
6 | const DATE_ISO_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => DateISOValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[dateISO][formControlName],[dateISO][formControl],[dateISO][ngModel]',
14 | providers: [DATE_ISO_VALIDATOR]
15 | })
16 | export class DateISOValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return dateISO(c);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/email/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { email } from './';
4 |
5 | describe('Email', () => {
6 | const error = {email: true};
7 |
8 | it('"test@gmail.com" should be email', () => {
9 | let control = new FormControl('test@gmail.com');
10 | expect(email(control)).toBeNull();
11 | });
12 |
13 | it('"test@xxx" should not be email', () => {
14 | let control = new FormControl('test');
15 | expect(email(control)).toEqual(error);
16 | });
17 |
18 | it('"abc" should not be email', () => {
19 | let control = new FormControl('abc');
20 | expect(email(control)).toEqual(error);
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/src/max/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { max } from './';
4 |
5 | describe('Max', () => {
6 | it('1 should be under 5', () => {
7 | let control = new FormControl(1);
8 |
9 | expect(max(5)(control)).toBeNull();
10 | });
11 |
12 | it('9 should not be over 5', () => {
13 | let control = new FormControl(9);
14 |
15 | expect(max(5)(control)).toEqual({max: true, actualValue: 9, requiredValue: 5});
16 | });
17 |
18 | it('"19" should not be over 5', () => {
19 | let control = new FormControl('19');
20 |
21 | expect(max(5)(control)).toEqual({max: true, actualValue: 19, requiredValue: 5});
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/src/credit-card/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, forwardRef } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
3 |
4 | import { creditCard } from './';
5 |
6 | const CREDIT_CARD_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => CreditCardValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[creditCard][formControlName],[creditCard][formControl],[creditCard][ngModel]',
14 | providers: [CREDIT_CARD_VALIDATOR]
15 | })
16 | export class CreditCardValidator implements Validator {
17 | validate(c: AbstractControl): {[key: string]: any} {
18 | return creditCard(c);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "noEmitHelpers": false,
10 | "declaration": true,
11 | "rootDir": "src",
12 | "outDir": "dist",
13 | "lib": [
14 | "es6",
15 | "dom"
16 | ],
17 | "types": [
18 | "jasmine",
19 | "node"
20 | ]
21 | },
22 | "exclude": [
23 | "node_modules",
24 | "example",
25 | "src/**/*.spec.ts",
26 | "aot"
27 | ],
28 | "angularCompilerOptions": {
29 | "genDir": "aot",
30 | "skipMetadataEmit" : false
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/max-date/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent, isDate } from '../util/lang';
4 |
5 | export const maxDate = (maxDate: any): ValidatorFn => {
6 | if (!isDate(maxDate) && !(maxDate instanceof Function)) {
7 | throw Error('maxDate value must be or return a formatted date');
8 | }
9 |
10 | return (control: AbstractControl): {[key: string]: any} => {
11 | if (isPresent(Validators.required(control))) return null;
12 |
13 | let d: Date = new Date(control.value);
14 |
15 | if (!isDate(d)) return {maxDate: true};
16 | if (maxDate instanceof Function) maxDate = maxDate();
17 |
18 | return d <= new Date(maxDate) ? null : {maxDate: true};
19 | };
20 | };
21 |
--------------------------------------------------------------------------------
/src/credit-card/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { creditCard } from './';
4 |
5 | describe('CreditCard', () => {
6 | const error = {creditCard: true};
7 |
8 | it('"378282246310005" should be creditCard', () => {
9 | let control = new FormControl('378282246310005');
10 | expect(creditCard(control)).toBeNull();
11 | });
12 |
13 | it('"37828224631000" should not be creditCard', () => {
14 | let control = new FormControl('37828224631000');
15 | expect(creditCard(control)).toEqual(error);
16 | });
17 |
18 | it('"3782822463100056" should not be creditCard', () => {
19 | let control = new FormControl('3782822463100056');
20 | expect(creditCard(control)).toEqual(error);
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/src/min-date/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent, isDate } from '../util/lang';
4 |
5 | export const minDate = (minDate: any): ValidatorFn => {
6 |
7 | if (!isDate(minDate) && !(minDate instanceof Function)) {
8 | throw Error('minDate value must be or return a formatted date');
9 | }
10 |
11 | return (control: AbstractControl): {[key: string]: any} => {
12 | if (isPresent(Validators.required(control))) return null;
13 |
14 | let d: Date = new Date(control.value);
15 |
16 | if (!isDate(d)) return {minDate: true};
17 | if (minDate instanceof Function) minDate = minDate();
18 |
19 | return d >= new Date(minDate) ? null : {minDate: true};
20 | };
21 | };
22 |
--------------------------------------------------------------------------------
/src/digits/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { digits } from './';
4 |
5 | describe('Digits', () => {
6 | const error = {digits: true};
7 |
8 | it('"234" should be digits', () => {
9 | let control = new FormControl('234');
10 | expect(digits(control)).toBeNull();
11 | });
12 |
13 | it('234 should be digits', () => {
14 | let control = new FormControl(234);
15 | expect(digits(control)).toBeNull();
16 | });
17 |
18 | it('"abc" should not be digits', () => {
19 | let control = new FormControl('abc');
20 | expect(digits(control)).toEqual(error);
21 | });
22 |
23 | it('"123a" should not be digits', () => {
24 | let control = new FormControl('123a');
25 | expect(digits(control)).toEqual(error);
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/example/src/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Validators, FormControl, FormGroup } from '@angular/forms';
3 |
4 | import { CustomValidators } from '../../src';
5 |
6 | @Component({
7 | selector: 'app',
8 | template: require('./app.html'),
9 | styles: [require('./app.less')]
10 | })
11 | export class AppComponent implements OnInit {
12 | form: FormGroup;
13 | num: number = 5;
14 |
15 | ngOnInit() {
16 | let password = new FormControl('', Validators.required);
17 | let certainPassword = new FormControl('', CustomValidators.notEqualTo(password));
18 |
19 | this.form = new FormGroup({
20 | password: password,
21 | certainPassword: certainPassword
22 | });
23 | }
24 |
25 | onSubmit(form) {
26 | console.log(form);
27 | }
28 | }
--------------------------------------------------------------------------------
/karma-test-shim.js:
--------------------------------------------------------------------------------
1 | Error.stackTraceLimit = Infinity;
2 |
3 | require('core-js/es6');
4 | require('reflect-metadata');
5 | require('rxjs');
6 | require('zone.js/dist/zone');
7 | require('zone.js/dist/long-stack-trace-zone');
8 | require('zone.js/dist/async-test');
9 | require('zone.js/dist/fake-async-test');
10 | require('zone.js/dist/sync-test');
11 | require('zone.js/dist/proxy');
12 | require('zone.js/dist/jasmine-patch');
13 |
14 | var appContext = require.context('./src', true, /\.spec\.ts/);
15 |
16 | appContext.keys().forEach(appContext);
17 |
18 | var testing = require('@angular/core/testing');
19 | var browser = require('@angular/platform-browser-dynamic/testing');
20 |
21 | testing.getTestBed().initTestEnvironment(
22 | browser.BrowserDynamicTestingModule,
23 | browser.platformBrowserDynamicTesting()
24 | );
25 |
--------------------------------------------------------------------------------
/src/date/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { date } from './';
4 |
5 | describe('Date', () => {
6 | const error = {date: true};
7 |
8 | it('"2013-11-12" should be date', () => {
9 | let control = new FormControl('2013-11-12');
10 | expect(date(control)).toBeNull();
11 | });
12 |
13 | it('"new Date()" should be date', () => {
14 | let control = new FormControl(new Date());
15 | expect(date(control)).toBeNull();
16 | });
17 |
18 | it('"2013-13-12" should not be date', () => {
19 | let control = new FormControl('2013-13-12');
20 | expect(date(control)).toEqual(error);
21 | });
22 |
23 | it('"20131212" should not be date', () => {
24 | let control = new FormControl('20131212');
25 | expect(date(control)).toEqual(error);
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/url/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl, ValidatorFn } from '@angular/forms';
2 |
3 | import { url } from './';
4 |
5 | describe('Url', () => {
6 | let control: FormControl;
7 | let validator: ValidatorFn;
8 |
9 | beforeEach(() => {
10 | validator = url;
11 | });
12 |
13 | it('"http://www.test.com" should equal to "null"', () => {
14 | control = new FormControl('http://www.test.com');
15 | expect(validator(control)).toBeNull()
16 | });
17 |
18 | it('"https://www.test.com" should equal to "null"', () => {
19 | control = new FormControl('https://www.test.com');
20 | expect(validator(control)).toBeNull()
21 | });
22 |
23 | it('"23a" should equal to "{url: true}"', () => {
24 | control = new FormControl('23a');
25 | expect(validator(control)).toEqual({url: true});
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/number/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { number } from './';
4 |
5 | describe('Number', () => {
6 | let control: FormControl;
7 |
8 | it('"23" should equal to "null"', () => {
9 | control = new FormControl('23');
10 | expect(number(control)).toBeNull()
11 | });
12 |
13 | it('"23.3" should equal to "null"', () => {
14 | control = new FormControl('23.3');
15 | expect(number(control)).toBeNull()
16 | });
17 |
18 | it('"23a" should equal to "{number: true}"', () => {
19 | control = new FormControl('23a');
20 | expect(number(control)).toEqual({number: true});
21 | });
22 |
23 | it('"23." should equal to "{number: true}"', () => {
24 | control = new FormControl('23.');
25 | expect(number(control)).toEqual({number: true});
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/url/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const url: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 | return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(v) ? null : {'url': true};
10 | };
11 |
--------------------------------------------------------------------------------
/src/equal-to/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { equalTo } from './';
5 |
6 | const EQUAL_TO_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => EqualToValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[equalTo][formControlName],[equalTo][formControl],[equalTo][ngModel]',
14 | providers: [EQUAL_TO_VALIDATOR]
15 | })
16 | export class EqualToValidator implements Validator, OnInit {
17 | @Input() equalTo: FormControl;
18 |
19 | private validator: ValidatorFn;
20 |
21 | ngOnInit() {
22 | this.validator = equalTo(this.equalTo);
23 | }
24 |
25 | validate(c: AbstractControl): {[key: string]: any} {
26 | return this.validator(c);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/uuid/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | const uuids = {
6 | '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
7 | '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
8 | '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
9 | 'all': /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
10 | };
11 |
12 | export const uuid = (version?: string): ValidatorFn => {
13 | return (control: AbstractControl): {[key: string]: any} => {
14 | if (isPresent(Validators.required(control))) return null;
15 |
16 | let v: string = control.value;
17 | let pattern = uuids[version] || uuids.all;
18 |
19 | return (new RegExp(pattern)).test(v) ? null : {uuid: true};
20 | };
21 | };
22 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # v3.4.0
2 |
3 | add lt and gt validator
4 |
5 | # v3.5.0
6 |
7 | re-trigger validate when validate-property change
8 |
9 | # v3.6.0
10 |
11 | Improved US Phone Number formats
12 | detail see https://github.com/yuyang041060120/ng2-validation/pull/43/
13 |
14 | # v3.7.0
15 |
16 | code split
17 |
18 | # v3.7.1
19 |
20 | add umd file
21 |
22 | # v3.8.0
23 |
24 | [#33](https://github.com/yuyang041060120/ng2-validation/issues/33)
25 |
26 | # v3.9.0
27 |
28 | upgrade to angular 4
29 |
30 | # v3.9.1
31 |
32 | upgrade dev dependencies and webpack@2.x.x
33 |
34 | # v4.0.0
35 |
36 | - support libphonenumber [#23](https://github.com/yuyang041060120/ng2-validation/issues/23)
37 | - add lte and gte validator [#69](https://github.com/yuyang041060120/ng2-validation/issues/69)
38 |
39 | # v4.2.0
40 |
41 | - add error details in range validator [#82](https://github.com/yuyang041060120/ng2-validation/issues/82)
--------------------------------------------------------------------------------
/src/not-equal-to/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { notEqualTo } from './';
5 |
6 | const NOT_EQUAL_TO_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => NotEqualToValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[notEqualTo][formControlName],[notEqualTo][formControl],[notEqualTo][ngModel]',
14 | providers: [NOT_EQUAL_TO_VALIDATOR]
15 | })
16 | export class NotEqualToValidator implements Validator, OnInit {
17 | @Input() notEqualTo: FormControl;
18 |
19 | private validator: ValidatorFn;
20 |
21 | ngOnInit() {
22 | this.validator = notEqualTo(this.notEqualTo);
23 | }
24 |
25 | validate(c: AbstractControl): {[key: string]: any} {
26 | return this.validator(c);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 |
3 | module.exports = {
4 | context: __dirname,
5 | entry: {
6 | main: './example/main',
7 | vendor: './example/vendor',
8 | polyfills: './example/polyfills'
9 | },
10 | devtool: 'source-map',
11 | output: {
12 | path: __dirname + '/example/dist',
13 | filename: 'bundle.js',
14 | publicPath: '/ng2-validation/example/dist/'
15 | },
16 | resolve: {
17 | extensions: ['.js', '.ts']
18 | },
19 | module: {
20 | rules: [
21 | {
22 | test: /\.ts$/,
23 | exclude: /\.d\.ts$/,
24 | use: 'ts-loader'
25 | },
26 | {
27 | test: /\.html$/,
28 | use: 'raw-loader'
29 | },
30 | {
31 | test: /\.less$/,
32 | loaders: [ 'raw-loader', 'less-loader' ]
33 | }
34 | ]
35 | },
36 | plugins: [
37 | new webpack.optimize.CommonsChunkPlugin({
38 | names: [ 'vendor', 'polyfills' ],
39 | filename: '[name].js'
40 | })
41 | ]
42 | };
--------------------------------------------------------------------------------
/src/range-length/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl, ValidatorFn } from '@angular/forms';
2 |
3 | import { rangeLength } from './';
4 |
5 | describe('RangeLength [4,9],', () => {
6 | let control: FormControl;
7 | let validator: ValidatorFn;
8 |
9 | beforeEach(() => {
10 | validator = rangeLength([4, 9]);
11 | });
12 |
13 | it('"abc" should equal to "{rangeLength: true}"', () => {
14 | control = new FormControl('abc');
15 | expect(validator(control)).toEqual({rangeLength: true});
16 | });
17 |
18 | it('"abcd" should equal to "null"', () => {
19 | control = new FormControl('abcd');
20 | expect(validator(control)).toBeNull();
21 | });
22 |
23 | it('"abcdefghi" should equal to "null"', () => {
24 | control = new FormControl('abcdefghi');
25 | expect(validator(control)).toBeNull();
26 | });
27 |
28 | it('"abcdefghij" should equal to "{rangeLength: true}"', () => {
29 | control = new FormControl('abcdefghij');
30 | expect(validator(control)).toEqual({rangeLength: true});
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/src/range/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl, ValidatorFn } from '@angular/forms';
2 |
3 | import { range } from './';
4 |
5 | describe('Range [4, 9]', () => {
6 | let control: FormControl;
7 | let validator: ValidatorFn;
8 |
9 | beforeEach(() => {
10 | validator = range([4, 9]);
11 | });
12 |
13 | it('"3" should equal to "{actualValue: 3, requiredValue: [4, 9], range: true}"', () => {
14 | control = new FormControl(3);
15 | expect(validator(control)).toEqual({actualValue: 3, requiredValue: [4, 9], range: true});
16 | });
17 |
18 | it('"4" should equal to "null"', () => {
19 | control = new FormControl(4);
20 | expect(validator(control)).toBeNull();
21 | });
22 |
23 | it('"9" should equal to "null"', () => {
24 | control = new FormControl(9);
25 | expect(validator(control)).toBeNull();
26 | });
27 |
28 | it('"10" should equal to "{actualValue: 3, requiredValue: [4, 9], range: true}"', () => {
29 | control = new FormControl(10);
30 | expect(validator(control)).toEqual({actualValue: 10, requiredValue: [4, 9], range: true});
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 | var _config = {
3 | basePath: './',
4 |
5 | frameworks: [ 'jasmine' ],
6 |
7 | files: [
8 | { pattern: './karma-test-shim.js', watched: false }
9 | ],
10 |
11 | preprocessors: {
12 | './karma-test-shim.js': [ 'webpack', 'sourcemap' ]
13 | },
14 |
15 | webpack: {
16 | resolve: {
17 | extensions: [' ', '.js', '.ts']
18 | },
19 | module: {
20 | loaders: [
21 | {
22 | test: /\.ts$/,
23 | loader: 'ts-loader'
24 | },
25 | {
26 | test: /\.html$/,
27 | loader: 'raw-loader'
28 | }
29 | ]
30 | }
31 | },
32 |
33 | webpackMiddleware: {
34 | stats: 'errors-only'
35 | },
36 |
37 | webpackServer: {
38 | noInfo: true
39 | },
40 |
41 | reporters: [ 'progress' ],
42 | port: 9876,
43 | colors: true,
44 | logLevel: config.LOG_INFO,
45 | autoWatch: false,
46 | browsers: [ 'PhantomJS' ],
47 | singleRun: true
48 | };
49 |
50 | config.set(_config);
51 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 YangYang Yu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/max/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { max } from './';
5 |
6 | const MAX_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => MaxValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[max][formControlName],[max][formControl],[max][ngModel]',
14 | providers: [MAX_VALIDATOR]
15 | })
16 | export class MaxValidator implements Validator, OnInit, OnChanges {
17 | @Input() max: number;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = max(this.max);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'max') {
29 | this.validator = max(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/min/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { min } from './';
5 |
6 | const MIN_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => MinValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[min][formControlName],[min][formControl],[min][ngModel]',
14 | providers: [MIN_VALIDATOR]
15 | })
16 | export class MinValidator implements Validator, OnInit, OnChanges {
17 | @Input() min: number;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = min(this.min);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'min') {
29 | this.validator = min(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/uuid/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { uuid } from './';
5 |
6 | const UUID_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => UUIDValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[uuid][formControlName],[uuid][formControl],[uuid][ngModel]',
14 | providers: [UUID_VALIDATOR]
15 | })
16 | export class UUIDValidator implements Validator, OnInit, OnChanges {
17 | @Input() uuid;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = uuid(this.uuid);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'uuid') {
29 | this.validator = uuid(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/less-than/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { lt } from './';
5 |
6 | const LESS_THAN_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => LessThanValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[lt][formControlName],[lt][formControl],[lt][ngModel]',
14 | providers: [LESS_THAN_VALIDATOR]
15 | })
16 | export class LessThanValidator implements Validator, OnInit, OnChanges {
17 | @Input() lt: number;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = lt(this.lt);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'lt') {
29 | this.validator = lt(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/equal/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, SimpleChanges, OnChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { equal } from './index';
5 |
6 | const EQUAL_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => EqualValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[equal][formControlName],[equal][formControl],[equal][ngModel]',
14 | providers: [EQUAL_VALIDATOR]
15 | })
16 | export class EqualValidator implements Validator, OnInit, OnChanges {
17 | @Input() equal: any;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = equal(this.equal);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'equal') {
29 | this.validator = equal(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/phone/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { phone } from './';
5 |
6 | const PHONE_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => PhoneValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[phone][formControlName],[phone][formControl],[phone][ngModel]',
14 | providers: [PHONE_VALIDATOR]
15 | })
16 | export class PhoneValidator implements Validator, OnInit, OnChanges {
17 | @Input() phone: string;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = phone(this.phone);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'phone') {
29 | this.validator = phone(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/range/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { range } from './';
5 |
6 | const RANGE_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => RangeValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[range][formControlName],[range][formControl],[range][ngModel]',
14 | providers: [RANGE_VALIDATOR]
15 | })
16 | export class RangeValidator implements Validator, OnInit, OnChanges {
17 | @Input() range: [number];
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = range(this.range);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'range') {
29 | this.validator = range(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/greater-than/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { gt } from './';
5 |
6 | const GREATER_THAN_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => GreaterThanValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[gt][formControlName],[gt][formControl],[gt][ngModel]',
14 | providers: [GREATER_THAN_VALIDATOR]
15 | })
16 | export class GreaterThanValidator implements Validator, OnInit, OnChanges {
17 | @Input() gt: number;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = gt(this.gt);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'gt') {
29 | this.validator = gt(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/max-date/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { maxDate } from './';
5 |
6 | const MAX_DATE_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => MaxDateValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[maxDate][formControlName],[maxDate][formControl],[maxDate][ngModel]',
14 | providers: [MAX_DATE_VALIDATOR]
15 | })
16 | export class MaxDateValidator implements Validator, OnInit, OnChanges {
17 | @Input() maxDate;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = maxDate(this.maxDate);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'maxDate') {
29 | this.validator = maxDate(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/min-date/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { minDate } from './';
5 |
6 | const MIN_DATE_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => MinDateValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[minDate][formControlName],[minDate][formControl],[minDate][ngModel]',
14 | providers: [MIN_DATE_VALIDATOR]
15 | })
16 | export class MinDateValidator implements Validator, OnInit, OnChanges {
17 | @Input() minDate;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = minDate(this.minDate);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'minDate') {
29 | this.validator = minDate(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/less-than-equal/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { lte } from './';
5 |
6 | const LESS_THAN_EQUAL_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => LessThanEqualValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[lte][formControlName],[lte][formControl],[lte][ngModel]',
14 | providers: [LESS_THAN_EQUAL_VALIDATOR]
15 | })
16 | export class LessThanEqualValidator implements Validator, OnInit, OnChanges {
17 | @Input() lte: number;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = lte(this.lte);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'lte') {
29 | this.validator = lte(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/greater-than-equal/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { gte } from './';
5 |
6 | const GREATER_THAN_EQUAL_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => GreaterThanEqualValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[gte][formControlName],[gte][formControl],[gte][ngModel]',
14 | providers: [GREATER_THAN_EQUAL_VALIDATOR]
15 | })
16 | export class GreaterThanEqualValidator implements Validator, OnInit, OnChanges {
17 | @Input() gte: number;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = gte(this.gte);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'gte') {
29 | this.validator = gte(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/not-equal/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, SimpleChanges, OnChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { notEqual } from './index';
5 |
6 | const NOT_EQUAL_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => NotEqualValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[notEqual][formControlName],[notEqual][formControl],[notEqual][ngModel]',
14 | providers: [NOT_EQUAL_VALIDATOR]
15 | })
16 | export class NotEqualValidator implements Validator, OnInit, OnChanges {
17 | @Input() notEqual: any;
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = notEqual(this.notEqual);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'notEqual') {
29 | this.validator = notEqual(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/credit-card/validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
2 |
3 | import { isPresent } from '../util/lang';
4 |
5 | export const creditCard: ValidatorFn = (control: AbstractControl): {[key: string]: boolean} => {
6 | if (isPresent(Validators.required(control))) return null;
7 |
8 | let v: string = control.value;
9 |
10 | let sanitized = v.replace(/[^0-9]+/g, '');
11 |
12 | // problem with chrome
13 | if (!(/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/.test(sanitized))) {
14 | return {creditCard: true};
15 | }
16 |
17 | let sum = 0;
18 | let digit;
19 | let tmpNum;
20 | let shouldDouble;
21 | for (let i = sanitized.length - 1; i >= 0; i--) {
22 | digit = sanitized.substring(i, (i + 1));
23 | tmpNum = parseInt(digit, 10);
24 | if (shouldDouble) {
25 | tmpNum *= 2;
26 | if (tmpNum >= 10) {
27 | sum += ((tmpNum % 10) + 1);
28 | } else {
29 | sum += tmpNum;
30 | }
31 | } else {
32 | sum += tmpNum;
33 | }
34 | shouldDouble = !shouldDouble;
35 | }
36 |
37 | if (Boolean((sum % 10) === 0 ? sanitized : false)) {
38 | return null;
39 | }
40 |
41 | return {creditCard: true};
42 | };
43 |
--------------------------------------------------------------------------------
/src/range-length/directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, forwardRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
2 | import { NG_VALIDATORS, Validator, ValidatorFn, AbstractControl } from '@angular/forms';
3 |
4 | import { rangeLength } from './';
5 |
6 | const RANGE_LENGTH_VALIDATOR: any = {
7 | provide: NG_VALIDATORS,
8 | useExisting: forwardRef(() => RangeLengthValidator),
9 | multi: true
10 | };
11 |
12 | @Directive({
13 | selector: '[rangeLength][formControlName],[rangeLength][formControl],[rangeLength][ngModel]',
14 | providers: [RANGE_LENGTH_VALIDATOR]
15 | })
16 | export class RangeLengthValidator implements Validator, OnInit, OnChanges {
17 | @Input() rangeLength: [number];
18 |
19 | private validator: ValidatorFn;
20 | private onChange: () => void;
21 |
22 | ngOnInit() {
23 | this.validator = rangeLength(this.rangeLength);
24 | }
25 |
26 | ngOnChanges(changes: SimpleChanges) {
27 | for (let key in changes) {
28 | if (key === 'rangeLength') {
29 | this.validator = rangeLength(changes[key].currentValue);
30 | if (this.onChange) this.onChange();
31 | }
32 | }
33 | }
34 |
35 | validate(c: AbstractControl): {[key: string]: any} {
36 | return this.validator(c);
37 | }
38 |
39 | registerOnValidatorChange(fn: () => void): void {
40 | this.onChange = fn;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/not-equal-to/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { notEqualTo } from './';
4 |
5 | describe('NotEqualTo', () => {
6 | let notEqualControl: FormControl;
7 | let control: FormControl;
8 | const error = {notEqualTo: true};
9 |
10 | beforeEach(() => {
11 | notEqualControl = new FormControl();
12 | control = new FormControl();
13 | });
14 |
15 | it('all control is empty should valid', () => {
16 | expect(notEqualTo(notEqualControl)(control)).toEqual(error);
17 | });
18 |
19 | it('control.value = "xxx" and notEqualControl.value is empty should valid', () => {
20 | control.setValue('xxx');
21 | expect(notEqualTo(notEqualControl)(control)).toBeNull();
22 | });
23 |
24 | it('control.value = "xxx" and notEqualControl.value = "yyy" should valid', () => {
25 | control.setValue('xxx');
26 | notEqualControl.setValue('yyy');
27 | expect(notEqualTo(notEqualControl)(control)).toBeNull();
28 | });
29 |
30 | it('control.value = "xxx" and notEqualControl.value = "xxx" should equal to "{notEqualTo: true}"', () => {
31 | control.setValue('xxx');
32 | notEqualControl.setValue('xxx');
33 | expect(notEqualTo(notEqualControl)(control)).toEqual(error);
34 | });
35 |
36 | it('control.value is empty and notEqualControl.value = "yyy" should valid', () => {
37 | control.setValue('');
38 | notEqualControl.setValue('yyy');
39 | expect(notEqualTo(notEqualControl)(control)).toBeNull();
40 | });
41 |
42 | });
43 |
--------------------------------------------------------------------------------
/src/min-date/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { minDate } from './';
4 |
5 | describe('MinDate', () => {
6 | let control: FormControl;
7 |
8 | it('"" should equal to "null"', () => {
9 | control = new FormControl('');
10 | expect(minDate('2016-09-09')(control)).toBeNull();
11 | });
12 |
13 | it('"2016-09-08" should equal to "{minDate: true}"', () => {
14 | control = new FormControl('2016-09-08');
15 | expect(minDate('2016-09-09')(control)).toEqual({minDate: true});
16 | });
17 |
18 | it('"2016-09-10" should equal to "null"', () => {
19 | control = new FormControl('2016-09-10');
20 | expect(minDate('2016-09-09')(control)).toBeNull();
21 | });
22 |
23 | it('Date("2016-09-08)" should equal to "{minDate: true}"', () => {
24 | control = new FormControl('2016-09-08');
25 | expect(minDate('2016-09-09')(control)).toEqual({minDate: true});
26 | });
27 |
28 | it('"Date(2016-09-10)" should equal to "null"', () => {
29 | control = new FormControl('2016-09-10');
30 | expect(minDate('2016-09-09')(control)).toBeNull();
31 | });
32 |
33 | it('() => Date("2016-09-08)" should equal to "{minDate: true}"', () => {
34 | control = new FormControl('2016-09-08');
35 | expect(minDate('2016-09-09')(control)).toEqual({minDate: true});
36 | });
37 |
38 | it('"() => Date(2016-09-10)" should equal to "null"', () => {
39 | control = new FormControl('2016-09-10');
40 | expect(minDate('2016-09-09')(control)).toBeNull();
41 | });
42 | });
43 |
44 |
--------------------------------------------------------------------------------
/src/max-date/validator.spec.ts:
--------------------------------------------------------------------------------
1 | import { FormControl } from '@angular/forms';
2 |
3 | import { maxDate } from './';
4 |
5 | describe('MaxDate', () => {
6 | let control: FormControl;
7 |
8 | it('"" should equal to "null"', () => {
9 | control = new FormControl('');
10 | expect(maxDate('2016-09-09')(control)).toBeNull();
11 | });
12 |
13 | it('"2016-09-10" should equal to "{maxDate: true}"', () => {
14 | control = new FormControl('2016-09-10');
15 | expect(maxDate('2016-09-09')(control)).toEqual({maxDate: true});
16 | });
17 |
18 | it('"2016-09-08" should equal to "null"', () => {
19 | control = new FormControl('2016-09-08');
20 | expect(maxDate('2016-09-09')(control)).toBeNull();
21 | });
22 |
23 | it('"Date(2016-09-10)" should equal to "{maxDate: true}"', () => {
24 | control = new FormControl('2016-09-10');
25 | expect(maxDate(new Date('2016-09-09'))(control)).toEqual({maxDate: true});
26 | });
27 |
28 | it('"Date(2016-09-08)" should equal to "null"', () => {
29 | control = new FormControl('2016-09-08');
30 | expect(maxDate(new Date('2016-09-09'))(control)).toBeNull();
31 | });
32 |
33 | it('"Date(2016-09-10)" should equal to "{maxDate: true}"', () => {
34 | control = new FormControl('2016-09-10');
35 | expect(maxDate(() => new Date('2016-09-09'))(control)).toEqual({maxDate: true});
36 | });
37 |
38 | it('"Date(2016-09-08)" should equal to "null"', () => {
39 | control = new FormControl('2016-09-08');
40 | expect(maxDate(() => new Date('2016-09-09'))(control)).toBeNull();
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng2-validation",
3 | "version": "4.2.0",
4 | "description": "angular2 validation",
5 | "main": "dist/index.js",
6 | "typings": "dist/index.d.ts",
7 | "scripts": {
8 | "test": "karma start ./karma.conf.js",
9 | "dev": "webpack-dev-server --port 4001 --watch",
10 | "example": "webpack --optimize-minimize",
11 | "ngc": "ngc",
12 | "prerollup": "rimraf bundles",
13 | "rollup": "rollup -c",
14 | "prebuild": "rimraf dist",
15 | "build": "npm run ngc && npm run rollup",
16 | "prepublish": "npm run build"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/yuyang041060120/angular2-validate.git"
21 | },
22 | "keywords": [
23 | "angular2",
24 | "validate",
25 | "validation"
26 | ],
27 | "author": "yuyang041060120 ",
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/yuyang041060120/angular2-validate/issues"
31 | },
32 | "homepage": "https://github.com/yuyang041060120/angular2-validate#readme",
33 | "devDependencies": {
34 | "@angular/common": "4.0.0",
35 | "@angular/compiler": "4.0.0",
36 | "@angular/compiler-cli": "4.0.0",
37 | "@angular/core": "4.0.0",
38 | "@angular/forms": "4.0.0",
39 | "@angular/http": "4.0.0",
40 | "@angular/platform-browser": "4.0.0",
41 | "@angular/platform-browser-dynamic": "4.0.0",
42 | "@types/jasmine": "^2.2.29",
43 | "@types/node": "^7.0.12",
44 | "bootstrap": "^3.3.7",
45 | "core-js": "^2.4.1",
46 | "jasmine-core": "^2.4.1",
47 | "jasmine-data-provider": "^2.2.0",
48 | "karma": "^1.1.1",
49 | "karma-jasmine": "^1.0.2",
50 | "karma-phantomjs-launcher": "^1.0.1",
51 | "karma-sourcemap-loader": "^0.3.7",
52 | "karma-webpack": "^2.0.3",
53 | "less": "^2.7.2",
54 | "less-loader": "^4.0.2",
55 | "phantomjs-prebuilt": "^2.1.7",
56 | "raw-loader": "^0.5.1",
57 | "reflect-metadata": "^0.1.3",
58 | "rimraf": "^2.5.4",
59 | "rollup": "^0.41.4",
60 | "rollup-plugin-typescript": "^0.8.1",
61 | "rxjs": "^5.2.0",
62 | "ts-loader": "^2.0.3",
63 | "typescript": "^2.2.2",
64 | "webpack": "^2.3.2",
65 | "webpack-dev-server": "^2.4.2",
66 | "zone.js": "^0.8.4"
67 | },
68 | "dependencies": {
69 | "libphonenumber-js": "^0.4.5"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 |
3 | import { base64, Base64Validator } from './base64';
4 | import { creditCard, CreditCardValidator } from './credit-card';
5 | import { date, DateValidator } from './date';
6 | import { dateISO, DateISOValidator } from './date-ios';
7 | import { digits, DigitsValidator } from './digits';
8 | import { email, EmailValidator } from './email';
9 | import { equal, EqualValidator } from './equal';
10 | import { equalTo, EqualToValidator } from './equal-to';
11 | import { gt, GreaterThanValidator } from './greater-than';
12 | import { gte, GreaterThanEqualValidator } from './greater-than-equal';
13 | import { json, JSONValidator } from './json';
14 | import { lt, LessThanValidator } from './less-than';
15 | import { lte, LessThanEqualValidator } from './less-than-equal';
16 | import { max, MaxValidator } from './max';
17 | import { maxDate, MaxDateValidator } from './max-date';
18 | import { min, MinValidator } from './min';
19 | import { minDate, MinDateValidator } from './min-date';
20 | import { notEqual, NotEqualValidator } from './not-equal';
21 | import { notEqualTo, NotEqualToValidator } from './not-equal-to';
22 | import { number, NumberValidator } from './number';
23 | import { phone, PhoneValidator } from './phone';
24 | import { range, RangeValidator } from './range';
25 | import { rangeLength, RangeLengthValidator } from './range-length';
26 | import { url, UrlValidator } from './url';
27 | import { uuid, UUIDValidator } from './uuid';
28 |
29 | export const CustomValidators: any = {
30 | base64,
31 | creditCard,
32 | date,
33 | dateISO,
34 | digits,
35 | email,
36 | equal,
37 | equalTo,
38 | gt,
39 | gte,
40 | json,
41 | lt,
42 | lte,
43 | max,
44 | maxDate,
45 | min,
46 | minDate,
47 | notEqual,
48 | notEqualTo,
49 | number,
50 | phone,
51 | range,
52 | rangeLength,
53 | url,
54 | uuid
55 | };
56 |
57 | const CUSTOM_FORM_DIRECTIVES = [
58 | Base64Validator,
59 | CreditCardValidator,
60 | DateValidator,
61 | DateISOValidator,
62 | DigitsValidator,
63 | EmailValidator,
64 | EqualValidator,
65 | EqualToValidator,
66 | GreaterThanValidator,
67 | GreaterThanEqualValidator,
68 | JSONValidator,
69 | LessThanValidator,
70 | LessThanEqualValidator,
71 | MaxValidator,
72 | MaxDateValidator,
73 | MinValidator,
74 | MinDateValidator,
75 | NotEqualValidator,
76 | NotEqualToValidator,
77 | NumberValidator,
78 | PhoneValidator,
79 | RangeValidator,
80 | RangeLengthValidator,
81 | UrlValidator,
82 | UUIDValidator
83 | ];
84 |
85 | @NgModule({
86 | declarations: [CUSTOM_FORM_DIRECTIVES],
87 | exports: [CUSTOM_FORM_DIRECTIVES]
88 | })
89 | export class CustomFormsModule {
90 | }
91 |
--------------------------------------------------------------------------------
/example/src/app.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > Deprecated, you can fork and publish yours.
2 |
3 | # Description
4 |
5 | Angular2 custom validation, inspired by jQuery validation.
6 |
7 | # Install
8 |
9 | ```bash
10 | npm install ng2-validation --save
11 | ```
12 | # Systemjs
13 |
14 | ```bash
15 | 'ng2-validation': 'npm:ng2-validation/bundles/ng2-validation.umd.js'
16 | ```
17 |
18 | # Validators
19 |
20 | ## angular2 built-in validators
21 |
22 | - required
23 | - minlength
24 | - maxlength
25 | - pattern
26 |
27 | ## custom validators
28 |
29 | - rangeLength
30 | - min
31 | - gt
32 | - gte
33 | - max
34 | - lt
35 | - lte
36 | - range
37 | - digits
38 | - number
39 | - url
40 | - email
41 | - date
42 | - minDate
43 | - maxDate
44 | - dateISO
45 | - creditCard
46 | - json
47 | - base64
48 | - phone
49 | - uuid
50 | - equal
51 | - notEqual
52 | - equalTo
53 | - notEqualTo
54 |
55 | # Usage
56 |
57 | ## template driven
58 |
59 | import `FormsModule` and `CustomFormsModule` in *app.module.ts*
60 |
61 | ```javascript
62 | import { NgModule } from '@angular/core';
63 | import { BrowserModule } from '@angular/platform-browser';
64 | import { FormsModule } from '@angular/forms';
65 | import { CustomFormsModule } from 'ng2-validation'
66 |
67 | import { AppComponent } from './app.component';
68 |
69 | @NgModule({
70 | imports: [BrowserModule, FormsModule, CustomFormsModule],
71 | declarations: [AppComponent],
72 | bootstrap: [AppComponent]
73 | })
74 | export class AppModule {
75 | }
76 | ```
77 |
78 | ### rangeLength
79 |
80 | ```html
81 |
82 | error message
83 | ```
84 |
85 | ### min
86 |
87 | ```html
88 |
89 | error message
90 | ```
91 |
92 | ### gt
93 |
94 | ```html
95 |
96 | error message
97 | ```
98 |
99 | ### gte
100 |
101 | ```html
102 |
103 | error message
104 | ```
105 |
106 | ### max
107 |
108 | ```html
109 |
110 | error message
111 | ```
112 |
113 | ### lt
114 |
115 | ```html
116 |
117 | error message
118 | ```
119 |
120 | ### lte
121 |
122 | ```html
123 |
124 | error message
125 | ```
126 |
127 | ### range
128 |
129 | ```html
130 |
131 | error message
132 | ```
133 |
134 | ### digits
135 |
136 | ```html
137 |
138 | error message
139 | ```
140 |
141 | ### number
142 |
143 | ```html
144 |
145 | error message
146 | ```
147 |
148 | ### url
149 |
150 | ```html
151 |
152 | error message
153 | ```
154 |
155 | ### email
156 |
157 | ```html
158 |
159 | error message
160 | ```
161 |
162 | ### date
163 |
164 | ```html
165 |
166 | error message
167 | ```
168 |
169 | ### minDate
170 |
171 | ```html
172 |
173 | error message
174 | ```
175 |
176 | ### maxDate
177 |
178 | ```html
179 |
180 | error message
181 | ```
182 |
183 | ### dateISO
184 |
185 | ```html
186 |
187 | error message
188 | ```
189 |
190 | ### creditCard
191 |
192 | ```html
193 |
194 | error message
195 | ```
196 |
197 | ### json
198 |
199 | ```html
200 |
201 | error message
202 | ```
203 |
204 | ### base64
205 |
206 | ```html
207 |
208 | error message
209 | ```
210 |
211 | ### phone
212 |
213 | ```html
214 |
215 | error message
216 | ```
217 |
218 | details see [libphonenumber](https://github.com/halt-hammerzeit/libphonenumber-js)
219 |
220 | ### uuid
221 |
222 | ```html
223 |
224 | error message
225 | ```
226 |
227 | *default*: all
228 |
229 | **support**
230 |
231 | - 3
232 | - 4
233 | - 5
234 | - all
235 |
236 | ### equal
237 |
238 | ```html
239 |
240 | error message
241 | ```
242 |
243 | ### equal
244 |
245 | ```html
246 |
247 | error message
248 | ```
249 |
250 | ### equalTo
251 |
252 | ```html
253 |
254 | required error
255 |
256 | equalTo error
257 | ```
258 |
259 | ### notEqualTo
260 |
261 | ```html
262 |
263 | required error
264 |
265 | equalTo error
266 | ```
267 |
268 | ## model driven
269 |
270 | import `ReactiveFormsModule` in *app.module.ts*
271 |
272 | ```javascript
273 | import { NgModule } from '@angular/core';
274 | import { BrowserModule } from '@angular/platform-browser';
275 | import { ReactiveFormsModule } from '@angular/forms';
276 |
277 | import { AppComponent } from './app.component';
278 |
279 | @NgModule({
280 | imports: [BrowserModule, ReactiveFormsModule],
281 | declarations: [AppComponent],
282 | bootstrap: [AppComponent]
283 | })
284 | export class AppModule {
285 | }
286 | ```
287 |
288 | import `CustomValidators` in *app.component.ts*
289 |
290 | ```javascript
291 | import { Component } from '@angular/core';
292 | import { FormGroup, FormControl } from '@angular/forms';
293 | import { CustomValidators } from 'ng2-validation';
294 |
295 | @Component({
296 | selector: 'app',
297 | template: require('./app.html')
298 | })
299 | export class AppComponent {
300 | form: FormGroup;
301 |
302 | constructor() {
303 | this.form = new FormGroup({
304 | field: new FormControl('', CustomValidators.range([5, 9]))
305 | });
306 | }
307 | }
308 | ```
309 |
310 | ```html
311 |
312 | error message
313 | ```
314 |
315 | ### rangeLength
316 |
317 | ```javascript
318 | new FormControl('', CustomValidators.rangeLength([5, 9]))
319 | ```
320 |
321 | ### min
322 |
323 | ```javascript
324 | new FormControl('', CustomValidators.min(10))
325 | ```
326 |
327 | ### gt
328 |
329 | ```javascript
330 | new FormControl('', CustomValidators.gt(10))
331 | ```
332 |
333 | ### max
334 |
335 | ```javascript
336 | new FormControl('', CustomValidators.max(20))
337 | ```
338 |
339 | ### lt
340 |
341 | ```javascript
342 | new FormControl('', CustomValidators.lt(20))
343 | ```
344 |
345 | ### range
346 |
347 | ```javascript
348 | new FormControl('', CustomValidators.range([10, 20]))
349 | ```
350 |
351 | ### digits
352 |
353 | ```javascript
354 | new FormControl('', CustomValidators.digits)
355 | ```
356 |
357 | ### number
358 |
359 | ```javascript
360 | new FormControl('', CustomValidators.number)
361 | ```
362 |
363 | ### url
364 |
365 | ```javascript
366 | new FormControl('', CustomValidators.url)
367 | ```
368 |
369 | ### email
370 |
371 | ```javascript
372 | new FormControl('', CustomValidators.email)
373 | ```
374 |
375 | ### date
376 |
377 | ```javascript
378 | new FormControl('', CustomValidators.date)
379 | ```
380 |
381 | ### minDate
382 |
383 | ```javascript
384 | new FormControl('', CustomValidators.minDate('2016-09-09'))
385 | ```
386 |
387 | ### maxDate
388 |
389 | ```javascript
390 | new FormControl('', CustomValidators.maxDate('2016-09-09'))
391 | ```
392 |
393 | ### dateISO
394 |
395 | ```javascript
396 | new FormControl('', CustomValidators.dateISO)
397 | ```
398 |
399 | ### creditCard
400 |
401 | ```javascript
402 | new FormControl('', CustomValidators.creditCard)
403 | ```
404 |
405 | ### json
406 |
407 | ```javascript
408 | new FormControl('', CustomValidators.json)
409 | ```
410 |
411 | ### base64
412 |
413 | ```javascript
414 | new FormControl('', CustomValidators.base64)
415 | ```
416 |
417 | ### phone
418 |
419 | ```javascript
420 | new FormControl('', CustomValidators.phone('zh-CN'))
421 | ```
422 |
423 | ### uuid
424 |
425 | ```javascript
426 | new FormControl('', CustomValidators.uuid('3'))
427 | ```
428 |
429 | ### equal
430 |
431 | ```javascript
432 | new FormControl('', CustomValidators.equal('xxx'))
433 | ```
434 |
435 | ### notEqual
436 |
437 | ```javascript
438 | new FormControl('', CustomValidators.notEqual('xxx'))
439 | ```
440 |
441 | ### equalTo
442 |
443 | ```javascript
444 | let password = new FormControl('', Validators.required);
445 | let certainPassword = new FormControl('', CustomValidators.equalTo(password));
446 |
447 | this.form = new FormGroup({
448 | password: password,
449 | certainPassword: certainPassword
450 | });
451 | ```
452 |
453 | ```html
454 |
460 | ```
461 |
462 | ### notEqualTo
463 |
464 | ```javascript
465 | let password = new FormControl('', Validators.required);
466 | let certainPassword = new FormControl('', CustomValidators.notEqualTo(password));
467 |
468 | this.form = new FormGroup({
469 | password: password,
470 | certainPassword: certainPassword
471 | });
472 | ```
473 |
474 | ```html
475 |
481 | ```
482 |
483 | # License
484 |
485 | MIT
486 |
--------------------------------------------------------------------------------
/example/dist/polyfills.js:
--------------------------------------------------------------------------------
1 | !function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(r,i,a){for(var u,c,s,l=0,f=[];l1)for(var n=1;n0)return!0;var o=ee.get(t);return o.delete(n),o.size>0||(ee.delete(t),!0)}function p(e,t){for(var n=e.length-1;n>=0;--n){var r=e[n],o=r(t);if(!E(o)&&!S(o)){if(!L(o))throw new TypeError;t=o}}return t}function d(e,t,n,r){for(var o=e.length-1;o>=0;--o){var i=e[o],a=i(t,n,r);if(!E(a)&&!S(a)){if(!j(a))throw new TypeError;r=a}}return r}function v(e,t,n){var r=ee.get(e);if(E(r)){if(!n)return;r=new Q,ee.set(e,r)}var o=r.get(t);if(E(o)){if(!n)return;o=new Q,r.set(t,o)}return o}function y(e,t,n){if(g(e,t,n))return!0;var r=B(t);return!S(r)&&y(e,r,n)}function g(e,t,n){var r=v(t,n,!1);return!E(r)&&D(r.has(e))}function k(e,t,n){if(g(e,t,n))return _(e,t,n);var r=B(t);return S(r)?void 0:k(e,r,n)}function _(e,t,n){var r=v(t,n,!1);if(!E(r))return r.get(e)}function w(e,t,n,r){v(n,r,!0).set(e,t)}function m(e,t){var n=T(e,t),r=B(e);if(null===r)return n;var o=m(r,t);if(o.length<=0)return n;if(n.length<=0)return o;for(var i=new Y,a=[],u=0,c=n;u=0&&e=this._keys.length?(this._index=-1,this._keys=o,this._values=o):this._index++,{value:t,done:!1}}return{value:void 0,done:!0}},e.prototype.throw=function(e){throw this._index>=0&&(this._index=-1,this._keys=o,this._values=o),e},e.prototype.return=function(e){return this._index>=0&&(this._index=-1,this._keys=o,this._values=o),{value:e,done:!0}},e}();return function(){function o(){this._keys=[],this._values=[],this._cacheKey=r,this._cacheIndex=-2}return Object.defineProperty(o.prototype,"size",{get:function(){return this._keys.length},enumerable:!0,configurable:!0}),o.prototype.has=function(e){return this._find(e,!1)>=0},o.prototype.get=function(e){var t=this._find(e,!1);return t>=0?this._values[t]:void 0},o.prototype.set=function(e,t){var n=this._find(e,!0);return this._values[n]=t,this},o.prototype.delete=function(e){var t=this._find(e,!1);if(t>=0){for(var n=this._keys.length,o=t+1;o=0;n--)"function"==typeof e[n]&&(e[n]=Zone.current.wrap(e[n],t+"_"+n));return e}function r(e,t){var n=Object.getOwnPropertyDescriptor(e,t)||{enumerable:!0,configurable:!0},r=Object.getOwnPropertyDescriptor(e,"original"+t);!r&&n.get&&Object.defineProperty(e,"original"+t,{enumerable:!1,configurable:!0,get:n.get}),delete n.writable,delete n.value;var o=t.substr(2),i=b("_"+t);n.set=function(e){if(this[i]&&this.removeEventListener(o,this[i]),"function"==typeof e){var t=function(t){var n;return n=e.apply(this,arguments),void 0==n||n||t.preventDefault(),n};this[i]=t,this.addEventListener(o,t,!1)}else this[i]=null},n.get=function(){var e=this[i]||null;return null===e&&r&&r.get&&(e=r.get.apply(this,arguments))&&(n.set.apply(this,[e]),"function"==typeof this.removeAttribute&&this.removeAttribute(t)),this[i]||null},Object.defineProperty(e,t,n)}function o(e,t){var n=[];for(var o in e)"on"==o.substr(0,2)&&n.push(o);for(var i=0;i1?new t(e,n):new t(e),a=Object.getOwnPropertyDescriptor(i,"onmessage");return a&&!1===a.configurable?(r=Object.create(i),["addEventListener","removeEventListener","send","close"].forEach(function(e){r[e]=function(){return i[e].apply(i,arguments)}})):r=i,o(r,["close","error","message","open"]),r};for(var n in t)e.WebSocket[n]=t[n]}function w(){if((j||P)&&!Object.getOwnPropertyDescriptor(HTMLElement.prototype,"onclick")&&"undefined"!=typeof Element){var e=Object.getOwnPropertyDescriptor(Element.prototype,"onclick");if(e&&!e.configurable)return!1}var t=Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"onreadystatechange");Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{enumerable:!0,configurable:!0,get:function(){return!0}});var n=new XMLHttpRequest,r=!!n.onreadystatechange;return Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",t||{}),r}function m(){for(var e=0;e "+o.zone.name+"]",o=o.parent):o=null;break;default:r[i]+=" ["+o.zone.name+"]"}}try{t.stack=t.zoneAwareStack=r.join("\n")}catch(e){}}return this instanceof G&&this.constructor!=G?(Object.keys(t).concat("stack","message").forEach(function(n){if(void 0!==t[n])try{e[n]=t[n]}catch(e){}}),this):t}if(e.Zone)throw new Error("Zone already loaded.");var y={name:"NO ZONE"},g=function(){function t(e,t){this._properties=null,this._parent=e,this._name=t?t.name||"unnamed":"",this._properties=t&&t.properties||{},this._zoneDelegate=new _(this,this._parent&&this._parent._zoneDelegate,t)}return t.assertZonePatched=function(){if(e.Promise!==A)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")},Object.defineProperty(t,"root",{get:function(){for(var e=t.current;e.parent;)e=e.parent;return e},enumerable:!0,configurable:!0}),Object.defineProperty(t,"current",{get:function(){return S.zone},enumerable:!0,configurable:!0}),Object.defineProperty(t,"currentTask",{get:function(){return O},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),t.prototype.get=function(e){var t=this.getZoneWith(e);if(t)return t._properties[e]},t.prototype.getZoneWith=function(e){for(var t=this;t;){if(t._properties.hasOwnProperty(e))return t;t=t._parent}return null},t.prototype.fork=function(e){if(!e)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,e)},t.prototype.wrap=function(e,t){if("function"!=typeof e)throw new Error("Expecting function got: "+e);var n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}},t.prototype.run=function(e,t,n,r){void 0===t&&(t=void 0),void 0===n&&(n=null),void 0===r&&(r=null),S=new m(S,this);try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{S=S.parent}},t.prototype.runGuarded=function(e,t,n,r){void 0===t&&(t=null),void 0===n&&(n=null),void 0===r&&(r=null),S=new m(S,this);try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{S=S.parent}},t.prototype.runTask=function(e,t,n){if(e.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(e.zone||y).name+"; Execution: "+this.name+")");var r="running"!=e.state;r&&e._transitionTo("running","scheduled"),e.runCount++;var o=O;O=e,S=new m(S,this);try{"macroTask"==e.type&&e.data&&!e.data.isPeriodic&&(e.cancelFn=null);try{return this._zoneDelegate.invokeTask(this,e,t,n)}catch(e){if(this._zoneDelegate.handleError(this,e))throw e}}finally{"notScheduled"!==e.state&&"unknown"!==e.state&&("eventTask"==e.type||e.data&&e.data.isPeriodic?r&&e._transitionTo("scheduled","running"):(e.runCount=0,this._updateTaskCount(e,-1),r&&e._transitionTo("notScheduled","running","notScheduled"))),S=S.parent,O=o}},t.prototype.scheduleTask=function(e){if(e.zone&&e.zone!==this)for(var t=this;t;){if(t===e.zone)throw Error("can not reschedule task to "+this.name+" which is descendants of the original zone "+e.zone.name);t=t.parent}e._transitionTo("scheduling","notScheduled");var n=[];e._zoneDelegates=n,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(t){throw e._transitionTo("unknown","scheduling","notScheduled"),this._zoneDelegate.handleError(this,t),t}return e._zoneDelegates===n&&this._updateTaskCount(e,1),"scheduling"==e.state&&e._transitionTo("scheduled","scheduling"),e},t.prototype.scheduleMicroTask=function(e,t,n,r){return this.scheduleTask(new w("microTask",e,t,n,r,null))},t.prototype.scheduleMacroTask=function(e,t,n,r,o){return this.scheduleTask(new w("macroTask",e,t,n,r,o))},t.prototype.scheduleEventTask=function(e,t,n,r,o){return this.scheduleTask(new w("eventTask",e,t,n,r,o))},t.prototype.cancelTask=function(e){if(e.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(e.zone||y).name+"; Execution: "+this.name+")");e._transitionTo("canceling","scheduled","running");try{this._zoneDelegate.cancelTask(this,e)}catch(t){throw e._transitionTo("unknown","canceling"),this._zoneDelegate.handleError(this,t),t}return this._updateTaskCount(e,-1),e._transitionTo("notScheduled","canceling"),e.runCount=0,e},t.prototype._updateTaskCount=function(e,t){var n=e._zoneDelegates;-1==t&&(e._zoneDelegates=null);for(var r=0;r0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e};this.hasTask(this.zone,i)}},e}(),w=function(){function e(e,t,n,r,o,i){this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=e,this.source=t,this.data=r,this.scheduleFn=o,this.cancelFn=i,this.callback=n;var u=this;this.invoke=function(){D++;try{return u.runCount++,u.zone.runTask(u,this,arguments)}finally{1==D&&a(),D--}}}return Object.defineProperty(e.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"state",{get:function(){return this._state},enumerable:!0,configurable:!0}),e.prototype.cancelScheduleRequest=function(){this._transitionTo("notScheduled","scheduling")},e.prototype._transitionTo=function(e,t,n){if(this._state!==t&&this._state!==n)throw new Error(this.type+" '"+this.source+"': can not transition to '"+e+"', expecting state '"+t+"'"+(n?" or '"+n+"'":"")+", was '"+this._state+"'.");this._state=e,"notScheduled"==e&&(this._zoneDelegates=null)},e.prototype.toString=function(){return this.data&&void 0!==this.data.handleId?this.data.handleId:Object.prototype.toString.call(this)},e.prototype.toJSON=function(){return{type:this.type,state:this.state,source:this.source,data:this.data,zone:this.zone.name,invoke:this.invoke,scheduleFn:this.scheduleFn,cancelFn:this.cancelFn,runCount:this.runCount,callback:this.callback}},e}(),m=function(){function e(e,t){this.parent=e,this.zone=t}return e}(),T=t("setTimeout"),b=t("Promise"),E=t("then"),S=new m(null,new g(null,null)),O=null,j=[],P=!1,z=[],D=0,Z=t("state"),C=t("value"),M="Promise.then",I=null,L=!0,x=!1,F=0,R=function(){var e=!1;return function(t){return function(){e||(e=!0,t.apply(null,arguments))}}},A=function(){function e(t){var n=this;if(!(n instanceof e))throw new Error("Must be an instanceof Promise.");n[Z]=I,n[C]=[];try{t&&t(l(n,L),l(n,x))}catch(e){f(n,!1,e)}}return e.toString=function(){return"function ZoneAwarePromise() { [native code] }"},e.resolve=function(e){return f(new this(null),L,e)},e.reject=function(e){return f(new this(null),x,e)},e.race=function(e){function t(e){i&&(i=r(e))}function n(e){i&&(i=o(e))}for(var r,o,i=new this(function(e,t){n=[e,t],r=n[0],o=n[1];var n}),a=0,c=e;a= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11 | return c > 3 && r && Object.defineProperty(target, key, r), r;
12 | }
13 |
14 | function __metadata(k, v) {
15 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
16 | }
17 |
18 | var BASE64_VALIDATOR = {
19 | provide: _angular_forms.NG_VALIDATORS,
20 | useExisting: _angular_core.forwardRef(function () { return Base64Validator$$1; }),
21 | multi: true
22 | };
23 | var Base64Validator$$1 = (function () {
24 | function Base64Validator$$1() {
25 | }
26 | Base64Validator$$1.prototype.validate = function (c) {
27 | return base64(c);
28 | };
29 | return Base64Validator$$1;
30 | }());
31 | Base64Validator$$1 = __decorate([
32 | _angular_core.Directive({
33 | selector: '[base64][formControlName],[base64][formControl],[base64][ngModel]',
34 | providers: [BASE64_VALIDATOR]
35 | })
36 | ], Base64Validator$$1);
37 |
38 | function isPresent(obj) {
39 | return obj !== undefined && obj !== null;
40 | }
41 | function isDate(obj) {
42 | return !/Invalid|NaN/.test(new Date(obj).toString());
43 | }
44 |
45 | var base64 = function (control) {
46 | if (isPresent(_angular_forms.Validators.required(control)))
47 | return null;
48 | var v = control.value;
49 | return /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i.test(v) ? null : { 'base64': true };
50 | };
51 |
52 | var CREDIT_CARD_VALIDATOR = {
53 | provide: _angular_forms.NG_VALIDATORS,
54 | useExisting: _angular_core.forwardRef(function () { return CreditCardValidator$$1; }),
55 | multi: true
56 | };
57 | var CreditCardValidator$$1 = (function () {
58 | function CreditCardValidator$$1() {
59 | }
60 | CreditCardValidator$$1.prototype.validate = function (c) {
61 | return creditCard(c);
62 | };
63 | return CreditCardValidator$$1;
64 | }());
65 | CreditCardValidator$$1 = __decorate([
66 | _angular_core.Directive({
67 | selector: '[creditCard][formControlName],[creditCard][formControl],[creditCard][ngModel]',
68 | providers: [CREDIT_CARD_VALIDATOR]
69 | })
70 | ], CreditCardValidator$$1);
71 |
72 | var creditCard = function (control) {
73 | if (isPresent(_angular_forms.Validators.required(control)))
74 | return null;
75 | var v = control.value;
76 | var sanitized = v.replace(/[^0-9]+/g, '');
77 | // problem with chrome
78 | if (!(/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/.test(sanitized))) {
79 | return { creditCard: true };
80 | }
81 | var sum = 0;
82 | var digit;
83 | var tmpNum;
84 | var shouldDouble;
85 | for (var i = sanitized.length - 1; i >= 0; i--) {
86 | digit = sanitized.substring(i, (i + 1));
87 | tmpNum = parseInt(digit, 10);
88 | if (shouldDouble) {
89 | tmpNum *= 2;
90 | if (tmpNum >= 10) {
91 | sum += ((tmpNum % 10) + 1);
92 | }
93 | else {
94 | sum += tmpNum;
95 | }
96 | }
97 | else {
98 | sum += tmpNum;
99 | }
100 | shouldDouble = !shouldDouble;
101 | }
102 | if (Boolean((sum % 10) === 0 ? sanitized : false)) {
103 | return null;
104 | }
105 | return { creditCard: true };
106 | };
107 |
108 | var DATE_VALIDATOR = {
109 | provide: _angular_forms.NG_VALIDATORS,
110 | useExisting: _angular_core.forwardRef(function () { return DateValidator$$1; }),
111 | multi: true
112 | };
113 | var DateValidator$$1 = (function () {
114 | function DateValidator$$1() {
115 | }
116 | DateValidator$$1.prototype.validate = function (c) {
117 | return date(c);
118 | };
119 | return DateValidator$$1;
120 | }());
121 | DateValidator$$1 = __decorate([
122 | _angular_core.Directive({
123 | selector: '[date][formControlName],[date][formControl],[date][ngModel]',
124 | providers: [DATE_VALIDATOR]
125 | })
126 | ], DateValidator$$1);
127 |
128 | var date = function (control) {
129 | if (isPresent(_angular_forms.Validators.required(control)))
130 | return null;
131 | var v = control.value;
132 | return isDate(v) ? null : { date: true };
133 | };
134 |
135 | var DATE_ISO_VALIDATOR = {
136 | provide: _angular_forms.NG_VALIDATORS,
137 | useExisting: _angular_core.forwardRef(function () { return DateISOValidator$$1; }),
138 | multi: true
139 | };
140 | var DateISOValidator$$1 = (function () {
141 | function DateISOValidator$$1() {
142 | }
143 | DateISOValidator$$1.prototype.validate = function (c) {
144 | return dateISO(c);
145 | };
146 | return DateISOValidator$$1;
147 | }());
148 | DateISOValidator$$1 = __decorate([
149 | _angular_core.Directive({
150 | selector: '[dateISO][formControlName],[dateISO][formControl],[dateISO][ngModel]',
151 | providers: [DATE_ISO_VALIDATOR]
152 | })
153 | ], DateISOValidator$$1);
154 |
155 | var dateISO = function (control) {
156 | if (isPresent(_angular_forms.Validators.required(control)))
157 | return null;
158 | var v = control.value;
159 | return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(v) ? null : { dateISO: true };
160 | };
161 |
162 | var DIGITS_VALIDATOR = {
163 | provide: _angular_forms.NG_VALIDATORS,
164 | useExisting: _angular_core.forwardRef(function () { return DigitsValidator$$1; }),
165 | multi: true
166 | };
167 | var DigitsValidator$$1 = (function () {
168 | function DigitsValidator$$1() {
169 | }
170 | DigitsValidator$$1.prototype.validate = function (c) {
171 | return digits(c);
172 | };
173 | return DigitsValidator$$1;
174 | }());
175 | DigitsValidator$$1 = __decorate([
176 | _angular_core.Directive({
177 | selector: '[digits][formControlName],[digits][formControl],[digits][ngModel]',
178 | providers: [DIGITS_VALIDATOR]
179 | })
180 | ], DigitsValidator$$1);
181 |
182 | var digits = function (control) {
183 | if (isPresent(_angular_forms.Validators.required(control)))
184 | return null;
185 | var v = control.value;
186 | return /^\d+$/.test(v) ? null : { digits: true };
187 | };
188 |
189 | var EMAIL_VALIDATOR = {
190 | provide: _angular_forms.NG_VALIDATORS,
191 | useExisting: _angular_core.forwardRef(function () { return EmailValidator$$1; }),
192 | multi: true
193 | };
194 | var EmailValidator$$1 = (function () {
195 | function EmailValidator$$1() {
196 | }
197 | EmailValidator$$1.prototype.validate = function (c) {
198 | return email(c);
199 | };
200 | return EmailValidator$$1;
201 | }());
202 | EmailValidator$$1 = __decorate([
203 | _angular_core.Directive({
204 | selector: '[email][formControlName],[email][formControl],[email][ngModel]',
205 | providers: [EMAIL_VALIDATOR]
206 | })
207 | ], EmailValidator$$1);
208 |
209 | var email = function (control) {
210 | if (isPresent(_angular_forms.Validators.required(control)))
211 | return null;
212 | var v = control.value;
213 | return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(v) ? null : { 'email': true };
214 | };
215 |
216 | var EQUAL_VALIDATOR = {
217 | provide: _angular_forms.NG_VALIDATORS,
218 | useExisting: _angular_core.forwardRef(function () { return EqualValidator$$1; }),
219 | multi: true
220 | };
221 | var EqualValidator$$1 = (function () {
222 | function EqualValidator$$1() {
223 | }
224 | EqualValidator$$1.prototype.ngOnInit = function () {
225 | this.validator = equal(this.equal);
226 | };
227 | EqualValidator$$1.prototype.ngOnChanges = function (changes) {
228 | for (var key in changes) {
229 | if (key === 'equal') {
230 | this.validator = equal(changes[key].currentValue);
231 | if (this.onChange)
232 | this.onChange();
233 | }
234 | }
235 | };
236 | EqualValidator$$1.prototype.validate = function (c) {
237 | return this.validator(c);
238 | };
239 | EqualValidator$$1.prototype.registerOnValidatorChange = function (fn) {
240 | this.onChange = fn;
241 | };
242 | return EqualValidator$$1;
243 | }());
244 | __decorate([
245 | _angular_core.Input(),
246 | __metadata("design:type", Object)
247 | ], EqualValidator$$1.prototype, "equal", void 0);
248 | EqualValidator$$1 = __decorate([
249 | _angular_core.Directive({
250 | selector: '[equal][formControlName],[equal][formControl],[equal][ngModel]',
251 | providers: [EQUAL_VALIDATOR]
252 | })
253 | ], EqualValidator$$1);
254 |
255 | var equal = function (val) {
256 | return function (control) {
257 | if (isPresent(_angular_forms.Validators.required(control)))
258 | return null;
259 | var v = control.value;
260 | return val === v ? null : { equal: true };
261 | };
262 | };
263 |
264 | var EQUAL_TO_VALIDATOR = {
265 | provide: _angular_forms.NG_VALIDATORS,
266 | useExisting: _angular_core.forwardRef(function () { return EqualToValidator$$1; }),
267 | multi: true
268 | };
269 | var EqualToValidator$$1 = (function () {
270 | function EqualToValidator$$1() {
271 | }
272 | EqualToValidator$$1.prototype.ngOnInit = function () {
273 | this.validator = equalTo(this.equalTo);
274 | };
275 | EqualToValidator$$1.prototype.validate = function (c) {
276 | return this.validator(c);
277 | };
278 | return EqualToValidator$$1;
279 | }());
280 | __decorate([
281 | _angular_core.Input(),
282 | __metadata("design:type", typeof (_a = typeof _angular_forms.FormControl !== "undefined" && _angular_forms.FormControl) === "function" && _a || Object)
283 | ], EqualToValidator$$1.prototype, "equalTo", void 0);
284 | EqualToValidator$$1 = __decorate([
285 | _angular_core.Directive({
286 | selector: '[equalTo][formControlName],[equalTo][formControl],[equalTo][ngModel]',
287 | providers: [EQUAL_TO_VALIDATOR]
288 | })
289 | ], EqualToValidator$$1);
290 | var _a;
291 |
292 | var equalTo = function (equalControl) {
293 | var subscribe = false;
294 | return function (control) {
295 | if (!subscribe) {
296 | subscribe = true;
297 | equalControl.valueChanges.subscribe(function () {
298 | control.updateValueAndValidity();
299 | });
300 | }
301 | var v = control.value;
302 | return equalControl.value === v ? null : { equalTo: true };
303 | };
304 | };
305 |
306 | var GREATER_THAN_VALIDATOR = {
307 | provide: _angular_forms.NG_VALIDATORS,
308 | useExisting: _angular_core.forwardRef(function () { return GreaterThanValidator$$1; }),
309 | multi: true
310 | };
311 | var GreaterThanValidator$$1 = (function () {
312 | function GreaterThanValidator$$1() {
313 | }
314 | GreaterThanValidator$$1.prototype.ngOnInit = function () {
315 | this.validator = gt(this.gt);
316 | };
317 | GreaterThanValidator$$1.prototype.ngOnChanges = function (changes) {
318 | for (var key in changes) {
319 | if (key === 'gt') {
320 | this.validator = gt(changes[key].currentValue);
321 | if (this.onChange)
322 | this.onChange();
323 | }
324 | }
325 | };
326 | GreaterThanValidator$$1.prototype.validate = function (c) {
327 | return this.validator(c);
328 | };
329 | GreaterThanValidator$$1.prototype.registerOnValidatorChange = function (fn) {
330 | this.onChange = fn;
331 | };
332 | return GreaterThanValidator$$1;
333 | }());
334 | __decorate([
335 | _angular_core.Input(),
336 | __metadata("design:type", Number)
337 | ], GreaterThanValidator$$1.prototype, "gt", void 0);
338 | GreaterThanValidator$$1 = __decorate([
339 | _angular_core.Directive({
340 | selector: '[gt][formControlName],[gt][formControl],[gt][ngModel]',
341 | providers: [GREATER_THAN_VALIDATOR]
342 | })
343 | ], GreaterThanValidator$$1);
344 |
345 | var gt = function (gt) {
346 | return function (control) {
347 | if (!isPresent(gt))
348 | return null;
349 | if (isPresent(_angular_forms.Validators.required(control)))
350 | return null;
351 | var v = +control.value;
352 | return v > +gt ? null : { gt: true };
353 | };
354 | };
355 |
356 | var GREATER_THAN_EQUAL_VALIDATOR = {
357 | provide: _angular_forms.NG_VALIDATORS,
358 | useExisting: _angular_core.forwardRef(function () { return GreaterThanEqualValidator$$1; }),
359 | multi: true
360 | };
361 | var GreaterThanEqualValidator$$1 = (function () {
362 | function GreaterThanEqualValidator$$1() {
363 | }
364 | GreaterThanEqualValidator$$1.prototype.ngOnInit = function () {
365 | this.validator = gte(this.gte);
366 | };
367 | GreaterThanEqualValidator$$1.prototype.ngOnChanges = function (changes) {
368 | for (var key in changes) {
369 | if (key === 'gte') {
370 | this.validator = gte(changes[key].currentValue);
371 | if (this.onChange)
372 | this.onChange();
373 | }
374 | }
375 | };
376 | GreaterThanEqualValidator$$1.prototype.validate = function (c) {
377 | return this.validator(c);
378 | };
379 | GreaterThanEqualValidator$$1.prototype.registerOnValidatorChange = function (fn) {
380 | this.onChange = fn;
381 | };
382 | return GreaterThanEqualValidator$$1;
383 | }());
384 | __decorate([
385 | _angular_core.Input(),
386 | __metadata("design:type", Number)
387 | ], GreaterThanEqualValidator$$1.prototype, "gte", void 0);
388 | GreaterThanEqualValidator$$1 = __decorate([
389 | _angular_core.Directive({
390 | selector: '[gte][formControlName],[gte][formControl],[gte][ngModel]',
391 | providers: [GREATER_THAN_EQUAL_VALIDATOR]
392 | })
393 | ], GreaterThanEqualValidator$$1);
394 |
395 | var gte = function (gte) {
396 | return function (control) {
397 | if (!isPresent(gte))
398 | return null;
399 | if (isPresent(_angular_forms.Validators.required(control)))
400 | return null;
401 | var v = +control.value;
402 | return v >= +gte ? null : { gte: true };
403 | };
404 | };
405 |
406 | var JSON_VALIDATOR = {
407 | provide: _angular_forms.NG_VALIDATORS,
408 | useExisting: _angular_core.forwardRef(function () { return JSONValidator$$1; }),
409 | multi: true
410 | };
411 | var JSONValidator$$1 = (function () {
412 | function JSONValidator$$1() {
413 | }
414 | JSONValidator$$1.prototype.validate = function (c) {
415 | return json(c);
416 | };
417 | return JSONValidator$$1;
418 | }());
419 | JSONValidator$$1 = __decorate([
420 | _angular_core.Directive({
421 | selector: '[json][formControlName],[json][formControl],[json][ngModel]',
422 | providers: [JSON_VALIDATOR]
423 | })
424 | ], JSONValidator$$1);
425 |
426 | var json = function (control) {
427 | if (isPresent(_angular_forms.Validators.required(control)))
428 | return null;
429 | var v = control.value;
430 | try {
431 | var obj = JSON.parse(v);
432 | if (Boolean(obj) && typeof obj === 'object') {
433 | return null;
434 | }
435 | }
436 | catch (e) {
437 | }
438 | return { json: true };
439 | };
440 |
441 | var LESS_THAN_VALIDATOR = {
442 | provide: _angular_forms.NG_VALIDATORS,
443 | useExisting: _angular_core.forwardRef(function () { return LessThanValidator$$1; }),
444 | multi: true
445 | };
446 | var LessThanValidator$$1 = (function () {
447 | function LessThanValidator$$1() {
448 | }
449 | LessThanValidator$$1.prototype.ngOnInit = function () {
450 | this.validator = lt(this.lt);
451 | };
452 | LessThanValidator$$1.prototype.ngOnChanges = function (changes) {
453 | for (var key in changes) {
454 | if (key === 'lt') {
455 | this.validator = lt(changes[key].currentValue);
456 | if (this.onChange)
457 | this.onChange();
458 | }
459 | }
460 | };
461 | LessThanValidator$$1.prototype.validate = function (c) {
462 | return this.validator(c);
463 | };
464 | LessThanValidator$$1.prototype.registerOnValidatorChange = function (fn) {
465 | this.onChange = fn;
466 | };
467 | return LessThanValidator$$1;
468 | }());
469 | __decorate([
470 | _angular_core.Input(),
471 | __metadata("design:type", Number)
472 | ], LessThanValidator$$1.prototype, "lt", void 0);
473 | LessThanValidator$$1 = __decorate([
474 | _angular_core.Directive({
475 | selector: '[lt][formControlName],[lt][formControl],[lt][ngModel]',
476 | providers: [LESS_THAN_VALIDATOR]
477 | })
478 | ], LessThanValidator$$1);
479 |
480 | var lt = function (lt) {
481 | return function (control) {
482 | if (!isPresent(lt))
483 | return null;
484 | if (isPresent(_angular_forms.Validators.required(control)))
485 | return null;
486 | var v = +control.value;
487 | return v < +lt ? null : { lt: true };
488 | };
489 | };
490 |
491 | var LESS_THAN_EQUAL_VALIDATOR = {
492 | provide: _angular_forms.NG_VALIDATORS,
493 | useExisting: _angular_core.forwardRef(function () { return LessThanEqualValidator$$1; }),
494 | multi: true
495 | };
496 | var LessThanEqualValidator$$1 = (function () {
497 | function LessThanEqualValidator$$1() {
498 | }
499 | LessThanEqualValidator$$1.prototype.ngOnInit = function () {
500 | this.validator = lte(this.lte);
501 | };
502 | LessThanEqualValidator$$1.prototype.ngOnChanges = function (changes) {
503 | for (var key in changes) {
504 | if (key === 'lte') {
505 | this.validator = lte(changes[key].currentValue);
506 | if (this.onChange)
507 | this.onChange();
508 | }
509 | }
510 | };
511 | LessThanEqualValidator$$1.prototype.validate = function (c) {
512 | return this.validator(c);
513 | };
514 | LessThanEqualValidator$$1.prototype.registerOnValidatorChange = function (fn) {
515 | this.onChange = fn;
516 | };
517 | return LessThanEqualValidator$$1;
518 | }());
519 | __decorate([
520 | _angular_core.Input(),
521 | __metadata("design:type", Number)
522 | ], LessThanEqualValidator$$1.prototype, "lte", void 0);
523 | LessThanEqualValidator$$1 = __decorate([
524 | _angular_core.Directive({
525 | selector: '[lte][formControlName],[lte][formControl],[lte][ngModel]',
526 | providers: [LESS_THAN_EQUAL_VALIDATOR]
527 | })
528 | ], LessThanEqualValidator$$1);
529 |
530 | var lte = function (lte) {
531 | return function (control) {
532 | if (!isPresent(lte))
533 | return null;
534 | if (isPresent(_angular_forms.Validators.required(control)))
535 | return null;
536 | var v = +control.value;
537 | return v <= +lte ? null : { lte: true };
538 | };
539 | };
540 |
541 | var MAX_VALIDATOR = {
542 | provide: _angular_forms.NG_VALIDATORS,
543 | useExisting: _angular_core.forwardRef(function () { return MaxValidator$$1; }),
544 | multi: true
545 | };
546 | var MaxValidator$$1 = (function () {
547 | function MaxValidator$$1() {
548 | }
549 | MaxValidator$$1.prototype.ngOnInit = function () {
550 | this.validator = max(this.max);
551 | };
552 | MaxValidator$$1.prototype.ngOnChanges = function (changes) {
553 | for (var key in changes) {
554 | if (key === 'max') {
555 | this.validator = max(changes[key].currentValue);
556 | if (this.onChange)
557 | this.onChange();
558 | }
559 | }
560 | };
561 | MaxValidator$$1.prototype.validate = function (c) {
562 | return this.validator(c);
563 | };
564 | MaxValidator$$1.prototype.registerOnValidatorChange = function (fn) {
565 | this.onChange = fn;
566 | };
567 | return MaxValidator$$1;
568 | }());
569 | __decorate([
570 | _angular_core.Input(),
571 | __metadata("design:type", Number)
572 | ], MaxValidator$$1.prototype, "max", void 0);
573 | MaxValidator$$1 = __decorate([
574 | _angular_core.Directive({
575 | selector: '[max][formControlName],[max][formControl],[max][ngModel]',
576 | providers: [MAX_VALIDATOR]
577 | })
578 | ], MaxValidator$$1);
579 |
580 | var max = function (max) {
581 | return function (control) {
582 | if (!isPresent(max))
583 | return null;
584 | if (isPresent(_angular_forms.Validators.required(control)))
585 | return null;
586 | var v = +control.value;
587 | return v <= +max ? null : { actualValue: v, requiredValue: +max, max: true };
588 | };
589 | };
590 |
591 | var MAX_DATE_VALIDATOR = {
592 | provide: _angular_forms.NG_VALIDATORS,
593 | useExisting: _angular_core.forwardRef(function () { return MaxDateValidator$$1; }),
594 | multi: true
595 | };
596 | var MaxDateValidator$$1 = (function () {
597 | function MaxDateValidator$$1() {
598 | }
599 | MaxDateValidator$$1.prototype.ngOnInit = function () {
600 | this.validator = maxDate(this.maxDate);
601 | };
602 | MaxDateValidator$$1.prototype.ngOnChanges = function (changes) {
603 | for (var key in changes) {
604 | if (key === 'maxDate') {
605 | this.validator = maxDate(changes[key].currentValue);
606 | if (this.onChange)
607 | this.onChange();
608 | }
609 | }
610 | };
611 | MaxDateValidator$$1.prototype.validate = function (c) {
612 | return this.validator(c);
613 | };
614 | MaxDateValidator$$1.prototype.registerOnValidatorChange = function (fn) {
615 | this.onChange = fn;
616 | };
617 | return MaxDateValidator$$1;
618 | }());
619 | __decorate([
620 | _angular_core.Input(),
621 | __metadata("design:type", Object)
622 | ], MaxDateValidator$$1.prototype, "maxDate", void 0);
623 | MaxDateValidator$$1 = __decorate([
624 | _angular_core.Directive({
625 | selector: '[maxDate][formControlName],[maxDate][formControl],[maxDate][ngModel]',
626 | providers: [MAX_DATE_VALIDATOR]
627 | })
628 | ], MaxDateValidator$$1);
629 |
630 | var maxDate = function (maxDate) {
631 | if (!isDate(maxDate) && !(maxDate instanceof Function)) {
632 | throw Error('maxDate value must be or return a formatted date');
633 | }
634 | return function (control) {
635 | if (isPresent(_angular_forms.Validators.required(control)))
636 | return null;
637 | var d = new Date(control.value);
638 | if (!isDate(d))
639 | return { maxDate: true };
640 | if (maxDate instanceof Function)
641 | maxDate = maxDate();
642 | return d <= new Date(maxDate) ? null : { maxDate: true };
643 | };
644 | };
645 |
646 | var MIN_VALIDATOR = {
647 | provide: _angular_forms.NG_VALIDATORS,
648 | useExisting: _angular_core.forwardRef(function () { return MinValidator$$1; }),
649 | multi: true
650 | };
651 | var MinValidator$$1 = (function () {
652 | function MinValidator$$1() {
653 | }
654 | MinValidator$$1.prototype.ngOnInit = function () {
655 | this.validator = min(this.min);
656 | };
657 | MinValidator$$1.prototype.ngOnChanges = function (changes) {
658 | for (var key in changes) {
659 | if (key === 'min') {
660 | this.validator = min(changes[key].currentValue);
661 | if (this.onChange)
662 | this.onChange();
663 | }
664 | }
665 | };
666 | MinValidator$$1.prototype.validate = function (c) {
667 | return this.validator(c);
668 | };
669 | MinValidator$$1.prototype.registerOnValidatorChange = function (fn) {
670 | this.onChange = fn;
671 | };
672 | return MinValidator$$1;
673 | }());
674 | __decorate([
675 | _angular_core.Input(),
676 | __metadata("design:type", Number)
677 | ], MinValidator$$1.prototype, "min", void 0);
678 | MinValidator$$1 = __decorate([
679 | _angular_core.Directive({
680 | selector: '[min][formControlName],[min][formControl],[min][ngModel]',
681 | providers: [MIN_VALIDATOR]
682 | })
683 | ], MinValidator$$1);
684 |
685 | var min = function (min) {
686 | return function (control) {
687 | if (!isPresent(min))
688 | return null;
689 | if (isPresent(_angular_forms.Validators.required(control)))
690 | return null;
691 | var v = +control.value;
692 | return v >= +min ? null : { actualValue: v, requiredValue: +min, min: true };
693 | };
694 | };
695 |
696 | var MIN_DATE_VALIDATOR = {
697 | provide: _angular_forms.NG_VALIDATORS,
698 | useExisting: _angular_core.forwardRef(function () { return MinDateValidator$$1; }),
699 | multi: true
700 | };
701 | var MinDateValidator$$1 = (function () {
702 | function MinDateValidator$$1() {
703 | }
704 | MinDateValidator$$1.prototype.ngOnInit = function () {
705 | this.validator = minDate(this.minDate);
706 | };
707 | MinDateValidator$$1.prototype.ngOnChanges = function (changes) {
708 | for (var key in changes) {
709 | if (key === 'minDate') {
710 | this.validator = minDate(changes[key].currentValue);
711 | if (this.onChange)
712 | this.onChange();
713 | }
714 | }
715 | };
716 | MinDateValidator$$1.prototype.validate = function (c) {
717 | return this.validator(c);
718 | };
719 | MinDateValidator$$1.prototype.registerOnValidatorChange = function (fn) {
720 | this.onChange = fn;
721 | };
722 | return MinDateValidator$$1;
723 | }());
724 | __decorate([
725 | _angular_core.Input(),
726 | __metadata("design:type", Object)
727 | ], MinDateValidator$$1.prototype, "minDate", void 0);
728 | MinDateValidator$$1 = __decorate([
729 | _angular_core.Directive({
730 | selector: '[minDate][formControlName],[minDate][formControl],[minDate][ngModel]',
731 | providers: [MIN_DATE_VALIDATOR]
732 | })
733 | ], MinDateValidator$$1);
734 |
735 | var minDate = function (minDate) {
736 | if (!isDate(minDate) && !(minDate instanceof Function)) {
737 | throw Error('minDate value must be or return a formatted date');
738 | }
739 | return function (control) {
740 | if (isPresent(_angular_forms.Validators.required(control)))
741 | return null;
742 | var d = new Date(control.value);
743 | if (!isDate(d))
744 | return { minDate: true };
745 | if (minDate instanceof Function)
746 | minDate = minDate();
747 | return d >= new Date(minDate) ? null : { minDate: true };
748 | };
749 | };
750 |
751 | var NOT_EQUAL_VALIDATOR = {
752 | provide: _angular_forms.NG_VALIDATORS,
753 | useExisting: _angular_core.forwardRef(function () { return NotEqualValidator$$1; }),
754 | multi: true
755 | };
756 | var NotEqualValidator$$1 = (function () {
757 | function NotEqualValidator$$1() {
758 | }
759 | NotEqualValidator$$1.prototype.ngOnInit = function () {
760 | this.validator = notEqual(this.notEqual);
761 | };
762 | NotEqualValidator$$1.prototype.ngOnChanges = function (changes) {
763 | for (var key in changes) {
764 | if (key === 'notEqual') {
765 | this.validator = notEqual(changes[key].currentValue);
766 | if (this.onChange)
767 | this.onChange();
768 | }
769 | }
770 | };
771 | NotEqualValidator$$1.prototype.validate = function (c) {
772 | return this.validator(c);
773 | };
774 | NotEqualValidator$$1.prototype.registerOnValidatorChange = function (fn) {
775 | this.onChange = fn;
776 | };
777 | return NotEqualValidator$$1;
778 | }());
779 | __decorate([
780 | _angular_core.Input(),
781 | __metadata("design:type", Object)
782 | ], NotEqualValidator$$1.prototype, "notEqual", void 0);
783 | NotEqualValidator$$1 = __decorate([
784 | _angular_core.Directive({
785 | selector: '[notEqual][formControlName],[notEqual][formControl],[notEqual][ngModel]',
786 | providers: [NOT_EQUAL_VALIDATOR]
787 | })
788 | ], NotEqualValidator$$1);
789 |
790 | var notEqual = function (val) {
791 | return function (control) {
792 | if (isPresent(_angular_forms.Validators.required(control)))
793 | return null;
794 | var v = control.value;
795 | return val !== v ? null : { notEqual: true };
796 | };
797 | };
798 |
799 | var NOT_EQUAL_TO_VALIDATOR = {
800 | provide: _angular_forms.NG_VALIDATORS,
801 | useExisting: _angular_core.forwardRef(function () { return NotEqualToValidator$$1; }),
802 | multi: true
803 | };
804 | var NotEqualToValidator$$1 = (function () {
805 | function NotEqualToValidator$$1() {
806 | }
807 | NotEqualToValidator$$1.prototype.ngOnInit = function () {
808 | this.validator = notEqualTo(this.notEqualTo);
809 | };
810 | NotEqualToValidator$$1.prototype.validate = function (c) {
811 | return this.validator(c);
812 | };
813 | return NotEqualToValidator$$1;
814 | }());
815 | __decorate([
816 | _angular_core.Input(),
817 | __metadata("design:type", typeof (_a$1 = typeof _angular_forms.FormControl !== "undefined" && _angular_forms.FormControl) === "function" && _a$1 || Object)
818 | ], NotEqualToValidator$$1.prototype, "notEqualTo", void 0);
819 | NotEqualToValidator$$1 = __decorate([
820 | _angular_core.Directive({
821 | selector: '[notEqualTo][formControlName],[notEqualTo][formControl],[notEqualTo][ngModel]',
822 | providers: [NOT_EQUAL_TO_VALIDATOR]
823 | })
824 | ], NotEqualToValidator$$1);
825 | var _a$1;
826 |
827 | var notEqualTo = function (notEqualControl) {
828 | var subscribe = false;
829 | return function (control) {
830 | if (!subscribe) {
831 | subscribe = true;
832 | notEqualControl.valueChanges.subscribe(function () {
833 | control.updateValueAndValidity();
834 | });
835 | }
836 | var v = control.value;
837 | return notEqualControl.value !== v ? null : { notEqualTo: true };
838 | };
839 | };
840 |
841 | var NUMBER_VALIDATOR = {
842 | provide: _angular_forms.NG_VALIDATORS,
843 | useExisting: _angular_core.forwardRef(function () { return NumberValidator$$1; }),
844 | multi: true
845 | };
846 | var NumberValidator$$1 = (function () {
847 | function NumberValidator$$1() {
848 | }
849 | NumberValidator$$1.prototype.validate = function (c) {
850 | return number(c);
851 | };
852 | return NumberValidator$$1;
853 | }());
854 | NumberValidator$$1 = __decorate([
855 | _angular_core.Directive({
856 | selector: '[number][formControlName],[number][formControl],[number][ngModel]',
857 | providers: [NUMBER_VALIDATOR]
858 | })
859 | ], NumberValidator$$1);
860 |
861 | var number = function (control) {
862 | if (isPresent(_angular_forms.Validators.required(control)))
863 | return null;
864 | var v = control.value;
865 | return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(v) ? null : { 'number': true };
866 | };
867 |
868 | var PHONE_VALIDATOR = {
869 | provide: _angular_forms.NG_VALIDATORS,
870 | useExisting: _angular_core.forwardRef(function () { return PhoneValidator$$1; }),
871 | multi: true
872 | };
873 | var PhoneValidator$$1 = (function () {
874 | function PhoneValidator$$1() {
875 | }
876 | PhoneValidator$$1.prototype.ngOnInit = function () {
877 | this.validator = phone(this.phone);
878 | };
879 | PhoneValidator$$1.prototype.ngOnChanges = function (changes) {
880 | for (var key in changes) {
881 | if (key === 'phone') {
882 | this.validator = phone(changes[key].currentValue);
883 | if (this.onChange)
884 | this.onChange();
885 | }
886 | }
887 | };
888 | PhoneValidator$$1.prototype.validate = function (c) {
889 | return this.validator(c);
890 | };
891 | PhoneValidator$$1.prototype.registerOnValidatorChange = function (fn) {
892 | this.onChange = fn;
893 | };
894 | return PhoneValidator$$1;
895 | }());
896 | __decorate([
897 | _angular_core.Input(),
898 | __metadata("design:type", String)
899 | ], PhoneValidator$$1.prototype, "phone", void 0);
900 | PhoneValidator$$1 = __decorate([
901 | _angular_core.Directive({
902 | selector: '[phone][formControlName],[phone][formControl],[phone][ngModel]',
903 | providers: [PHONE_VALIDATOR]
904 | })
905 | ], PhoneValidator$$1);
906 |
907 | var phone = function (country) {
908 | return function (control) {
909 | if (isPresent(_angular_forms.Validators.required(control)))
910 | return null;
911 | var v = control.value;
912 | return libphonenumberJs.isValidNumber({ phone: v, country: country }) ? null : { phone: true };
913 | };
914 | };
915 |
916 | var RANGE_VALIDATOR = {
917 | provide: _angular_forms.NG_VALIDATORS,
918 | useExisting: _angular_core.forwardRef(function () { return RangeValidator$$1; }),
919 | multi: true
920 | };
921 | var RangeValidator$$1 = (function () {
922 | function RangeValidator$$1() {
923 | }
924 | RangeValidator$$1.prototype.ngOnInit = function () {
925 | this.validator = range(this.range);
926 | };
927 | RangeValidator$$1.prototype.ngOnChanges = function (changes) {
928 | for (var key in changes) {
929 | if (key === 'range') {
930 | this.validator = range(changes[key].currentValue);
931 | if (this.onChange)
932 | this.onChange();
933 | }
934 | }
935 | };
936 | RangeValidator$$1.prototype.validate = function (c) {
937 | return this.validator(c);
938 | };
939 | RangeValidator$$1.prototype.registerOnValidatorChange = function (fn) {
940 | this.onChange = fn;
941 | };
942 | return RangeValidator$$1;
943 | }());
944 | __decorate([
945 | _angular_core.Input(),
946 | __metadata("design:type", Array)
947 | ], RangeValidator$$1.prototype, "range", void 0);
948 | RangeValidator$$1 = __decorate([
949 | _angular_core.Directive({
950 | selector: '[range][formControlName],[range][formControl],[range][ngModel]',
951 | providers: [RANGE_VALIDATOR]
952 | })
953 | ], RangeValidator$$1);
954 |
955 | var range = function (range) {
956 | return function (control) {
957 | if (!isPresent(range))
958 | return null;
959 | if (isPresent(_angular_forms.Validators.required(control)))
960 | return null;
961 | var v = +control.value;
962 | return v >= range[0] && v <= range[1] ? null : { actualValue: v, requiredValue: range, range: true };
963 | };
964 | };
965 |
966 | var RANGE_LENGTH_VALIDATOR = {
967 | provide: _angular_forms.NG_VALIDATORS,
968 | useExisting: _angular_core.forwardRef(function () { return RangeLengthValidator$$1; }),
969 | multi: true
970 | };
971 | var RangeLengthValidator$$1 = (function () {
972 | function RangeLengthValidator$$1() {
973 | }
974 | RangeLengthValidator$$1.prototype.ngOnInit = function () {
975 | this.validator = rangeLength(this.rangeLength);
976 | };
977 | RangeLengthValidator$$1.prototype.ngOnChanges = function (changes) {
978 | for (var key in changes) {
979 | if (key === 'rangeLength') {
980 | this.validator = rangeLength(changes[key].currentValue);
981 | if (this.onChange)
982 | this.onChange();
983 | }
984 | }
985 | };
986 | RangeLengthValidator$$1.prototype.validate = function (c) {
987 | return this.validator(c);
988 | };
989 | RangeLengthValidator$$1.prototype.registerOnValidatorChange = function (fn) {
990 | this.onChange = fn;
991 | };
992 | return RangeLengthValidator$$1;
993 | }());
994 | __decorate([
995 | _angular_core.Input(),
996 | __metadata("design:type", Array)
997 | ], RangeLengthValidator$$1.prototype, "rangeLength", void 0);
998 | RangeLengthValidator$$1 = __decorate([
999 | _angular_core.Directive({
1000 | selector: '[rangeLength][formControlName],[rangeLength][formControl],[rangeLength][ngModel]',
1001 | providers: [RANGE_LENGTH_VALIDATOR]
1002 | })
1003 | ], RangeLengthValidator$$1);
1004 |
1005 | var rangeLength = function (rangeLength) {
1006 | return function (control) {
1007 | if (!isPresent(rangeLength))
1008 | return null;
1009 | if (isPresent(_angular_forms.Validators.required(control)))
1010 | return null;
1011 | var v = control.value;
1012 | return v.length >= rangeLength[0] && v.length <= rangeLength[1] ? null : { rangeLength: true };
1013 | };
1014 | };
1015 |
1016 | var URL_VALIDATOR = {
1017 | provide: _angular_forms.NG_VALIDATORS,
1018 | useExisting: _angular_core.forwardRef(function () { return UrlValidator$$1; }),
1019 | multi: true
1020 | };
1021 | var UrlValidator$$1 = (function () {
1022 | function UrlValidator$$1() {
1023 | }
1024 | UrlValidator$$1.prototype.validate = function (c) {
1025 | return url(c);
1026 | };
1027 | return UrlValidator$$1;
1028 | }());
1029 | UrlValidator$$1 = __decorate([
1030 | _angular_core.Directive({
1031 | selector: '[url][formControlName],[url][formControl],[url][ngModel]',
1032 | providers: [URL_VALIDATOR]
1033 | })
1034 | ], UrlValidator$$1);
1035 |
1036 | var url = function (control) {
1037 | if (isPresent(_angular_forms.Validators.required(control)))
1038 | return null;
1039 | var v = control.value;
1040 | return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(v) ? null : { 'url': true };
1041 | };
1042 |
1043 | var UUID_VALIDATOR = {
1044 | provide: _angular_forms.NG_VALIDATORS,
1045 | useExisting: _angular_core.forwardRef(function () { return UUIDValidator$$1; }),
1046 | multi: true
1047 | };
1048 | var UUIDValidator$$1 = (function () {
1049 | function UUIDValidator$$1() {
1050 | }
1051 | UUIDValidator$$1.prototype.ngOnInit = function () {
1052 | this.validator = uuid(this.uuid);
1053 | };
1054 | UUIDValidator$$1.prototype.ngOnChanges = function (changes) {
1055 | for (var key in changes) {
1056 | if (key === 'uuid') {
1057 | this.validator = uuid(changes[key].currentValue);
1058 | if (this.onChange)
1059 | this.onChange();
1060 | }
1061 | }
1062 | };
1063 | UUIDValidator$$1.prototype.validate = function (c) {
1064 | return this.validator(c);
1065 | };
1066 | UUIDValidator$$1.prototype.registerOnValidatorChange = function (fn) {
1067 | this.onChange = fn;
1068 | };
1069 | return UUIDValidator$$1;
1070 | }());
1071 | __decorate([
1072 | _angular_core.Input(),
1073 | __metadata("design:type", Object)
1074 | ], UUIDValidator$$1.prototype, "uuid", void 0);
1075 | UUIDValidator$$1 = __decorate([
1076 | _angular_core.Directive({
1077 | selector: '[uuid][formControlName],[uuid][formControl],[uuid][ngModel]',
1078 | providers: [UUID_VALIDATOR]
1079 | })
1080 | ], UUIDValidator$$1);
1081 |
1082 | var uuids = {
1083 | '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
1084 | '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1085 | '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
1086 | 'all': /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
1087 | };
1088 | var uuid = function (version) {
1089 | return function (control) {
1090 | if (isPresent(_angular_forms.Validators.required(control)))
1091 | return null;
1092 | var v = control.value;
1093 | var pattern = uuids[version] || uuids.all;
1094 | return (new RegExp(pattern)).test(v) ? null : { uuid: true };
1095 | };
1096 | };
1097 |
1098 | var CustomValidators = {
1099 | base64: base64,
1100 | creditCard: creditCard,
1101 | date: date,
1102 | dateISO: dateISO,
1103 | digits: digits,
1104 | email: email,
1105 | equal: equal,
1106 | equalTo: equalTo,
1107 | gt: gt,
1108 | gte: gte,
1109 | json: json,
1110 | lt: lt,
1111 | lte: lte,
1112 | max: max,
1113 | maxDate: maxDate,
1114 | min: min,
1115 | minDate: minDate,
1116 | notEqual: notEqual,
1117 | notEqualTo: notEqualTo,
1118 | number: number,
1119 | phone: phone,
1120 | range: range,
1121 | rangeLength: rangeLength,
1122 | url: url,
1123 | uuid: uuid
1124 | };
1125 | var CUSTOM_FORM_DIRECTIVES = [
1126 | Base64Validator$$1,
1127 | CreditCardValidator$$1,
1128 | DateValidator$$1,
1129 | DateISOValidator$$1,
1130 | DigitsValidator$$1,
1131 | EmailValidator$$1,
1132 | EqualValidator$$1,
1133 | EqualToValidator$$1,
1134 | GreaterThanValidator$$1,
1135 | GreaterThanEqualValidator$$1,
1136 | JSONValidator$$1,
1137 | LessThanValidator$$1,
1138 | LessThanEqualValidator$$1,
1139 | MaxValidator$$1,
1140 | MaxDateValidator$$1,
1141 | MinValidator$$1,
1142 | MinDateValidator$$1,
1143 | NotEqualValidator$$1,
1144 | NotEqualToValidator$$1,
1145 | NumberValidator$$1,
1146 | PhoneValidator$$1,
1147 | RangeValidator$$1,
1148 | RangeLengthValidator$$1,
1149 | UrlValidator$$1,
1150 | UUIDValidator$$1
1151 | ];
1152 | exports.CustomFormsModule = (function () {
1153 | function CustomFormsModule() {
1154 | }
1155 | return CustomFormsModule;
1156 | }());
1157 | exports.CustomFormsModule = __decorate([
1158 | _angular_core.NgModule({
1159 | declarations: [CUSTOM_FORM_DIRECTIVES],
1160 | exports: [CUSTOM_FORM_DIRECTIVES]
1161 | })
1162 | ], exports.CustomFormsModule);
1163 |
1164 | exports.CustomValidators = CustomValidators;
1165 |
1166 | Object.defineProperty(exports, '__esModule', { value: true });
1167 |
1168 | })));
1169 | //# sourceMappingURL=ng2-validation.umd.js.map
1170 |
--------------------------------------------------------------------------------