I'm creating a signup form in Angular with three inputs: email
, password
and passwordConfirm
. My controller looks like this:
app.controller('SignupController', function ($scope, User) {
$scope.user = {};
$scope.signup = function() {
User.save($scope.user, function(success) {
// TODO
}, function(error) {
if (error.status === 422) {
error.data.errors.forEach(function(item) {
$scope.signupForm[item.field].$setValidity(item.error, false);
});
}
});
};
});
What this is doing is sending a request to my API when the user submits the form to register themselves. If a 422
response comes back (which means validation errors), I loop through them and set the corresponding inputs to invalid based on what the API returned.
Let's take the example of an email address already being registered. I show the validation error in my view like this:
<small class="error" ng-show="signupForm.email.$error.exists">Email address taken, please use another</small>
This all works perfectly, but my user is now stuck because when they try to change the email address to another one, the validity of the email
field isn't changed to allow them to resubmit the form (I disable the submit button based on form validity).
Basically, I need the validation property (in this case exists
) to be reset to true
after the user changes the input model. What's the best way for me to do that?
Edit: A small brainwave hit me after posting, I added this to my controller:
$scope.$watch('user.email', function() {
// Reset exists validation property back to true
$scope.signupForm.email.$setValidity('exists', true);
});
which seems to work. When the user changes the model value after the input was set to invalid, this sets it back to valid. But this doesn't strike me as the best way to do this. Anyone know better?
I have also struggled with this issue. After reading your post I came up with a possible solution - create a directive that is watching the model for changes and reset the validity state on change (basically what you suggested but put in a generic directive)
angular.module('app').directive('resetValidityOnChange', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, iElem, iAttrs, ngModelCtrl) {
ngModelCtrl.$viewChangeListeners.push(function () {
ngModelCtrl.$setValidity(iAttrs['resetValidityOnChange'], true);
});
}
}
}
You will have to add this directive to the input's you would like to reset, for instance:
<input type="text" ng-model="vm.email" reset-validity-on-change="exists" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With