Comments (4)
I have used this module in AngularJS and it works awesome and I have used more than 10 projects.
I have now requirement for Angular5 implementation so I was think to use this module. What is the best way to use it? Alternatively I'm thinking to go ng2-validation package. But I love this module.
from angular-auto-validate.
@saheel-ahmed I haven't got around to porting this to angular 5 yet. However, it is pretty easy to do with a directive and using the mat-error element from angular material. Basic code is below. If I get some time I might try and port this over. Contribution are welcome!
export abstract class ValidationDecoratorDirectiveBase implements Validator, OnChanges, OnDestroy, OnInit {
@Input()
public ngModel: any;
@Input()
public errorContainerId: string; // the id of the mat-error element
@Input()
public preValidate: boolean = false;
@Input()
public getValidationErrorMessage: (errors: ValidationErrors) => string;
@Input()
public scrollIntoViewWhenInvalid: boolean = false;
private statusChangeSubscription: Subscription;
public constructor(protected parentForm: NgForm,
protected ngControl: NgControl,
protected element: ElementRef,
protected renderer: Renderer2,
protected utilService: UtilService,
protected validationMessageService: ValidationMessageService) {}
@HostListener("blur")
public onElementBlurred(markAsTouched: boolean = false): void {
if (document.activeElement !== this.element.nativeElement) {
if (this.canMarkInValid()) {
this.markAsTouched();
const primaryErrorKey = this.getFirstErrorKey(this.ngControl.errors);
const remoteErrors = this.getRemoteErrors(this.ngControl.errors);
let errorMessage = this.element.nativeElement.validationMessage ||
this.validationMessageService.getErrorMessage(primaryErrorKey,
this.ngControl.errors[primaryErrorKey] ?
this.ngControl.errors[primaryErrorKey].data ||
this.ngControl.errors[primaryErrorKey] :
undefined);
if (remoteErrors.length > 0) {
errorMessage = remoteErrors[0].message;
}
if (this.getValidationErrorMessage !== undefined) {
errorMessage = this.getValidationErrorMessage(this.ngControl.errors) || errorMessage;
}
setTimeout(() => {
const el = this.getErrorElement();
this.makeInvalid(el, errorMessage);
if (this.scrollIntoViewWhenInvalid && el.scrollIntoView) {
el.scrollIntoView();
}
}, 100);
} else if (this.canMarkValid()) {
setTimeout(() => {
this.markAsTouched();
this.makeValid();
}, 100);
}
}
}
public markAsTouched(): void {
const formControl = this.parentForm.controls[this.ngControl.name] ||
this.parentForm.controls[this.errorContainerId];
if (!this.ngControl.touched && formControl) {
formControl.markAsTouched();
}
}
public ngOnInit(): void {
this.statusChangeSubscription = this.ngControl
.statusChanges
.subscribe((status) => {
if (status === "INVALID") {
this.onFormSubmitHandler(false);
} else if (status === "VALID") {
setTimeout(() => this.makeValid(), 100);
}
});
this.parentForm.ngSubmit.subscribe((evt) => {
this.onFormSubmitHandler(true);
});
}
public ngOnChanges(changes: SimpleChanges): void {
let change = changes.ngModel;
if (!this.utilService.isNullOrUndefined(change) &&
this.utilService.isNullOrUndefined(change.previousValue) &&
!this.utilService.isNullOrUndefinedOrEmpty(change.currentValue)) {
setTimeout(() => this.onElementBlurred(true), 100);
}
}
public validate(control: AbstractControl): ValidationErrors|null {
return null;
}
public ngOnDestroy(): void {
if (this.statusChangeSubscription) {
this.statusChangeSubscription.unsubscribe();
}
}
// tslint:disable-next-line:no-empty
public registerOnValidatorChange(fn: () => void): void {}
protected canMarkInValid(): boolean {
let canValidate = false;
const controlValue = this.ngControl.value;
const isTouched = this.ngControl.touched;
if (this.ngControl.invalid) {
canValidate = isTouched || !this.utilService.isNullOrUndefinedOrEmpty(controlValue) ||
(this.preValidate);
}
return canValidate;
}
protected canMarkValid(): boolean {
let canValidate = false;
const controlValue = this.ngControl.value;
const isTouched = this.ngControl.touched;
if (this.ngControl.valid) {
canValidate = (isTouched && !this.utilService.isNullOrUndefinedOrEmpty(controlValue)) ||
(this.preValidate && !this.utilService.isNullOrUndefinedOrEmpty(controlValue));
}
return canValidate;
}
protected getErrorElement(): HTMLElement {
return document.getElementById(this.errorContainerId);
}
protected abstract makeInvalid(errorElement: HTMLElement, errorMessage: string): void;
protected abstract makeValid(): void;
private onFormSubmitHandler(markAsTouched = false): void {
if (this.ngControl.invalid) {
if (markAsTouched) {
this.markAsTouched();
}
this.onElementBlurred(markAsTouched);
}
}
private getRemoteErrors(errors: ValidationErrors): IRemoteValidationError[] {
let remoteErrors: IRemoteValidationError[] = new Array<IRemoteValidationError>();
for (let key in errors) {
if (errors.hasOwnProperty(key) && errors[key].remote === true) {
remoteErrors.push({ propertyName: errors[key].propertyName, message: errors[key].message, level: 1 });
}
}
return remoteErrors;
}
private getFirstErrorKey(errors: ValidationErrors): string {
const properties = Object.keys(errors).sort();
return properties[0];
}
}
// tslint:disable-next-line:max-classes-per-file
@Directive({
selector: "[inputValidationDecorator]"
})
export class InputValidationDecoratorDirective extends ValidationDecoratorDirectiveBase {
public constructor(@Host() parentForm: NgForm,
@Host() private parentContainer: MatFormField,
ngControl: NgControl,
element: ElementRef,
renderer: Renderer2,
utilService: UtilService,
validationMessageService: ValidationMessageService) {
super(parentForm, ngControl, element, renderer, utilService, validationMessageService);
}
protected makeInvalid(errorElement: HTMLElement, errorMessage: string): void {
if (!this.utilService.isNullOrUndefined(errorElement)) {
errorElement.innerText = errorMessage;
}
}
protected makeValid(): void {
if (this.ngControl.touched) {
this.renderer.addClass(this.parentContainer._elementRef.nativeElement, "mat-focused");
}
}
}
You would then use it like this:
<mat-form-field>
<input name="EmailAddress"
type="email"
placeholder="Email Address (optional)"
[(ngModel)]="worker.emailAddress"
matInput
minLength="1"
inputValidationDecorator errorContainerId="mdErrorEmail" [preValidate]="inEditMode">
<mat-error id="mdErrorEmail"></mat-error>
</mat-form-field>
I hope this helps
Thanks,
Jon
from angular-auto-validate.
Awesome 👍
Thank you, Jon. As I was using Bootstrap 4 with Angular 5, and this "inputValidationDecorator " concept should work.
from angular-auto-validate.
Inspired by your AngularJS version and using the above code as a starting point I created an couple of Angular directives that work well together to standardise and simplify form validation. They are built to work in the ASP.NET Zero Framework but could easily be adapted for general use. You'd need to implement the localizationservice yourself as it is something that's built into the framework.
See https://github.com/gconey/aspnet-zero-core-auto-validate
from angular-auto-validate.
Related Issues (20)
- package.json has incorrect main attribute HOT 3
- angular-auto-validate with bower
- Is there any way to display more than one error message?
- Validation not working with material md-select
- After submit data remoove styling HOT 1
- Update npm registry HOT 3
- conflict with sb-admin admin template HOT 2
- Failed when using an angular expression in ng-pattern
- min and max error description wrong i18n es-co
- Prevent validating ng-hide elements
- Value {0} replace dont work when use myCustomErrorMessageResolver HOT 1
- Passing a parameter from a Custom Validator directive to errorMessages doesn't work unless you make errorMessages dash-case. HOT 1
- cannot validate ng-form or sections in a form
- Show server side errors using this package
- Validate when state redirection
- custom error message (help)
- auto validate for other plugins
- autovalidate intefering with ngRequired directive
- request/potential bug: allow validation when on $touched instead of on $dirty HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular-auto-validate.