Provides directives for form validation (template or model driven) for many validation needs. Supports Angular 16 and higher.
This package follows semantic versioning. See changelog here.
Originally forked from ng2-validation.
npm i @davidda/ngx-custom-validators --save
- array length
- base64
- credit card
- date
- date ISO
- digits
- equal
- included in
- not included in
- not equal
- equal to
- not equal to
- greater than
- greater than or equal
- json
- less than
- less than or equal
- max
- max date
- min
- min date
- not equal
- not equal to
- number
- property
- range
- range length
- url
- uuid
The paramater of each validatiom error (if it has one) is accessible in the template with reason
.
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-gt]="10">
<!-- Will display : error message and must be greater than 10 -->
<p *ngIf="field.errors?.gt">error message and must be greater than {{ field.errors?.reason }}</p>
import FormsModule
and CustomFormsModule
in app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { CustomFormsModule } from '@davidda/ngx-custom-validators';
import { AppComponent } from './app.component';
@NgModule({
imports: [BrowserModule, FormsModule, CustomFormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}
Alternatively, you may import only the directives you need.
import { EmailValidator } from "@davidda/ngx-custom-validators";
@NgModule({
imports: [/*...*/, EmailValidator],
//...
})
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-rangeLength]="[5, 9]">
<p *ngIf="field.errors?.rangeLength">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-min]="10">
<p *ngIf="field.errors?.min">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-gt]="10">
<p *ngIf="field.errors?.gt">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-gte]="10">
<p *ngIf="field.errors?.gte">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-max]="20">
<p *ngIf="field.errors?.max">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-lt]="20">
<p *ngIf="field.errors?.lt">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-lte]="20">
<p *ngIf="field.errors?.lte">error message</p>
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-range]="[10, 20]">
<p *ngIf="field.errors?.range">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-digits>
<p *ngIf="field.errors?.digits">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-number>
<p *ngIf="field.errors?.number">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-url>
<p *ngIf="field.errors?.url">error message</p>
<!-- Optionally, configure the kind of URLs allowed. -->
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-url]="{require_protocol: true}">
See here for a list of options and their defaults.
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-email>
<p *ngIf="field.errors?.email">error message</p>
<!-- Optionally, configure the kind of emails allowed. -->
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-email]="{allow_display_name: true}">
See here for a list of options and their defaults.
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-date>
<p *ngIf="field.errors?.date">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-minDate="2016-09-09">
<p *ngIf="field.errors?.minDate">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-minDate]="myOtherField">
<p *ngIf="field.errors?.minDate">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-maxDate="2016-09-09">
<p *ngIf="field.errors?.maxDate">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-maxDate]="myOtherField">
<p *ngIf="field.errors?.maxDate">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-dateISO>
<p *ngIf="field.errors?.dateISO">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-creditCard>
<p *ngIf="field.errors?.creditCard">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-json>
<p *ngIf="field.errors?.json">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-base64>
<p *ngIf="field.errors?.base64">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-uuid="all">
<p *ngIf="field.errors?.uuid">error message</p>
default: all
support
- 3
- 4
- 5
- all
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-equal="xxx">
<p *ngIf="field.errors?.equal">error message</p>
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-notEqual="xxx">
<p *ngIf="field.errors?.notEqual">error message</p>
<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" [ngv-equalTo]="password">
<p *ngIf="certainPassword.errors?.equalTo">equalTo error</p>
<input type="text" ngModel name="password" #password="ngModel" required>
<p *ngIf="password.errors?.required">required error</p>
<input type="password" ngModel name="certainPassword" #certainPassword="ngModel" [ngv-notEqualTo]="password">
<p *ngIf="certainPassword.errors?.equalTo">equalTo error</p>
public obj = { id: 1 } // OK
public obj = { name: 'baguette' } // KO
<input type="text" ngModel name="obj" #obj="ngModel" ngv-property="id">
<!-- For multiple properties check -->
<input type="text" ngModel name="obj" #obj="ngModel" ngv-property="id,value,name">
<p *ngIf="obj.errors?.property">property error</p>
public arr = [{ name: 'baguette' }, { name: 'croisant' }] // OK
public arr = [{ name: 'baguette' }] // KO
<input type="text" ngModel name="arr" #arr="ngModel" ngv-arrayLength="2">
<p *ngIf="arr.errors?.arrayLength">arrayLength error</p>
import ReactiveFormsModule
in app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [BrowserModule, ReactiveFormsModule],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}
import CustomValidators
in app.component.ts
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { CustomValidators } from '@davidda/ngx-custom-validators';
@Component({
selector: 'app',
template: require('./app.html')
})
export class AppComponent {
form: FormGroup;
constructor() {
this.form = new FormGroup({
field: new FormControl('', CustomValidators.range([5, 9]))
});
}
}
<input type="text" formControlName="field">
<p *ngIf="demoForm.from.controls.field.errors?.rangeLength">error message</p>
new FormControl('', CustomValidators.rangeLength([5, 9]))
new FormControl('', CustomValidators.min(10))
new FormControl('', CustomValidators.gt(10))
new FormControl('', CustomValidators.max(20))
new FormControl('', CustomValidators.lt(20))
new FormControl('', CustomValidators.range([10, 20]))
new FormControl('', CustomValidators.digits)
new FormControl('', CustomValidators.number)
new FormControl('', CustomValidators.url)
new FormControl('', CustomValidators.email)
new FormControl('', CustomValidators.date)
new FormControl('', CustomValidators.minDate('2016-09-09'))
new FormControl('', CustomValidators.maxDate('2016-09-09'))
new FormControl('', CustomValidators.dateISO)
new FormControl('', CustomValidators.creditCard)
new FormControl('', CustomValidators.json)
new FormControl('', CustomValidators.base64)
new FormControl('', CustomValidators.uuid('3'))
new FormControl('', CustomValidators.equal('xxx'))
new FormControl('', CustomValidators.notEqual('xxx'))
let password = new FormControl('', Validators.required);
let certainPassword = new FormControl('', CustomValidators.equalTo(password));
this.form = new FormGroup({
password: password,
certainPassword: certainPassword
});
<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>
let password = new FormControl('', Validators.required);
let certainPassword = new FormControl('', CustomValidators.notEqualTo(password));
this.form = new FormGroup({
password: password,
certainPassword: certainPassword
});
<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?.notEqualTo">notEqualTo error</p>
</form>
public obj = { id: 1 };
this.form = new FormGroup({
obj: new FormControl('', CustomValidators.property('id'))
// For multiple properties check
obj: new FormControl('', CustomValidators.property('id,value,name'))
});
<form [formGroup]="form">
<input type="text" formControlName="obj">
<p *ngIf="form.controls.obj.errors?.property">property error</p>
</form>
public arr = [{ name: 'baguette' }, { name: 'croisant' }]
this.form = new FormGroup({
arr: new FormControl('', CustomValidators.arrayLength(2))
});
<form [formGroup]="form">
<input type="text" formControlName="arr">
<p *ngIf="arr.errors?.arrayLength">arrayLength error</p>
</form>
public arr = [{ name: 'baguette' }, { name: 'croisant' }]
this.form = new FormGroup({
arr: new FormControl('bread', CustomValidators.includedIn(arr))
});
<form [formGroup]="form">
<input type="text" formControlName="arr">
<p *ngIf="arr.errors?.includedIn">includedIn error</p>
</form>
public arr = [{ name: 'baguette' }, { name: 'croisant' }]
this.form = new FormGroup({
arr: new FormControl('baguette', CustomValidators.notIncludedIn(arr))
});
<form [formGroup]="form">
<input type="text" formControlName="arr">
<p *ngIf="arr.errors?.notIncludedIn">notIncludedIn error</p>
</form>
public pattern = /a+bc/
this.form = new FormGroup({
p: new FormControl('aabc', CustomValidators.notIncludedIn(pattern))
});
<form [formGroup]="form">
<input type="text" formControlName="p">
<p *ngIf="arr.errors?.notMatching">notMatching error</p>
</form>
To compile the projet : npx ng-packagr
Don't forget to run npm test
before each pull request. Thanks!