@davidda/ngx-custom-validators
v13.0.0
Published
Angular custom directives for validation
Downloads
146
Maintainers
Readme
Description
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.
Installation
npm i @davidda/ngx-custom-validators --save
Provided validators
- 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
Usage
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" [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>
Template driven
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],
//...
})
range length - rangeLength
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-rangeLength]="[5, 9]">
<p *ngIf="field.errors?.rangeLength">error message</p>
min
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-min]="10">
<p *ngIf="field.errors?.min">error message</p>
greater than - gt
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-gt]="10">
<p *ngIf="field.errors?.gt">error message</p>
greater than or equal - gte
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-gte]="10">
<p *ngIf="field.errors?.gte">error message</p>
max
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-max]="20">
<p *ngIf="field.errors?.max">error message</p>
less than - lt
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-lt]="20">
<p *ngIf="field.errors?.lt">error message</p>
less than or equal - lte
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-lte]="20">
<p *ngIf="field.errors?.lte">error message</p>
range
<input type="number" [(ngModel)]="model.field" name="field" #field="ngModel" [ngv-range]="[10, 20]">
<p *ngIf="field.errors?.range">error message</p>
digits
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-digits>
<p *ngIf="field.errors?.digits">error message</p>
number
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-number>
<p *ngIf="field.errors?.number">error message</p>
url
<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.
date
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-date>
<p *ngIf="field.errors?.date">error message</p>
min date - minDate
<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>
max date - maxDate
<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>
date ISO - dateISO
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-dateISO>
<p *ngIf="field.errors?.dateISO">error message</p>
credit card - creditCard
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-creditCard>
<p *ngIf="field.errors?.creditCard">error message</p>
json
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-json>
<p *ngIf="field.errors?.json">error message</p>
base64
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-base64>
<p *ngIf="field.errors?.base64">error message</p>
uuid
<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
equal
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-equal="xxx">
<p *ngIf="field.errors?.equal">error message</p>
not equal - notEqual
<input type="text" [(ngModel)]="model.field" name="field" #field="ngModel" ngv-notEqual="xxx">
<p *ngIf="field.errors?.notEqual">error message</p>
equal to - equalTo
<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>
not equal to - notEqualTo
<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>
property
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>
array length - ArrayLength
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>
Model driven
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>
range length - rangeLenght
new FormControl('', CustomValidators.rangeLength([5, 9]))
min
new FormControl('', CustomValidators.min(10))
greater than - gt
new FormControl('', CustomValidators.gt(10))
max
new FormControl('', CustomValidators.max(20))
less than - lt
new FormControl('', CustomValidators.lt(20))
range
new FormControl('', CustomValidators.range([10, 20]))
digits
new FormControl('', CustomValidators.digits)
number
new FormControl('', CustomValidators.number)
url
new FormControl('', CustomValidators.url)
new FormControl('', CustomValidators.email)
date
new FormControl('', CustomValidators.date)
min date - minDate
new FormControl('', CustomValidators.minDate('2016-09-09'))
max date - maxDate
new FormControl('', CustomValidators.maxDate('2016-09-09'))
date ISO - dateISO
new FormControl('', CustomValidators.dateISO)
credit card - creditCard
new FormControl('', CustomValidators.creditCard)
json
new FormControl('', CustomValidators.json)
base64
new FormControl('', CustomValidators.base64)
uuid
new FormControl('', CustomValidators.uuid('3'))
equal
new FormControl('', CustomValidators.equal('xxx'))
not equal - notEqual
new FormControl('', CustomValidators.notEqual('xxx'))
equal to - equalTo
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>
not equal to - notEqualTo
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>
property
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>
array length - ArrayLength
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>
included in array - includedIn
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>
not included in array - notIncludedIn
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>
not matching a regular expression - notMatching (negate pattern)
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>
For developpers
To compile the projet : npx ng-packagr
Don't forget to run npm test
before each pull request. Thanks!