I have a form with currently one field, which has few validation rules:
<form name="my_form" novalidate ng-controller="FormController">
<label>Your Name:</label>
<input type="text"
name="name"
placeholder="Your Name"
ng-model="form.name"
ng-minlength="3"
ng-maxlength="20"
unique
required />
<button ng-click="submitForm()">Submit</button>
<div class="error"
ng-show="my_form.isSubmitted"
ng-messages="my_form.name.$error">
<div ng-messages-include="errors.html"></div>
</div>
</form>
My field is validated against:
- Min. length;
- Max. length;
- It's required
- And must be unique (custom validation rule)
I'm using ng-messages to display error messages near input field. Here is my errors.html template:
<div ng-message="required">This field is required.</div>
<div ng-message="minlength">This field is too short.</div>
<div ng-message="maxlength">This field is too long.</div>
<div ng-message="unique">The value of this field must be unique.</div>
The validation should be started only after 'Submit' button is pressed (submitForm() function sets my_form.isSubmitted flag to true and my error div is displayed)
Here is my js code:
var app = angular.module('formValidation', ['ngMessages']);
app.controller('FormController', function($scope) {
$scope.submitForm = function() {
$scope.my_form.isSubmitted = true;
};
});
app.directive('unique', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, ele, attrs, ctrl) {
var names = ['Dmitry', 'Alexander', 'Elizabeth'];
ctrl.$parsers.push(function(value) {
if (names.indexOf(value) > -1) {
ctrl.$setValidity('unique', false);
return false;
}
ctrl.$setValidity('unique', true);
return true;
});
}
};
);
Everything works fine, but what I want to do now is to hide errors if the field is modified after errors were shown (until submit button will be pressed again).
The first idea came to my mind is to add another condition to ng-show directive of error div to check if corresponding field is updated and if it is, errors should not be shown. Something like:
<div class="error"
ng-show="!my_form.name.isUpdated && my_form.isSubmitted"
ng-messages="my_form.name.$error">
<div ng-messages-include="errors.html"></div>
</div>
So, on button click I can set isUpdated flag of all form fields to false and on input update can set it to true. But this solution seems to me far from elegant. I'm sure there is a better way to achieve this behaviour. Any ideas?
ng-changedirective on the input to let the form know one of the values has changed?