Reputation: 9587
I'm trying to set up a form validation systems with angular as follows.
An error class is assigned when the field is both $invalid && $dirty.
This works great for individual fields. Here is an example field.
<div class="control-group" ng-class="getErrorClasses(schoolSignup.first_name)">
<label class="control-label" for="first_name">First Name</label>
<div class="controls">
<input type="text" class="input-xlarge" id="first_name" name="first_name" required ng-maxlength="30" ng-model="school.first_name">
<span class="help-inline" ng-show="showError(schoolSignup.first_name, 'required')">This field is required</span>
<span class="help-inline" ng-show="showError(schoolSignup.first_name, 'maxlength')">Maximum of 30 character allowed</span>
</div>
</div>
schoolSignup
is the name of the form.
ng-class="getErrorClasses(schoolSignup.first_name)">
is defined in the controller as
$scope.getErrorClasses = function(ngModelContoller) {
return {
error: ngModelContoller.$invalid && ngModelContoller.$dirty
};
};
And on the error help items ng-show="showError(schoolSignup.first_name, 'required')"
is defined as:
$scope.showError = function(ngModelController, error) {
return ngModelController.$dirty && ngModelController.$error[error];
};
This all works fine.
However, what I want to do is make it so if the user clicks the submit button and all the individual fields that are required are invalid then show the required
error message next to the appropriate fields.
This will require setting all the individual fields to $dirty
and the $error['required']
value to true
based on this system.
I have set up a directive on the submit button called can-save
as follows which has access to the form.
<button class="btn btn-primary btn-large" type="submit" can-save="schoolSignup">Register</button>
-
.directive('canSave', function () {
return function (scope, element, attrs) {
var form = scope.$eval(attrs.canSave);
var valid = false;
element.click(function(){
if(!valid)
{
// show errors
return false;
}
return true;
});
scope.$watch(function() {
return form.$dirty && form.$valid;
}, function(value) {
valid = !!value;
});
}
});
This all works except for making the errors show as desired.
Any ideas on how to achieve this would be appreciated.
Upvotes: 0
Views: 5372
Reputation: 9587
For anyone interested, I've amended my directive to loop through the errors and set each to $dirty
and then run $rootScope.$digest()
:
.directive('canSave', function ($rootScope) {
return function (scope, element, attrs) {
var form = scope.$eval(attrs.canSave);
element.click(function () {
if(form.$dirty && form.$valid) {
return true;
} else {
// show errors
angular.forEach(form.$error, function (value, key) {
var type = form.$error[key];
angular.forEach(type, function (item) {
item.$dirty = true;
item.$pristine = false;
});
});
$rootScope.$digest();
return false;
}
});
}
});
Upvotes: 2