I have a validation directive called valid-number
that is used to set the validity of a form using $setValidity - this works fine for any text values that I type in
You can simply call your verification function during the linking phase, like in this fiddle :
link: function(scope, elm, attrs, ctrl) {
var regex=/\d/;
var verificationFunction = function(viewValue) {
var floatValue = parseFloat(viewValue);
if(regex.test(viewValue)) {
ctrl.$setValidity('validNumber',true);
return viewValue;
}
else {
ctrl.$setValidity('validNumber',false);
return undefined;
}
};
ctrl.$parsers.unshift(verificationFunction);
verificationFunction();
}
$parsers
array contains a list of functions that will be applied to the value that model receives from the view (what user types in), and $formatters
array contains the list of functions that are being applied to the model value before it's displayed in the view.
In your directive you correctly used the $parsers
array, but you also need to add the $formatters
array if you want the initial value to be validated:
angular.module('test',[]).directive('validNumber',function(){
return{
require: "ngModel",
link: function(scope, elm, attrs, ctrl){
var regex = /^\d$/;
var validator = function(value){
ctrl.$setValidity('validNumber', regex.test(value));
return value;
};
ctrl.$parsers.unshift(validator);
ctrl.$formatters.unshift(validator);
}
};
});
Demo plunker
After (>=) angular 1.3.1 version was released you could implement that behaviour with a little bit correct way, following angular validation directives style (e.g. required, maxlength).
In that case you have to append your validator as property of $validators
array and there are no need in $parsers
or $formatters
anymore:
var app = angular.module('test', []);
app
.directive('validNumber', function() {
return {
require: "ngModel",
link: function(scope, elm, attrs, ctrl) {
var regex = /^\d+$/;
ctrl.$validators['validNumber'] = function(modelValue, viewValue) {
return regex.test(viewValue);
};
}
};
});
app.controller('NumberCtrl', NumberCtrl);
function NumberCtrl($scope) {
$scope.amount = '5z';
};
input.ng-invalid {
background-color: #FA787E;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="NumberCtrl">
<div ng-form name="numberForm">
<input name="amount"
type="text"
ng-model="amount"
required
valid-number />
<span ng-show="numberForm.amount.$error.validNumber">
Doesn't look like an integer
</span>
</div>
</div>
</div>