angular.module('schemaForm').directive('schemaValidate', ['sfValidator', function(sfValidator) {
return {
restrict: 'A',
scope: false,
// We want the link function to be *after* the input directives link function so we get access
// the parsed value, ex. a number instead of a string
priority: 1000,
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
//Since we have scope false this is the same scope
//as the decorator
scope.ngModel = ngModel;
var error = null;
var getForm = function() {
if (!form) {
form = scope.$eval(attrs.schemaValidate);
}
return form;
};
var form = getForm();
// Validate against the schema.
// Get in last of the parses so the parsed value has the correct type.
Eif (ngModel.$validators) { // Angular 1.3
ngModel.$validators.schema = function(value) {
var result = sfValidator.validate(getForm(), value);
error = result.error;
return result.valid;
};
} else {
// Angular 1.2
ngModel.$parsers.push(function(viewValue) {
form = getForm();
//Still might be undefined
if (!form) {
return viewValue;
}
var result = sfValidator.validate(form, viewValue);
if (result.valid) {
// it is valid
ngModel.$setValidity('schema', true);
return viewValue;
} else {
// it is invalid, return undefined (no model update)
ngModel.$setValidity('schema', false);
error = result.error;
return undefined;
}
});
}
// Listen to an event so we can validate the input on request
scope.$on('schemaFormValidate', function() {
if (ngModel.$validate) {
ngModel.$validate();
if (ngModel.$invalid) { // The field must be made dirty so the error message is displayed
ngModel.$dirty = true;
ngModel.$pristine = false;
}
} else {
ngModel.$setViewValue(ngModel.$viewValue);
}
});
//This works since we now we're inside a decorator and that this is the decorators scope.
//If $pristine and empty don't show success (even if it's valid)
scope.hasSuccess = function() {
return ngModel.$valid && (!ngModel.$pristine || !ngModel.$isEmpty(ngModel.$modelValue));
};
scope.hasError = function() {
return ngModel.$invalid && !ngModel.$pristine;
};
scope.schemaError = function() {
return error;
};
}
};
}]);
|