salix/front/core/directives/validation.js

81 lines
2.4 KiB
JavaScript

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('<span class="mdl-textfield__error"></span>');
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);