Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Angular Form Group Directive and Form Errors Service (sets validities depending on server response)
/**
* Handles form errors from server.
*/
app.factory('formErrors', function () {
return {
/**
* Creates $error.errorKey (String) and sets validity
* for every failing model validation received from the server.
* E.g. 'form.message.$error.errorKey' can be accessed in the view.
* @param {Object} form
* @param {Object} errors, formatted like this: [{"subject":["required"],"text":["required"]}]}
*/
handle: function (form, errors) {
if(angular.isUndefined(errors) || angular.isUndefined(form)) {return;}
this.clean(form);
angular.forEach(errors, function(error) {
angular.forEach(error, function(errorKeys, inputName) {
angular.forEach(errorKeys, function(errorKey) {
form[inputName].$setValidity(errorKey, false);
form[inputName].$setPristine();
});
});
});
},
/**
* Cleans form errors by setting validity of every input to true
* @param {Object} form
*/
clean: function(form) {
if(angular.isUndefined(form)) {return;}
angular.forEach(form, function(input) {
if(!input) { return; }
angular.forEach(input.$error, function(invalid, errorKey) {
if(invalid) {
input.$setValidity(errorKey, true);
}
});
});
}
};
});
/**
* Form group directive for handling input errors. ($touched is the new $dirty)
* 'input' needs to be the name of the input.
* @example
* <form-group input="email">
* <input type="email" class="form-control" required autofocus name="email" ng-model="user.email" />
* </form-group>
*/
app.directive('formGroup', function () {
return {
restrict: 'E',
require: '^form',
transclude: true,
replace: true,
scope: {
cssClass: '@class',
input: '@'
},
template: '<div class="form-group" ng-class="{\'has-error\':hasError, cssClass:true}">'+
'<div ng-transclude></div>' +
'<div ng-if="hasError">' +
'<span ng-repeat="(key,error) in form[input].$error" class="help-block" '+
'ng-if="error" translate="form.invalid.{{key}}">' +
'</span>' +
'</div>' +
'</div>',
link: function (scope, element, attrs, ctrl) {
scope.form = ctrl;
var input = scope.form.$name + '.' + scope.input;
scope.$parent.$watch(input+'.$invalid && '+input+'.$touched', function (hasError) {
scope.hasError = hasError;
});
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.