import {module} from '../module'; import {validateAll} from '../lib/validator'; import {firstUpper} from '../lib/string'; directive.$inject = ['$interpolate', '$compile', '$window']; export function directive(interpolate, compile, $window) { return { restrict: 'A', require: ['ngModel', '?^^form'], link: link }; function link(scope, element, attrs, ctrl) { let vnValidations = $window.validations; if (!attrs.vnValidation || !vnValidations) return; let split = attrs.vnValidation.split('.'); if (split.length !== 2) throw new Error(`vnValidation: Attribute must have this syntax: [entity].[field]`); let entityName = firstUpper(split[0]); let fieldName = split[1]; let entity = vnValidations[entityName]; if (!entity) throw new Error(`vnValidation: Entity '${entityName}' doesn't exist`); let validations = entity.validations[fieldName]; if (!validations || validations.length == 0) return; let input = ctrl[0]; let form = ctrl[1]; let errorSpan = angular.element(''); let errorMsg; let errorShown = false; input.$options.$$options.allowInvalid = true; input.$validators.entity = value => { try { validateAll(value, validations); return true; } catch (e) { errorMsg = e.message; if (errorShown) changeError(); return false; } }; scope.$watch(() => { return (form.$submitted || input.$dirty) && input.$invalid; }, value => { let parent = element.parent(); if (value) { changeError(); parent.addClass('invalid'); element.after(errorSpan); } else if (errorShown) { parent.removeClass('invalid'); parent.removeAttr('title'); errorSpan.remove(); errorSpan.empty(); } errorShown = value; }); function changeError() { let parent = element.parent(); errorSpan.text(errorMsg); parent.attr('title', errorMsg); } } } module.directive('vnValidation', directive);