Creating Your Own Custom Angular Maxlength Directive For Readonly Restrictions

19 June 2015

Here's an example - you've got a field (eg, for customer comments) where you'd like to limit the maximum number of characters entered on the frontend. Pretty simple, you just throw on ng-maxlength, right?

<textarea class="form-control msd-elastic"                            
    ng-model="comments"
    ng-maxlength="100"
    name="comments"></textarea>

But now, you also want administrators to be able to modify those comments (possibly surpassing the 100 character limit). So you pull some JSON data (with 100+ characters) from your endpoint, and load the page...and to your surprise, the text area is completely empty.

This is because the default behaviour for ng-maxlength is to set the data to undefined if it surpasses the specified value (instead of becoming a read only field).

The easiest way to get around this is to create your own directive that validates and, instead of messing around with your model, sets the form validity and provides an error message.

A sample directive taken from Stack Overflow:

<textarea my-maxlength="15" ng-model="result"></textarea>

And in your javascript:

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

Now, your page should be able to render and display data larger than the maxlength - but when the user attempts to edit the contents, they won't be able to submit any changes until the total length is less than or equal to maxlength.

Note that you can still also use ng-message with your new directive - the error name is the first property provided to the $setValidity method:

<div ng-message="my-maxlength">Your comment must not exceed 15 characters</div>

Honestly, I feel like this should be the default behaviour for Angular (as in, non-destructive validation), but at least it's not too difficult to supplant.

Tags: AngularJS, ng-maxlength, validation

Add a Comment

No Comments