Example for stackoverflow. Server side validation
by Stepan Kasyanenko
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<ng-form name="myForm">
<input ng-model="user.firstName" name="firstName" required server-validation="'serverError'">
<div ng-messages="myForm.firstName.$error" class="error">
<div ng-message="required">firstName is required</div>
<div ng-message="serverError">firstName is server error</div>
</div>
<input ng-model="user.lastName" name="lastName" required server-validation="'serverError'">
<div ng-messages="myForm.lastName.$error" class="error">
<div ng-message="required">lastName is required</div>
<div ng-message="serverError">lastName is server error</div>
</div>
<input ng-model="user.email" name="email" required server-validation="['serverError','serverError2']">
<div ng-messages="myForm.email.$error" class="error" multiple="true">
<div ng-message="required">email is required</div>
<div ng-message="serverError">email is server error</div>
<div ng-message="serverError2">email is server error 2</div>
</div>
<input ng-disabled="myForm.$invalid" ng-click="doSubmit(myForm)" type="submit">
</ng-form>
</div>
</div>
CSS
.error {
color: red;
font-style: italic;
}
JavaScript
angular.module('ExampleApp', ['ngMessages'])
.controller('ExampleController', function($scope, ServerService) {
$scope.user = {};
$scope.doSubmit = function(myForm) {
ServerService.save().then(function(errors) {
// Set error from server on our form
angular.forEach(errors, function(error) {
myForm[error.fieldName].$setValidity(error.error, false);
});
});
};
})
//Simulate Ajax call
.service('ServerService', function($q, $timeout) {
var errorsFromServer = [{
fieldName: "firstName",
error: "serverError"
}, {
fieldName: "lastName",
error: "serverError"
}, {
fieldName: "email",
error: "serverError"
}, {
fieldName: "email",
error: "serverError2"
}];
return {
save: function() {
return $q.when(errorsFromServer);
}
};
})
.directive('serverValidation', function() {
return {
restrict: "A",
require: "ngModel",
scope: {
ngModel: "=",
serverValidation: "=" // String or array of strings with name of errors
},
link: function(scope, elem, attr, ngModelCtrl) {
function setValidity(errorName) {
console.log(errorName);
ngModelCtrl.$setValidity(errorName, true);
}
if (typeof(scope.serverValidation) == "string") {
console.log(scope.serverValidation);
scope.arrServerValidation = [scope.serverValidation];
} else {
scope.arrServerValidation = scope.serverValidation;
}
var firstError = scope.arrServerValidation[0];
scope.$watch('ngModel', function() {
// workaround to don't update $setValidity, then changed value of ngModel
// update $setValidity, only when server-error is true
if (firstError && ngModelCtrl.$error[firstError])
angular.forEach(scope.arrServerValidation, setValidity);
});
},
};
});