Reputation: 1728
I have some doubts about AngularJS + Custom Validations, from what I have read and checked by myself:
My doubts come when we have custom business validations that impact on more than one filed. Let's check the following simple scenario:
The business validations that I want to apply is: comments fields is required only if status fields value is "Delayed".
The way I have implemented it:
This directive delegates the business validation into a service
The benefits I think this approach is giving to me are:
My business service validation gets isolated.
I could easily add unit testing to that business validation.
I could reuse it and it doesn't depend on UI elements.
I have compiled this sample in a JSFiddle (JSFiddle validation sample).
JS:
function MyCtrl($scope) {
$scope.arrival = {
"id": 1,
"originAirport": "Malaga (AGP)",
"flightNumber": "Iberia 132",
"dueAt": "2013-05-26T12:10:10",
"status": 2,
"info": "test"
}
}
myApp.directive('validateinfofield', ['formArrivalValidation', function (formArrivalValidation) {
return {
require: "ngModel",
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue){
// Empty? Let's check status
//if (!viewValue.length && scope.arrival.status == 3) {
if(formArrivalValidation.validateInfoField(scope.arrival.status, viewValue)) {
ctrl.$setValidity('validInfo', true);
} else {
ctrl.$setValidity('validInfo', false);
}
});
// Let's add a watch to arrival.status if the values change we need to
// reevaluate, if comments is empty and status is delayes display error
scope.$watch('arrival.status', function (newValue, oldValue) {
if (formArrivalValidation.validateInfoField(newValue, scope.editArrivalForm.txInfo.$viewValue)) {
ctrl.$setValidity('validInfo', true);
} else {
ctrl.$setValidity('validInfo', false);
}
});
}
};
}]);
// Validation Service, limited to our "business language"
myApp.factory('formArrivalValidation',
function () {
return {
validateInfoField: function (status, infoField) {
var isOk = true;
if (status == 3) {
if (infoField == undefined) {
isOk = false;
} else {
if (!infoField.length)
isOk = false;
}
}
return isOk;
},
};
});
Is this a good approach to follow? Is there better and simpler way to achieve this?
Upvotes: 1
Views: 2330
Reputation: 1728
Coming back to this question... one valid approach could be to write a directive that accepts as parameter a second value (e.g. comments is empty)
Upvotes: 0
Reputation: 178
Regarding this part - "The business validations that I want to apply is: comments fields is required only if status fields value is "Delayed". for comment field set ng-required="flight.status == 'DELAYED'"
Upvotes: 2