2

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.

3 Answers 3

1

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();
      });
    }
  }
}]);
Sign up to request clarification or add additional context in comments.

1 Comment

Actually, @user2718281 I'm not passing 3 as a constant, but it comes from an input field. <input ... data-multiple-validator="{{competition.teams}}"/>, it works initially as 3 is my default competition.teams value, but when I change the input value at competition.teams, the change doesn't affect the directive. Does anybody know how to do that?
1

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>

2 Comments

Writing regex patterns in html is not a good Idea. You would end up with repeating yourself as the webapp grows big. A directive is better
You can write your regex in js files. I have written here it just for purpose of better understanding
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.