UNPKG

@seges/angular-validators

Version:

TypeScript 1.8.10

110 lines (98 loc) 3.89 kB
import { IValidator } from "./IValidator"; export class AngularValidationDirective<TValidator extends IValidator<TDependencies>, TDependencies> { validator: IValidator<TDependencies>; /** * Angular validation wrapper. * Set angular specific setup to use custom validation directive. * * Example usage: * const validator = new AngularValidationDirective(CustomValidator); * angular * .module(moduleName, []) * .directive("isCustomValid", validator.factory); * * @param validator The validator class implementing IValidator. * @param directiveName The directive name in pascal casing. */ constructor(validator: { new (): TValidator; }, private directiveName: string) { if (!validator) { throw Error("Angular validation directive is dependent on IValidator implementation."); } if (!directiveName) { throw Error("Angular validation directive must have a directive name"); } this.validator = new validator(); } /** * Link method for Angular directive. Called after the view is loaded. */ link = (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ngModel: ng.INgModelController) => { this.initNgModel(ngModel, (value: string) => this.validateInput(value, ngModel, attrs)); attrs.$observe(this.directiveName, () => { this.validateInput(ngModel.$viewValue, ngModel, attrs); }); } /** * Validate value against validator. * @param value The value to validate. */ validateInput = (value: string, ngModel: ng.INgModelController, attrs: ng.IAttributes): string => { if (!value) { this.setValidity(true, ngModel); return value; } if (this.validator.isValid(value, attrs)) { this.setValidity(true, ngModel); return value; } this.setValidity(false, ngModel); return value; } /** * Factory method to register directive with Angular. * * Example: * const integerValidatorName = "isInteger"; * const integerValidator = new AngularValidationDirective(IntegerValidator, integerValidatorName); * module.directive(integerValidatorName, () => integerValidator.factory()); * * If validator has dependencies, they can be injected from Angular like this: * const dateValidValidatorName = "dateFormat"; * const dateValidValidator = new AngularValidationDirective<DateValidator, IDateValidatorDeps>( * DateValidator, * dateValidValidatorName * ); * module.directive(dateValidValidatorName, * (moment: moment.MomentStatic, dateFormat: string) => dateValidValidator.factory({ * moment, * dateFormat, * }) * ); * * @param dependencies Optional dependency object to set on validator. */ factory(dependencies?: TDependencies): ng.IDirective { if (this.validator.setDependencies && dependencies) { this.validator.setDependencies(dependencies); } return { link: this.link, require: "ngModel", scope: false, }; } /** * Set ngModel validity. * @param isValid The validity. */ setValidity = (isValid: boolean, ngModel: ng.INgModelController): void => { ngModel.$setValidity(this.directiveName, isValid); } /** * Initialize ngModel with validator. */ private initNgModel = (ngModel: ng.INgModelController, validatorMethod: ng.IModelParser): void => { ngModel.$parsers.unshift(validatorMethod); ngModel.$formatters.push(validatorMethod); } }