I encountered an issue with a directive used within a form, specifically when clicking on a button with the type reset. The problem can be replicated on this stackblitz link. The directive I'm using is quite simple - it sets the input in an error state if the entered value is less than 1900. It's worth noting that I am unable to change the type of the button, it must remain as type=reset
.
To see the expected behavior of the directive:
- Input '100' into the field => you should see the input display an error
- Input '2000' into the field => the input should no longer show an error
To observe the bug in the directive's behavior:
- Input '100' into the field => the input will show an error
- Click on the reset button => the input will be cleared, but the error state persists, even though it should have been removed
Below is the HTML code snippet:
<form name="dateForm">
<div class="form-group" name="dateForm">
<label for="usr">Name:</label>
<input type="text" class="form-control" id="year" name="year"
valid-year="true" ng-model="$ctrl.year" year-min="1900">
</div>
<button type="reset" class="btn btn-primary">Reset</button>
</form>
This is the corresponding JS code:
angular.module('app', requires)
.directive('validYear', function() {
return {
require: 'ngModel',
link: function (scope, element, attrs, modelCtrl) {
if (attrs.validYear === 'true') {
if (!modelCtrl) {
return;
}
modelCtrl.$parsers.push(function (value) {
console.log('--> call to directive');
if (angular.isDefined(attrs.yearMax) && parseInt(value) > parseInt(attrs.yearMax)) {
modelCtrl.$setValidity('validYear', false);
} else {
modelCtrl.$setValidity('validYear', true);
}
if (angular.isDefined(attrs.yearMin) && parseInt(value) < parseInt(attrs.yearMin)) {
modelCtrl.$setValidity('validYear', false);
} else {
if (angular.isDefined(attrs.yearMax) && parseInt(value) > parseInt(attrs.yearMax)) {
modelCtrl.$setValidity('validYear', false);
} else {
modelCtrl.$setValidity('validYear', true);
}
}
return value;
});
}
}
};
});