Reputation: 815
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:
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?
Upvotes: 1
Views: 3336
Reputation: 815
My current solution (probably not the best one):
<input type="text"
name="name"
placeholder="Your Name"
ng-model="form.name"
ng-minlength="3"
ng-maxlength="20"
unique
updatable
required />
<button ng-click="submitForm()">Submit</button>
<div class="error"
ng-show="!my_form.name.isDirty && my_form.isSubmitted"
ng-messages="my_form.name.$error">
<div ng-messages-include="errors.html"></div>
</div>
I added new directive updatable to my field and updated the show condition for error div:
ng-show="!my_form.name.isDirty && my_form.isSubmitted"
The directive:
app.directive('updatable', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, ele, attrs, ctrl) {
ele.bind('input', function() {
scope.$apply(function() {
ctrl.isDirty = true;
});
);
}
};
});
And a small update of submitForm function which now sets isDirty flag of my field(s) to false:
$scope.submitForm = function() {
$scope.my_form.isSubmitted = true;
$scope.my_form.name.isDirty = false;
};
Upvotes: 1