import ngModule from '../module'; import {validateAll} from '../lib/validator'; import {firstUpper} from '../lib/string'; directive.$inject = ['$interpolate', '$compile', '$translate', '$window']; export function directive(interpolate, compile, $translate, $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 ngModel = ctrl[0]; let form = ctrl[1]; let errorSpan = angular.element(''); let errorMsg; let errorShown = false; ngModel.$options.$$options.allowInvalid = true; ngModel.$validators.entity = value => { try { validateAll($translate, value, validations); return true; } catch (e) { errorMsg = e.message; if (errorShown) changeError(); return false; } }; scope.$watch(() => { return (form.$submitted || ngModel.$dirty) && ngModel.$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); } } } ngModule.directive('vnValidation', directive);