salix/front/core/directives/rule.js

72 lines
2.2 KiB
JavaScript

import ngModule from '../module';
import {validateAll} from '../lib/validator';
import {firstUpper} from '../lib/string';
directive.$inject = ['$translate', '$window'];
export function directive($translate, $window) {
return {
restrict: 'A',
link: link,
require: {
ngModel: 'ngModel',
form: '^^?form'
}
};
function link($scope, $element, $attrs, $ctrl) {
let vnValidations = $window.validations;
if (!vnValidations) return;
if (!/^([A-Z]\w+(\.[a-z]\w*)?)?$/.test($attrs.rule))
throw new Error(`rule: Attribute must have this syntax: [ModelName[.fieldName]]`);
let rule = $attrs.rule.split('.');
let modelName = rule.shift();
let fieldName = rule.shift();
let split = $attrs.ngModel.split('.');
if (!fieldName) fieldName = split.pop() || null;
if (!modelName) modelName = firstUpper(split.pop() || '');
if (!modelName || !fieldName)
throw new Error(`rule: Cannot retrieve model or field attribute`);
let modelValidations = vnValidations[modelName];
if (!modelValidations)
throw new Error(`rule: Model '${modelName}' doesn't exist`);
let validations = modelValidations.validations[fieldName];
if (!validations || validations.length == 0)
return;
let ngModel = $ctrl.ngModel;
let form = $ctrl.form;
let field = $element[0].$ctrl;
let error;
function refreshError() {
if (!field) return;
let canShow = ngModel.$dirty || (form && form.$submitted);
field.error = error && canShow ? error.message : null;
}
ngModel.$options.$$options.allowInvalid = true;
ngModel.$validators.entity = value => {
try {
error = null;
validateAll($translate, value, validations);
} catch (e) {
error = e;
}
refreshError();
return error == null;
};
if (form)
$scope.$watch(() => form.$submitted, refreshError);
}
}
ngModule.directive('rule', directive);