28

I am looking for ways to limit the value inside the input to 4 and process the 4 digit value unto my controller.

 <input type="number" class="form-control input-lg"
 ng-model="search.main" placeholder="enter first 4 digits: 09XX">
                {{ search.main | limitTo:4}}
bluestella
  • 383
  • 2
  • 6
  • 17

17 Answers17

62

Can always make a directive for it:

app.directive("limitTo", [function() {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            angular.element(elem).on("keypress", function(e) {
                if (this.value.length == limit) e.preventDefault();
            });
        }
    }
}]);

<input limit-to="4" type="number" class="form-control input-lg" ng-model="search.main" placeholder="enter first 4 digits: 09XX">
Sébastien BATEZAT
  • 2,353
  • 26
  • 42
tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • 1
    I think @Raghav answer is better suited and is more straight forward. – Kousha Jul 11 '14 at 22:22
  • 2
    You probably don't want to return false because that won't allow the user to go back and fix their input. It will also render tabbing false. – uxder May 26 '15 at 20:28
  • 3
    You can modify the above to: angular.element(elem).on('keypress', function(e) { this.value = this.value.substring(0, limit - 1); }); – uxder May 26 '15 at 20:42
  • 2
    With "keydown" you can't really delete the value if it has reached the limit. Chaning it to "keypress" would solve this issue. – Alon Jun 22 '15 at 16:00
  • 4
    there is a problem with this directive. If you enter maximum length once, then it will not accept any other character even the backspace. That is if limit-to="4" and if you entered 4 character in input box, then you will not able to delete it. – Sunil Garg Nov 05 '15 at 11:51
  • I fixed it this way: angular.element(elem).on("keypress", function(e) { var key; if (e.which == null) { // IE key = e.keyCode; } if (e.which != 0) { // all but IE key = e.which; } if (this.value.length == limit && (key != 8 && key !== 46)) { e.preventDefault(); } }); – Sol Apr 30 '16 at 19:18
  • 2
    On copy pasting in the input field, this allows more than limited length. – Deepak Acharya Jul 11 '18 at 15:13
15

You can always use ng-minlength, ng-maxlength for string length and min, max for number limits. Try this

<input type="number" 
       name="input"
       class="form-control input-lg"
       ng-model="search.main" 
       placeholder="enter first 4 digits: 09XX"
       ng-minlength="1" 
       ng-maxlength="4" 
       min="1" 
       max="9999">

DEMO FIDDLE

Raghavendra
  • 5,281
  • 4
  • 36
  • 51
11

No need to use an AngularJS directive.

Just use the good old standard html attribute maxlength.

<input type="text" maxlength="30" />
  • There is no `maxlength` attribute, when you use an input field of type `number`. This only applies to type `text`. See [reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#Additional_attributes) in MDN, for example. – user1438038 Apr 16 '20 at 09:30
8

I used the accepted answer as a launching point, but this is what I came up with.

angular.module('beastTimerApp')
  .directive('awLimitLength', function () {
  return {
    restrict: "A",
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      attrs.$set("ngTrim", "false");
      var limitLength = parseInt(attrs.awLimitLength, 10);// console.log(attrs);
      scope.$watch(attrs.ngModel, function(newValue) {
        if(ngModel.$viewValue.length>limitLength){
          ngModel.$setViewValue( ngModel.$viewValue.substring(0, limitLength ) );
          ngModel.$render();
        }
      });
    }
  };
});

usage

<input name="name" type="text"  ng-model="nameVar" aw-limit-length="10"/>

The key is to use $setViewValue() and $render() to set and display the changes respectively. This will make sure $viewValue and $modelValue are correct and displayed properly. You also want to set ngTrim to false to prevent the user adding whitespaces beyond the limit. This answer is an amalgamation of @tymeJV's answer and this blog post... https://justforchangesake.wordpress.com/2015/01/10/useful-angularjs-directives/

honkskillet
  • 3,007
  • 6
  • 31
  • 47
  • Awesome this is what I was looking for. I was trying to use watch, but couldn't figure out what to bind it to. Just a caution this will move your cursor to the end after formatting. Here is a plunker I made to fix some of the problem with cursor jumping. http://plnkr.co/edit/7glDI3Mh3HtmgVAR2bFz?p=preview. This is based on my answer to this question: http://stackoverflow.com/questions/20203216/input-cursor-position-jumps-to-end-with-ng-change/36421366#36421366 – jgerstle May 29 '16 at 08:11
8

Will do it allowing backspaces and deletes.

app.directive("limitTo", [function() {
    return {
    restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            angular.element(elem).on("keydown", function() {
                if(event.keyCode > 47 && event.keyCode < 127) {
                    if (this.value.length == limit) 
                        return false;
                }   
            }); 
        }
    }
}]);
Danilo Kobold
  • 2,562
  • 1
  • 21
  • 31
5

you can use this code:

<input type="number" class="form-control input-lg" 
       ng-model="search.main" 
       ng-keypress="limitKeypress($event,search.main,4)"
       placeholder="enter first 4 digits: 09XX">

and AngularJS code:

$scope.limitKeypress = function ($event, value, maxLength) {
        if (value != undefined && value.toString().length >= maxLength) {
            $event.preventDefault();
        }
    }
Behnam
  • 6,244
  • 1
  • 39
  • 36
4

We can use ng-value instead:

ng-value="(minutes > 60 ? minutes = 0 : minutes)"

In html code:

<input type="text" class="form-control" ng-model="minutes" ng-maxlength="2" ng-pattern="/^[0-9]*$/" ng-value="(minutes > 60 ? minutes = 0 : minutes)"/>

This will check for the value and if it is greater than 60, it replaces the value with 0.

PetsonJ
  • 49
  • 1
  • 1
2

As there is a problem in above directive (answer of tymeJV). If you enter maximum length once, then it will not accept any other character even the backspace. That is if limit-to="4" and if you entered 4 character in input box, then you will not able to delete it. SO here is the updated answer.

app.directive("limitTo", [function () {
        return {
            restrict: "A",
            link: function (scope, elem, attrs) {
                var limit = parseInt(attrs.limitTo);
                elem.bind('keypress', function (e) {
//                    console.log(e.charCode)
                    if (elem[0].value.length >= limit) {
                        console.log(e.charCode)
                        e.preventDefault();
                        return false;
                    }
                });
            }
        }
    }]);
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
2

Angular material has a directive mdMaxlength, if you want to cut off the input at this length, you can use this directive:

 app.directive("forceMaxlength", [function() {
   return {
     restrict: "A",
     link: function(scope, elem, attrs) {
       var limit = parseInt(attrs.mdMaxlength);
       angular.element(elem).on("keydown", function() {
         if (this.value.length >= limit) {
           this.value = this.value.substr(0,limit-1);
           return false;
         }
       });
     }
   }
 }]);

Usage:

<input type="text" md-maxlength="30" force-maxlength=""/>
Arne
  • 6,140
  • 2
  • 21
  • 20
2

We can write the directive to listen to the keypress event. But for some old browsers, this event is not triggered. Thats why i created a directive in such a way that there's no dependency on browser specific events limitation. I created an angular directive to limit the number of text in the input box.

'use strict';
angular.module("appName")
.directive("limitTo", [function() {
return {
restrict: "A",
require: "ngModel",
link: function(scope, elem, attrs, ctrl) {
    var limit = parseInt(attrs.limitTo);
    ctrl.$parsers.push(function (value) {
        if (value.length > limit){
            value = value.substr(0, limit);
            ctrl.$setViewValue(value);
            ctrl.$render();
        }
        return value;
    });
 }
}}]);

Usage: <input limit-to="3" ng-model="test"/> would allow only 3 characters in input box.

Muhammed Neswine
  • 2,028
  • 1
  • 20
  • 20
2

In Angular Js Material we can limit input field by "maxLimit", for example we need limit of input text should b 60 character as:

maxLimit ='60'

complete code:

<form-input-field flex
                  class="input-style-1"
                    title="Quick response tag title"
                    placeholder="Write a catchy title to help users get more information on the service card"
                    form-name="parent.qrtForm"
                    show-error="showError"
                    name="title"
                    maxLength="65"
                    text-limit="65"
                    required="true"
                    ng-model="newQrt.tagName">
Rizwan
  • 3,741
  • 2
  • 25
  • 22
1

Run this operation on any change to the number:

var log = Math.log(number) / Math.log(10);
if (log >= 4)
   number = Math.floor(number / Math.pow(10, Math.ceil(log - 4)));

This will always limit "number" to 4 digits.

1

I am reiterating what @Danilo Kobold said.

I had to make sure that users can enter only numbers (0-9) [Without 'e' or '.' or '-'] and a limit of 4 values only.

app.directive("limitTo", [function() {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            var exclude = /Backspace|Enter/;
            angular.element(elem).on("keydown", function(e) {
                if (event.keyCode > 47 && event.keyCode < 58) {
                    if (this.value.length == limit) e.preventDefault();
                } else if (!exclude.test(event.key)) {
                    e.preventDefault();
                }
            });
        }
    }
}]);

