I need to create a validation directive for showing all input errors for each input automatically. This validation directive should show all errors at current moment and list of errors should be updated automatically while user is typing.
I need to show all errors for input if input is dirty, not empty and invalid. I need to add all errors into html element near this input element.
For example if input have type="email" and ng-minlength="5" and user typed 'abc' I need to show such errors near this input: 'Invalid email; Please enter at least 5 characters;'
For example if input has type="number" attr and min="200" and min-model="minnumber" and minnumber model set to '300' and user typed '100' I need to show such errors near this input: 'Please enter the minimum number of 500; Should be greater than Min Number;'
Also I need to update all errors messages for input in prev example if related model (min-model param) is updated.
var app = angular.module('app', []);
app.controller('appCtrl', function ($scope) {
});
app.directive('validate', function () {
return {
restrict: 'A',
require: 'ngModel', // require: '^form',
link: function (scope, element, attrs, ctrl) {
console.log('======================');
console.log(scope);
console.log(element);
console.log(attrs);
console.log(ctrl);
console.log(scope.form.$error);
angular.forEach(scope.form.$error, function (value, key) {
console.log('scope.form.$error = ' + key + ': ' + value);
console.log(value);
});
}
};
});
app.directive('positiveInteger', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var INTEGER_REGEXP = /^\d+$/;
if (INTEGER_REGEXP.test(viewValue)) { // it is valid
ctrl.$setValidity('positiveInteger', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('positiveInteger', false);
return undefined;
}
});
}
};
});
app.directive('positiveFloat', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var FLOAT_REGEXP = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
if (FLOAT_REGEXP.test(viewValue)) { // it is valid
ctrl.$setValidity('positiveInteger', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('positiveInteger', false);
return undefined;
}
});
}
};
});
app.directive('minModel', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
if (viewValue > scope[attrs.minModel]) { // it is valid
ctrl.$setValidity('minModel', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('minModel', false);
return undefined;
}
});
}
};
});
Can you help to make this validation directive?
Or maybe can you point me into the right direction?
Link to JSFiddle with some code for testing.
P.S. Something similar is made with UI-Utils but their directive does not give ability to set similar error messages in one place.
errors = []; $scope. hasError = false; $scope.
Form Validation AngularJS also holds information about whether they have been touched, or modified, or not. You can use standard HTML5 attributes to validate input, or you can make your own validation functions. Client-side validation cannot alone secure user input. Server side validation is also necessary.
$setValidity(validationErrorKey, isValid); Change the validity state, and notify the form. This method can be called within $parsers/$formatters or a custom validation implementation. However, in most cases it should be sufficient to use the ngModel. $validators and ngModel.
Here is the pattern that I used (with Angular 1.3):
app.directive('number', function() {
var NUMBER_REGEXP = /^(\d+)$/;
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.number = function(modelValue, viewValue) {
return NUMBER_REGEXP.test(viewValue);
};
}
};
});
Then I was able to check for errors in the HTML (with Bootstrap 3.3) using this pattern:
<form name="form">
<div class="form-group"
ng-class="{'has-error': form.value.$dirty && form.value.$error.number}">
<label for="id_value" class="control-label">Value:</label>
<div>
<input type="text" class="form-control" id="id_value" name="value"
ng-model="model.number" number>
<p class="help-block" ng-if="form.value.$error.number">Please enter a number</p>
</div>
</div>
</form>
Explanation:
The number
attribute in the <input name="value">
tag triggers the directive, which causes the ngModel
validator 'number'
to be called and to set/unset value.$error.number
.
If value.$error.number
is set, then the has-error
class is applied to the form-group
so it displays a red input field and the help message is displayed.
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