A collection of classes to help handling display error messages on your form. PLEASE REFER TO THE DEPRECATED BRANCH THIS IS THE README OF THE v2.0 THAT IS ON CONSTRUCTION
- Demo
- Reason
- Installation
- Usage
- Validators
- Customizing
- Integration with other packages
- Development
- TODO
https://ouracademy.github.io/ng2-validation/
Tired to always write this in your angular 2 app:
<label for="name">Name</label>
<input type="text" id="name" class="form-control"
required minlength="4" maxlength="24"
name="name" [(ngModel)]="hero.name"
#name="ngModel" >
<div *ngIf="name.errors && (name.dirty || name.touched)"
class="alert alert-danger">
<div [hidden]="!name.errors.required">
Name is required
</div>
<div [hidden]="!name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div [hidden]="!name.errors.maxlength">
Name cannot be more than 24 characters long.
</div>
</div>
And repeat this to every field in every form in every view. This package deals with it, using a uniform approach to make validation messages based on the amazing Laravel framework. So you can instead do this:
<label for="name">Name</label>
<input type="text" id="name" class="form-control"
required minlength="4" maxlength="24"
name="name" [(ngModel)]="hero.name"
#name="ngModel" >
<div *ngIf="errors.name" class="alert alert-danger">
{{ errors.name }}
</div>
And it will do the same in very uniform way in all your fields in every forms in all your views. This package will create validation messages for you. It contains predefined validation messages, but you can customize it (see customizing).
Install the npm module by running:
npm install ng2-custom-validation --save
Add to your systemjs.config.js
map: {
// other stuff...
'ng2-custom-validation': 'node_modules/ng2-custom-validation/bundles/ng2-custom-validation.umd.js'
},
packages: {
// other stuf...
'ng2-custom-validation': {
defaultExtension: 'js'
}
}
The steps here are very similar to the ngx-translate package, because it's based on it. Alternative you can see the demo app to have a more detail of the usage.
The forRoot
static method is a convention that provides and configures services at the same time.
Make sure you only call this method in the root module of your application, most of the time called AppModule
.
This method allows you to configure the ValidationMessagesModule
by specifying a loader, a parser and/or a missing validation messages handler, as it's described in customizing.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { ValidationMessagesModule } from 'ng2-custom-validation';
@NgModule({
imports: [
BrowserModule,
HttpModule,
HeroFormReactiveModule,
ValidationMessagesModule.forRoot()
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
If you use a SharedModule
that you import in multiple other feature modules,
you can export the ValidationMessagesModule
to make sure you don't have to import it in every module.
@NgModule({
exports: [BrowserModule, HttpModule, ValidationMessagesModule],
})
export class SharedModule {
}
Note: Never call a
forRoot
static method in theSharedModule
. You might end up with different instances of the service in your injector tree.
TODO
TODO
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MessageBag, ValidationMessagesService } from 'ng2-custom-validation';
@Component({
moduleId: module.id,
selector: 'hero-form-reactive3',
templateUrl: 'hero-form.component.html'
})
export class HeroFormReactiveComponent implements OnInit {
errors: MessageBag = new MessageBag();
heroForm: FormGroup;
constructor(private fb: FormBuilder, private validationMessages: ValidationMessagesService) { }
ngOnInit(): void {
this.buildForm();
}
buildForm(): void {
this.heroForm = this.fb.group({
'name': ['', [
Validators.required,
Validators.minLength(4),
Validators.maxLength(24)
]]
});
this.validationMessages
.from(this.heroForm)
.subscribe((errors: MessageBag) => {
this.errors = errors;
});
// or using observables ($errors must be of type Observable<MessageBag>)
// this.$errors = this.validationMessages.from(this.heroForm);
}
<label for="name">Name</label>
<input id="name" type="text" class="form-control" required formControlName="name">
<div *ngIf="errors.name" class="alert alert-danger">
{{ errors.name }}
</div>
<!-- Using observables you should use the async pipe
<div *ngIf="(errors| async)?.name" class="alert alert-danger">
{{ (errors| async)?.name }}
</div>
-->
This is the list of the supported validations
- required
- minlength
- maxlength
- pattern
You can customize the predefined messages (instead of the predefined message for the required Validator: "The {{attribute}} field is required", get "Please, fill the {{attribute}}", change the display name of an attribute - like instead of "email" display "email address"), the parser (instead of define the display value of an attribute with "{{attribute}}" use ":attribute" - if you prefer the Laravel style) or change the missing validation message handler.
There are two ways of customizing the validationMessages: extending the default validation messages or providing your own loader. In the demo there are an example of using both ways.
Create your file of custom validation messages (for example custom-validation
)
import { defaultValidationMessages } from '../src';
// An example of overriding the name field to super name
//do the same with any validation message (min, required...)
defaultValidationMessages.customAttributes = {
'name': 'super name'
};
And import it in your NgModule(for example the RootComponent):
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
//...import other modules
import { ValidationMessagesModule } from 'ng2-custom-validation';
import './custom-validation';
@NgModule({
imports: [
//your modules
ValidationMessagesModule.forRoot()
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
If you want to write your own loader, you need to create a class that implements ValidationMessagesLoader. The only required method is load() that must return an Observable. If your loader is synchronous, just use Observable.of to create an observable from your static value.
class CustomLoader implements ValidationMessagesLoader {
load(): Observable<any> {
//Your own implementation...maybe like the HttpLoader of the ngx-translate/http-loader package
}
}
Once you've defined your loader, you can provide it in your NgModule by passing it in the loader
parameter of the forRoot
configuration . Don't forget that you have to import ValidationMessagesModule as well:
@NgModule({
imports: [
// other imports..
//construct with your params
ValidationMessagesModule.forRoot({ loader: {provide: ValidationMessagesLoader, useClass: CustomLoader }})
],
exports: [ValidationMessagesModule],
})
export class SharedModule {
}
The steps here are similar to the section Write and use your own loader, with the difference of passing your custom parser to the parser
parameter of the forRoot
configuration and of course defining all the predefined messages (because the predefined messages are understood by this package by using the predefined parser).
The steps here are similar to the section Write and use your own loader.
This package will work with the ngx-translate package, by using the HttpTranslateLoader.
- Install Node.js and NPM (should come with)
- Install local dev dependencies:
npm install
while current directory is this repo
Run npm start
to start a development server on port 8000 with auto reload + tests.
Run npm test
to run tests once or npm run test:watch
to continually run tests.
- Bump the version in package.json (once the module hits 1.0 this will become automatic)
npm run release
This package it's creating on free times after university...and theses... For now works with Reactive Driven Forms, it wasn't tested with Template Driven Forms. Probably it will work, if work send us a message. Also it doesn't work with Composite Form Groups (and unique Controls) and doesn't have a way to add more ErrorPlaceholderParser (this is if you create your own Validator, you can't add it to the validation messages to show..this will be fixed soon).
There's a list of things that are in our roadmap. You can see it in the TODO file