Reputation: 767
I'm building an app in angular js. I want to create a restriction an input field to accept only 3, 6, 9, 12, 15 and so on. It should mark it as no valid if the user writes for example an 8.
I couldn't find how to do this, help would be appreciated.
Upvotes: 2
Views: 1559
Reputation: 5077
You can create a directive and add your own validator that checks for multiples of 3.
See plunker
Markup:
<input name="numberField" type="number" data-ng-model="model.number" data-multiple-validator="3"/>
JS:
app.directive('multipleValidator', [function(){
return {
restrict: 'AC',
require: 'ngModel',
link: function(scope, elem, attr, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
var multiple = parseInt(attr.multipleValidator);
if (!multiple) {
return;
}
ngModelCtrl.$validators.multipleValidator = function(modelValue, viewValue) {
return !!modelValue && modelValue%multiple === 0;
}
}
}
}])
If it's only the numbers 3, 6, 9, 12 and 15 then you can just use ng-pattern
like so
<input name="numberField" type="number" data-ng-model="model.number" data-ng-pattern="/^(3|6|9|12|15)$/"/>
EDIT
If your multiple
value is dynamic then you will have to watch for changes in your directive using the very handy $observe
and re-validate when it changes. See updated plunker.
Markup:
<input placeholder="input" name="numberField" type="number" data-ng-model="model.number" data-multiple-validator="{{model.multiple}}"/>
JS:
app.directive('multipleValidator', [function(){
return {
restrict: 'AC',
require: 'ngModel',
link: function(scope, elem, attr, ngModelCtrl) {
if (!ngModelCtrl) {
return;
}
ngModelCtrl.$validators.multipleValidator = function(modelValue, viewValue) {
var multiple = parseInt(attr.multipleValidator);
if (!multiple) {
// If there is no multiple then assume that it is valid
return true;
}
return !!modelValue && modelValue%multiple === 0;
}
// Watch for changes to the multipleValidator attribute
attr.$observe('multipleValidator', function(newVal, oldVal) {
// Re-validate the input when a change is detected
ngModelCtrl.$validate();
});
}
}
}]);
Upvotes: 1
Reputation: 512
There is no need to use a custom directive. Angular has built in directive called ng-pattern which lets you match the input field to your given regular expression.
Here is how i have achieved this.. CODE...
<html ng-app="num">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-controller="numCtrl">
<form class="digits" name="digits">
<input type="text" placeholder="digits here plz" name="nums" ng-model="nums" required ng-pattern="/^([0369]|[258][0369]*[147]|[147]([0369]|[147][0369]*[258])*[258]|[258][0369]*[258]([0369]|[147][0369]*[258])*[258]|[147]([0369]|[147][0369]*[258])*[147][0369]*[147]|[258][0369]*[258]([0369]|[147][0369]*[258])*[147][0369]*[147])*$/" />
<p class="alert" ng-show="digits.nums.$error.pattern">Multiples of three only accepted.</p>
<br>
</form>
<script>
var app = angular.module('num',[]);
app.controller('numCtrl', function($scope, $http){
$scope.digits = {};
});
</script>
</body>
</html>
Upvotes: 1
Reputation: 101
See this jsfiddle for a working example https://jsfiddle.net/s7mmvxq5/5/
The approach I took was to create a directive that just adds an additional $validator
to the form field. Since the validator is just a function you can do whatever check you'd like in it.
This section of the angular docs might be of interest https://docs.angularjs.org/guide/forms#custom-validation
Upvotes: 0