Skip to content

Commit

Permalink
bugfix and add new feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jacky.yyy committed Nov 30, 2016
1 parent 29a06d5 commit 2e772ff
Show file tree
Hide file tree
Showing 18 changed files with 392 additions and 152 deletions.
81 changes: 46 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ npm install ng2-validation --save
- url
- email
- date
- minDate
- maxDate
- dateISO
- creditCard
- json
Expand Down Expand Up @@ -123,6 +125,20 @@ export class AppModule {
<p *ngIf="field.errors?.date">error message</p>
```

### minDate

```html
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" minDate="2016-09-09"/>
<p *ngIf="field.errors?.minDate">error message</p>
```

### maxDate

```html
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" maxDate="2016-09-09"/>
<p *ngIf="field.errors?.maxDate">error message</p>
```

### dateISO

```html
Expand Down Expand Up @@ -178,6 +194,8 @@ export class AppModule {
- nn-NO
- vi-VN
- en-NZ
- hu-HU
- nl-NL

### uuid

Expand Down Expand Up @@ -205,14 +223,10 @@ export class AppModule {
### equalTo

```html
<form #demoForm="ngForm" novalidate>
<div ngModelGroup="passwordGroup" equalTo>
<input type="password" ngModel name="password" #password="ngModel" required/>
<p *ngIf="password?.errors?.required">required error</p>
<input type="password" ngModel name="certainPassword"/>
<p *ngIf="demoForm.form.controls.passwordGroup?.errors?.equalTo">equalTo error</p>
</div>
</form>
<input type="password" ngModel name="password" #password="ngModel" required/>
<p *ngIf="password.errors?.required">required error</p>
<input type="password" ngModel name="certainPassword" #certainPassword="ngModel" [equalTo]="password"/>
<p *ngIf="certainPassword.errors?.equalTo">equalTo error</p>
```

## model driven
Expand Down Expand Up @@ -316,6 +330,18 @@ new FormControl('', CustomValidators.email)
new FormControl('', CustomValidators.date)
```

### minDate

```javascript
new FormControl('', CustomValidators.minDate('2016-09-09'))
```

### maxDate

```javascript
new FormControl('', CustomValidators.maxDate('2016-09-09'))
```

### dateISO

```javascript
Expand Down Expand Up @@ -361,36 +387,21 @@ new FormControl('', CustomValidators.equal('xxx'))
### equalTo

```javascript
@Component({
selector: 'app',
template: require('./app.html')
})
export class AppComponent implements OnInit {
form: FormGroup;

ngOnInit() {
var password = new FormControl('', Validators.required);
var certainPassword = new FormControl('');

this.form = new FormGroup({
passwordGroup: new FormGroup({
password: password,
certainPassword: certainPassword
}, CustomValidators.equalTo)
});
}
}
let password = new FormControl('', Validators.required);
let certainPassword = new FormControl('', CustomValidators.equalTo(password));

this.form = new FormGroup({
password: password,
certainPassword: certainPassword
});
```

```html
<form [formGroup]="form" novalidate>
<div formGroupName="passwordGroup">
<input type="password" formControlName="password"/>
<p *ngIf="form.controls.passwordGroup.controls.password?.errors?.required">required error</p>
<input type="password" formControlName="certainPassword"/>
<p *ngIf="form.controls.passwordGroup?.errors?.equalTo">equalTo error</p>
</div>
<button>submit</button>
<form [formGroup]="form">
<input type="password" formControlName="password"/>
<p *ngIf="form.controls.password.errors?.required">required error</p>
<input type="password" formControlName="certainPassword"/>
<p *ngIf="form.controls.certainPassword.errors?.equalTo">equalTo error</p>
</form>
```

Expand Down
11 changes: 5 additions & 6 deletions example/src/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ import { CustomValidators } from '../../src';
})
export class AppComponent implements OnInit {
form: FormGroup;
num: number = 5;

ngOnInit() {
var password = new FormControl('', Validators.required);
var certainPassword = new FormControl('');
let password = new FormControl('', Validators.required);
let certainPassword = new FormControl('', CustomValidators.equalTo(password));

this.form = new FormGroup({
passwordGroup: new FormGroup({
password: password,
certainPassword: certainPassword
}, CustomValidators.equalTo)
password: password,
certainPassword: certainPassword
});
}

Expand Down
63 changes: 39 additions & 24 deletions example/src/app.html
Original file line number Diff line number Diff line change
@@ -1,50 +1,65 @@
<form #demoForm="ngForm" (ngSubmit)="onSubmit(demoForm)" novalidate>
<form #demoForm="ngForm" novalidate>
<!--<h4>rangeLength</h4>-->
<!--<input type="text" ngModel name="username" #username="ngModel" [rangeLength]="[5, 9]" />-->
<!--<input type="text" ngModel name="username" #username="ngModel" [rangeLength]="[5, 9]"/>-->
<!--<p *ngIf="username?.errors?.rangeLength">rangeLength error</p>-->

<!--<h4>min</h4>-->
<!--<input type="text" ngModel name="min" #min="ngModel" [min]="5" />-->
<!--<p *ngIf="min?.errors?.min">min error</p>-->
<h4>min</h4>
<input type="text" ngModel name="min" #min="ngModel" [min]="num"/>
<p *ngIf="min?.errors?.min">min error</p>

<!--<h4>max</h4>-->
<!--<input type="text" ngModel name="max" #max="ngModel" [max]="9" />-->
<!--<p *ngIf="max?.errors?.max">max error</p>-->
<h4>max</h4>
<input type="text" ngModel name="max" #max="ngModel" [max]="num"/>
<p *ngIf="max?.errors?.max">max error</p>

<h4>equal to "xxx"</h4>
<input type="text" ngModel name="equal" #equal="ngModel" [equal]="'' + num"/>
<p *ngIf="equal?.errors?.equal">equal error</p>

<h4>minDate</h4>
<input type="text" ngModel name="minDate" #minDate="ngModel" minDate="2016-09-09"/>
<p *ngIf="minDate?.errors?.minDate">minDate error</p>

<button (click)="num = 6">click {{num}}</button>

<!--<h4>range</h4>-->
<!--<input type="text" ngModel name="range" #range="ngModel" [range]="[5, 9]" />-->
<!--<input type="text" ngModel name="range" #range="ngModel" [range]="[5, 9]"/>-->
<!--<p *ngIf="range?.errors?.range">range error</p>-->

<!--<h4>creditCard</h4>-->
<!--<input type="text" ngModel name="creditCard" #creditCard="ngModel" creditCard />-->
<!--<input type="text" ngModel name="creditCard" #creditCard="ngModel" creditCard/>-->
<!--<p *ngIf="creditCard?.errors?.creditCard">creditCard error</p>-->

<!--<h4>JSON</h4>-->
<!--<input type="text" ngModel name="json" #json="ngModel" json />-->
<!--<input type="text" ngModel name="json" #json="ngModel" json/>-->
<!--<p *ngIf="json?.errors?.json">JSON error</p>-->

<!--<h4>base64</h4>-->
<!--<input type="text" ngModel name="base" #base="ngModel" base64 />-->
<!--<input type="text" ngModel name="base" #base="ngModel" base64/>-->
<!--<p *ngIf="base?.errors?.base64">base64 error</p>-->

<!--<h4>phone</h4>-->
<!--<input type="text" ngModel name="phone" #phone="ngModel" [phone]="'zh-CN'" />-->
<!--<input type="text" ngModel name="phone" #phone="ngModel" [phone]="'zh-CN'"/>-->
<!--<p *ngIf="phone?.errors?.phone">phone error</p>-->

<!--<h4>UUID</h4>-->
<!--<input type="text" ngModel name="uuid" #uuid="ngModel" [uuid]="4" />-->
<!--<input type="text" ngModel name="uuid" #uuid="ngModel" [uuid]="4"/>-->
<!--<p *ngIf="uuid?.errors?.uuid">UUID error</p>-->

<!--<h4>equal to "xxx"</h4>-->
<!--<input type="text" ngModel name="equal" #equal="ngModel" [equal]="'xxx'" />-->
<!--<input type="text" ngModel name="equal" #equal="ngModel" [equal]="'xxx'"/>-->
<!--<p *ngIf="equal?.errors?.equal">equal error</p>-->

<div ngModelGroup="passwordGroup" equalTo>
<h4>equalTo to password</h4>
<input type="password" ngModel name="password" #password="ngModel" required/>
<p *ngIf="password?.errors?.required">required error</p>
<input type="password" ngModel name="certainPassword"/>
<p *ngIf="demoForm.form.controls.passwordGroup?.errors?.equalTo">equalTo error</p>
</div>
<button>submit</button>
</form>
<!--<h4>equalTo to password</h4>-->
<!--<input type="password" ngModel name="password" #password="ngModel" required/>-->
<!--<p *ngIf="password?.errors?.required">required error</p>-->
<!--<input type="password" ngModel name="certainPassword" #certainPassword="ngModel" [equalTo]="password"/>-->
<!--<p *ngIf="certainPassword?.errors?.equalTo">equalTo error</p>-->

</form>

<!--<form [formGroup]="form">-->
<!--<input type="password" formControlName="password"/>-->
<!--<p *ngIf="form.controls.password.errors?.required">required error</p>-->
<!--<input type="password" formControlName="certainPassword"/>-->
<!--<p *ngIf="form.controls.certainPassword.errors?.equalTo">equalTo error</p>-->
<!--</form>-->
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ng2-validation",
"version": "2.1.0",
"version": "3.0.1",
"description": "angular2 validation",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
65 changes: 48 additions & 17 deletions src/custom-validators.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ValidatorFn, AbstractControl, Validators, FormGroup } from '@angular/forms';
import { ValidatorFn, AbstractControl, Validators } from '@angular/forms';

import { isPresent } from './lang';
import { isPresent, isDate } from './lang';

export class CustomValidators {
/**
Expand Down Expand Up @@ -101,6 +101,40 @@ export class CustomValidators {
return !/Invalid|NaN/.test(new Date(v).toString()) ? null : {'date': true};
}

/**
* Validator that requires controls to have a value of minDate.
*/
static minDate(minDate: any): ValidatorFn {
if (!isDate(minDate)) throw Error('minDate value must be a formatted date');

return (control: AbstractControl): {[key: string]: any} => {
if (isPresent(Validators.required(control))) return null;

let d: Date = new Date(control.value);

if (!isDate(d)) return {minDate: true};

return d >= new Date(minDate) ? null : {minDate: true};
};
}

/**
* Validator that requires controls to have a value of maxDate.
*/
static maxDate(maxDate: any): ValidatorFn {
if (!isDate(maxDate)) throw Error('maxDate value must be a formatted date');

return (control: AbstractControl): {[key: string]: any} => {
if (isPresent(Validators.required(control))) return null;

let d: Date = new Date(control.value);

if (!isDate(d)) return {maxDate: true};

return d <= new Date(maxDate) ? null : {maxDate: true};
};
}

/**
* Validator that requires controls to have a value of dateISO.
*/
Expand Down Expand Up @@ -255,22 +289,19 @@ export class CustomValidators {
/**
* Validator that requires controls to have a value to equal another control.
*/
static equalTo(group: AbstractControl): {[key: string]: any} {
if (!(group instanceof FormGroup)) return null;

let keys: string[] = Object.keys(group.controls);
let len: number = keys.length;

if (!len) return null;

let firstKey = keys[0];

for (let i = 1; i < len; i++) {
if (group.controls[firstKey].value !== group.controls[keys[i]].value) {
return {equalTo: true};
static equalTo(equalControl: AbstractControl): ValidatorFn {
let subscribe: boolean = false;
return (control: AbstractControl): {[key: string]: any} => {
if (!subscribe) {
subscribe = true;
equalControl.valueChanges.subscribe(() => {
control.updateValueAndValidity();
});
}
}

return null;
let v: string = control.value;

return equalControl.value === v ? null : {equalTo: true};
};
}
}
4 changes: 4 additions & 0 deletions src/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { NumberValidator } from './directives/number';
import { UrlValidator } from './directives/url';
import { EmailValidator } from './directives/email';
import { DateValidator } from './directives/date';
import { MinDateValidator } from './directives/min-date';
import { MaxDateValidator } from './directives/max-date';
import { DateISOValidator } from './directives/date-iso';
import { CreditCardValidator } from './directives/credit-card';
import { JSONValidator } from './directives/json';
Expand All @@ -28,6 +30,8 @@ export const CUSTOM_FORM_DIRECTIVES: Directive[] = [
UrlValidator,
EmailValidator,
DateValidator,
MinDateValidator,
MaxDateValidator,
DateISOValidator,
CreditCardValidator,
JSONValidator,
Expand Down
20 changes: 14 additions & 6 deletions src/directives/equal-to.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Directive, forwardRef } from '@angular/core';
import { NG_VALIDATORS, Validator, FormGroup, NgModelGroup } from '@angular/forms';
import { Directive, Input, forwardRef, OnInit } from '@angular/core';
import { NG_VALIDATORS, Validator, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

import { CustomValidators } from '../index';

Expand All @@ -10,11 +10,19 @@ const EQUAL_TO_VALIDATOR: any = {
};

@Directive({
selector: '[equalTo][ngModelGroup]',
selector: '[equalTo][formControlName],[equalTo][formControl],[equalTo][ngModel]',
providers: [EQUAL_TO_VALIDATOR]
})
export class EqualToValidator implements Validator {
validate(c: FormGroup): {[key: string]: any} {
return CustomValidators.equalTo(c);
export class EqualToValidator implements Validator, OnInit {
@Input() equalTo: FormControl;

private validator: ValidatorFn;

ngOnInit() {
this.validator = CustomValidators.equalTo(this.equalTo);
}

validate(c: AbstractControl): {[key: string]: any} {
return this.validator(c);
}
}
Loading

0 comments on commit 2e772ff

Please sign in to comment.