Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs minlength validation stop characters counter

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

like image 716
Ayeye Brazo Avatar asked Apr 16 '26 12:04

Ayeye Brazo


1 Answers

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.

like image 56
ChrisM Avatar answered Apr 18 '26 02:04

ChrisM