Front End

15 jun, 2015

AngularJS: validação customizada com diretivas

Publicidade

Neste artigo, vamos criar uma diretiva simples em AngularJS para fazer uma validação customizada.

Depois de dar uma olhada na documentação de AngularJS, nós podemos perceber que não existe uma validação de input para um número exato de caracteres. Então, se precisamos que uma string seja válida somente se tivermos dois caracteres nós teremos que criar nossa própria validação customizada em AngularJS com uma diretiva.

Primeiro, vamos criar nossa estrutura seguindo a abordagem do John Papa:

(function() {
    'use strict';

    angular
        .module('app')
        .directive('ngLength', NgLength);

    function NgLength() {
    }
})();

Agora, vamos restringir nossa diretiva apenas a atributos (restrict: ‘A’) e criar uma função de ligação (link):

(function() {
    'use strict';

    angular
        .module('app')
        .directive('ngLength', NgLength);

    function NgLength() {
        return {
            restrict: 'A',
            link: function($scope, $element, $attrs){
            }
        };
    }
})();

E agora nós precisamos adicionar um $scope.$watch para ficar lendo o input do usuário. Para isso, nós vamos dar um require em ngModel dentro da nossa diretiva.

(function() {
    'use strict';

    angular
        .module('app')
        .directive('ngLength', NgLength);

    function NgLength() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function($scope, $element, $attrs, ngModel) {
                $scope.$watch($attrs.ngModel, function(value) {

                });
            }
        }
    }
})();

Agora a única coisa que falta é a validação. No nosso caso, nós vamos checar se value.length === 2 e então usar o método $setValidity para aplicar a validação em si:

(function() {
    'use strict';

    angular
        .module('app')
        .directive('ngLength', NgLength);

    function NgLength() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function($scope, $element, $attrs, ngModel) {
                $scope.$watch($attrs.ngModel, function(value) {
                    var isValid = (value.length === 2);
                    ngModel.$setValidity($attrs.ngModel, isValid);
                });
            }
        }
    }
})();

E pronto! Agora, para usar essa diretiva, nós vamos simplesmente chamá-la do nosso input, assim:

<input type='text' ng-model='vm.age' ng-length />

Mas isso não é muito inteligente. Se nós precisamos, por exemplo, da mesma validação, mas para uma string com 5 caracteres, por exemplo, nós vamos precisar criar outra diretiva. Para evitar esse tipo de trabalho, nós podemos mudar nossa diretiva para aceitar uma variável que saberá quantos caracteres nosso input precisará ter para ser válido:

(function() {
    'use strict';

    angular
        .module('app')
        .directive('ngLength', NgLength);

    function NgLength() {
        return {
            restrict: 'A',
            require: 'ngModel',
            scope: {
                ngLength: '='
            }
            link: function($scope, $element, $attrs, ngModel) {
                $scope.$watch($attrs.ngModel, function(value) {
                    var isValid = (value.length === $scope.ngLength);
                    ngModel.$setValidity($attrs.ngModel, isValid);
                });
            }
        }
    }
})();

E agora podemos chamar assim:

<input type='text' ng-model='vm.age' ng-length='2' />  
<input type='text' ng-model='vm.name' ng-length='5' />

Certo? Ficou alguma dúvida, tem algum comentário ou perdeu algum passo? Deixe abaixo seu comentário!

***

Publicado originalmente em inglês, no blog pessoal do autor.