Pablo Santamaria
Pablo Santamaria

Reputation: 767

angular js, how to restrict input values to only a few numbers

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

Answers (3)

logee
logee

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

Nitesh Rana
Nitesh Rana

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

Marshall Hampson
Marshall Hampson

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

Related Questions