3

I'm facing a weird "bug". I have a form with a textarea with a minlength and a maxlength validation on it.

Also, there is a super simple character left counter:

<textarea ng-trim="false" ng-model="form.text" minlength="20" maxlength="240"></textarea>
<p>{{240 - form.text.length}} left</p>

I don't know why my counter start working only after the characters reach the minlength value... While typing the counter stuck to 240. After I reach 20 characters the counter jump to 220... What is going wrong here?

Pen example

2 Answers 2

2

The basic validation directives such as ng-minlength will block ngModel from being updated until validation is passed. It's not a bug as such, and it's useful in many cases, but it can also be less than useful in some cases. Such as this.

The way around this while still keeping the benefits of using ngModel based validation (including form validity etc) is to set the validation step 'manually' by using $setValidity. To do this you would remove the ng-minlength attribute and use an ng-change callback.

You will also need to make sure that your form element is named and part of a named form, in order to get access to the relevant ngModelController.

<form name="formCtrl">
    <textarea ng-trim="false" 
              ng-model="form.text"
              ng-change="checkTextLength()" 
              name="formText">
    </textarea>
    <p>{{240 - form.text.length}} left</p>
</form>

And then in your controller, assuming you are just using $scope here:

  $scope.checkTextLength = function(){
     if($scope.form.text.length < 20){
          $scope.formCtrl.formText.$setValidity('minlength', false);
     } else{
          $scope.formCtrl.formText.$setValidity('minlength', true);
     }

    if($scope.form.text.length > 240){
          $scope.formCtrl.formText.$setValidity('maxlength', false);
     } else{
          $scope.formCtrl.formText.$setValidity('maxlength', true);
     }
  }

I forked your codepen to create a working example here. There I also added a bit to the template to show the validity state.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, by adjusting a little your implementation I have been able to let it work properly.
1

This is probably because angular isn't saving the the internal state of the textarea to its form.text variable until you hit the minlength. It should be very easy to validate this by changing that <p> tag's inner text from form.text.length to form.text.

If at all possible, I would remove the minlength attribute from your textarea and add that as a validation step later on -- Definitely inform the user somehow with a label on-screen though by keeping track of it.

1 Comment

Thanks for your answer but this solution doesn't fit exactly my needs!

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.