If you want to use only limit then use

app.directive("limitTo", [function() {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            var exclude = /Backspace|Enter/;
            angular.element(elem).on("keydown", function(e) {
                if (!exclude.test(event.key)) {
                    if (this.value.length == limit) e.preventDefault();
                }
            });
        }
    }
}]);

You can add more keys if you want to the exclude variable, like this:

var exclude = /Backspace|Enter|Tab|Delete|Del|ArrowUp|Up|ArrowDown|Down|ArrowLeft|Left|ArrowRight|Right/;

Got idea from this post

Hope I helped someone.

Community
  • 1
  • 1
Prashanth VG
  • 191
  • 1
  • 14
0

You can just use

ui-mask="9999"

as attribute in your view.

Nagarjun
  • 6,557
  • 5
  • 33
  • 51
Finelf
  • 11
  • 3
0

**

app.directive("limitTo", [function() {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            var exclude = /Backspace|Enter/;
            angular.element(elem).on("keydown", function(e) {
                if (e.keyCode > 47 && e.keyCode < 58) {
                    if (this.value.length == limit) e.preventDefault();
                } else if (!exclude.test(e.key)) {
                    e.preventDefault();
                }
            });
        }
    }
}]);

**

suresh manda
  • 659
  • 1
  • 8
  • 25
0

Use this directive if you want to restrict max length for a input field which is present as part of custom directive template. This is the native html5 way of restricting max-lenth. This will also handle the copy paste case also to restrict till the maxlength on pasting.

app.directive('inputWrapper', function() {
    return {
        restrict: 'A',
        template: "<input type='text'/>"
    };
});

app.directive('maxInputLength', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.maxInputLength);
            angular.element(elem).find('input').attr('maxlength', limit);
        }
    };
});
<input-wrapper max-input-lenth="35"></input-wrapper>
Deepak Acharya
  • 429
  • 5
  • 6
0

Do this instead

 <input type="text" class="form-control input-lg" ng-model="search.main" placeholder="enter first 4 digits: 09XX"  maxlength="4" num-only>{{ search.main | limitTo:4}}

use the type "text", then use maxlength to limit it and also use the num-only option to make it number input only