17

How can I stop an user from typing more characters into a textarea when a maximum amount of characters is reached?

Im using ng-keypress right now but I can't figure out how to prevent the input when the limit is reached. The user should not be able to enter or paste more than 1000 characters in total into that textarea.

The question is about how to stop the input, not how to Count the Input lenght, this part is already working fine for me.

Plunker link.

    $scope.$watch('comment.Comment.body', function (newValue, oldValue) {
        if (newValue) {
            $scope.commentLength = 1000 - newValue.length;
        }
    });
    // Tried this, nothing stops it
    $scope.updateBody = function (event) {
        event.cancel();
        event.stop();
        return false;
    };

HTML

<textarea
    ng-model="comment.Comment.body"
    name="comment[Comment][body]"
    placeholder="Your comment..."
    ng-keypress="updateBody($event)">
</textarea>
<p>
    {{commentLength}} remaining
</p>

Solution:

My mistake was I just had a typo somewhere but the given answer is not 100% OK. Instead of using the oldValue it is required to substring() the newValue. If you don't do that you can't paste a text that goes over the 1000 characters into the text area. Using the newValue allows you to paste and cut the text down to the Limit.

    $scope.$watch('comment.Comment.body', function (newValue) {
        if (newValue && newValue.length > 1000) {
            $scope.comment.Comment.body = newValue.substring(0, 1000);
        }
        // Must be checked against undefined or you get problems when removing text
        if (newValue != undefined) {
            $scope.commentLength = 1000 - newValue.length;
        }
    });
  • Does it help at all to use ng-keydown (rather than ng-keypress)? – Josh Darnell Nov 24 '14 at 13:57
  • if you still need an answer to this, check the answer in this thread, you have to write a custom directive -> http://stackoverflow.com/questions/17075969/ng-maxlength-screws-up-my-model – akashrajkn Jun 15 '15 at 12:28

11 Answers11

22

You should try using maxlength attribute. The code would be something like

<textarea
    ng-model="comment.Comment.body"
    name="comment[Comment][body]"
    placeholder="Your comment..."
    maxlength="1000">
</textarea>
<p>
    {{1000 - comment.Comment.body.length}} remaining
</p>
Ijon Tichy
  • 447
  • 2
  • 7
  • 1
    This **doesn't** prevent the user from typing more than 1000 characters into the Input box. –  Nov 24 '14 at 12:53
  • @Falk my bad. Here was a comment of someone, I don't know why it was deleted. I've edited my answer according to it. – Ijon Tichy Nov 24 '14 at 12:59
  • I made a mistake - the maxlength is now working for text area as well so this is a correct answer – Bogdan Sep 03 '15 at 03:21
15

You can use 'ng-maxlength' from angular input functionality, and watch when value is invalid. https://docs.angularjs.org/api/ng/directive/input , but it won't block the possibility to input.

Also you could just set a watch for value:

$scope.$watch('value', function(newVal, oldVal) {
  if(newVal.length > 10) {       
    $scope.value = oldVal;
  }
});
Rasalom
  • 3,101
  • 3
  • 21
  • 29
  • I'm already doing this. The question is how to block the Input. –  Nov 24 '14 at 12:56
  • You want to disable the input field at all? Because the second one will block possibility to input data. – Rasalom Nov 24 '14 at 12:58
  • I've tried that, didn't work for me. I have an appointment right now, I'll set up a plunker when I'm back in ~2h. –  Nov 24 '14 at 13:00
  • Here is the Plunker link http://plnkr.co/edit/40xoDECCnIB650bj8N0E I want to stop the user from adding more than 1000 chars but not set the field to disabled. Just not allowing him to enter more chars but still allow him to remove and change the content. –  Nov 24 '14 at 14:59
  • Works, I've had a typo somewhere :/ Thank you! –  Nov 24 '14 at 15:14
  • I've updated my answer with an improved version of your code. Check it out if you're interested because your code has one disadvantage. –  Nov 24 '14 at 22:14
  • Tried it with an input of text, worked for me after changing the ng-model name from `ng-model='myInput'` to `ng-model='myInput.text` and also the name of the watched var and in the assignment line – ZivS Mar 26 '16 at 23:04
10

Directive way:

app.directive('myBlock', function ($parse) {
    return {
        scope: {
          validLength: '='
        },
        link: function (scope, elm, attrs) {

          elm.bind('keypress', function(e){

            // stop typing if length is equal or greater then limit
            if(elm[0].value.length >= scope.validLength){
              e.preventDefault();
              return false;
            }
          });
        }
    }   
});

Demo in plunker

vinesh
  • 4,745
  • 6
  • 41
  • 45
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
6

All of the answers here are overly complicated and fail to leverage the power of HTML5. All you need to do is add maxlength="1000" to your input element and this will prevent the user from typing more than 1000 characters. It will also clip any pasted input to maintain the limit. See the Docs for more details.

Note that maxlength is not the same as ng-maxlength. ng-maxlength simply checks the length of the input and sets formName.$invalid if the input exceeds the limit. You can use both on the same input or textarea element.

Daniel Bonnell
  • 4,817
  • 9
  • 48
  • 88
6
<input type="text" name="usrname" maxlength="10">

use maxlength in your HTML . this is easy and effective

Thom
  • 323
  • 1
  • 3
  • 13
2

just adding the maxlength property to textarea solve the problem

<textarea maxlength="10"
    ng-model="comment.Comment.body"
    name="comment[Comment][body]"
    placeholder="Your comment..."
    ng-keypress="updateBody();">
</textarea>
2

Although watchers do work, they are very costly due to the nature of the digest cycle, so if you need this functionality in many places you can access the change event and monitor the length.

// controller
$scope.monitorLength = function (maxLength) {
  if ($scope.value.length > maxLength) {
    $scope.value = $scope.value.substring(0, maxLength);
  }
}

// html
<textarea ng-model="value" ng-change="monitorLength(1000)"></textarea>
dbushy727
  • 111
  • 3
  • I think this is the best option when only limiting the length. I've used the watch strategy for applying a regex to the input and replacing the contents with the last valid input on failure, but for this case I like a non-watch option. – Luke Rice May 26 '16 at 21:40
2

Going through same problem, stumbled on this post. Below solution worked for me.

<input type="text" data-ng-model="value" class="form-control" ng-pattern="/^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]$/" ng-maxlength="15" maxlength="15" placeholder="enter your text here...">
Mr. Wonderful
  • 189
  • 4
  • 13
1

You can do this to block it

    $scope.$watch('value', function(newVal, oldVal) {
        if(newVal == undefined){
            $scope.value= oldVal;
        }
    });

    <textarea ng-maxlength="10" ng-model="value" ></textarea>
  • This works. Since it has ng-maxlength set, if value is > than 10 newVal will be undefined, and than you can just set it back to oldVal. – mirzak Feb 12 '16 at 12:13
0

Why angular?? when simple HTML & JavaScript can do this?

   $scope.charLimit = function($event, limitNum) {
       limitField =$event.currentTarget;
       if (limitField.value.length > limitNum) {
           limitField.value = limitField.value.substring(0, limitNum);}
   };

In HTML

 <textarea onkeyup="charLimit($event,10)" placeholder="Enter text here..."></textarea>
LadyQ
  • 9
  • 2
0

Just do this -

<textarea ng-model="msg" maxlength="25"></textarea>

This will definitely work!

dust
  • 171
  • 1
  • 5