Search code examples
angularjsng-maxlength

ng-maxlength screws up my model


I'm trying to do a simple textarea with "so many chars remaining" along with validation. when I use ng-maxlength to validate my form, it resets my charcount as soon as the length hits the max length. Here's the plunkr Any workarounds?

  <body ng-controller="MainCtrl">
    <div ng-form="noteForm">
      <textarea ng-maxlength="15" ng-model="result"></textarea>
      <p>{{15 - result.length}} chars remaining</p>
      <button ng-disabled="!noteForm.$valid">Submit</button>
    </div>
  </body>

Solution

  • When your textarea exceeds 15 characters, result becomes undefined — that's just how the ng-min/maxlength directives work. I think you'll have to write your own directive. Here is a directive that will block input after 15 characters:

    <textarea my-maxlength="15" ng-model="result"></textarea>
    
    app.directive('myMaxlength', function() {
      return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
          var maxlength = Number(attrs.myMaxlength);
          function fromUser(text) {
              if (text.length > maxlength) {
                var transformedInput = text.substring(0, maxlength);
                ngModelCtrl.$setViewValue(transformedInput);
                ngModelCtrl.$render();
                return transformedInput;
              } 
              return text;
          }
          ngModelCtrl.$parsers.push(fromUser);
        }
      }; 
    });
    

    fiddle


    Update: to allow more than 15 characters, but disable the submit button when the count exceeds 15:

    link: function (scope, element, attrs, ngModelCtrl) {
      var maxlength = Number(attrs.myMaxlength);
      function fromUser(text) {
          ngModelCtrl.$setValidity('unique', text.length <= maxlength);
          return text;
      }
      ngModelCtrl.$parsers.push(fromUser);
    }
    

    fiddle