Validação de formulário AngularJS no envio: $dirty, $valid e $invalid
⚡ Resumo Inteligente
A validação de formulários no AngularJS verifica se os dados inseridos em um formulário estão corretos e completos antes de chegarem ao servidor. Quatro abordagens são abordadas aqui, desde atributos HTML5 simples, passando por propriedades de escopo, até módulos de validação automática.
Validação de formulário em AngularJS
Validação de formulário Em AngularJS, a validação é o processo de garantir que os dados inseridos em um formulário estejam corretos e completos. Quando um usuário envia o formulário, a validação ocorre antes que os dados sejam enviados ao servidor. O processo de validação garante, da melhor forma possível, que os campos de entrada foram preenchidos corretamente.
Num exemplo prático, imagine um site que exige o preenchimento de um formulário de cadastro antes de conceder acesso completo. A página de cadastro teria campos para nome de usuário, senha, endereço de e-mail e assim por diante.
Por exemplo, o endereço de e-mail precisa sempre estar no formato nomedeusuário@site.domínioSe alguém inserir apenas o nome de usuário, a validação deverá falhar. A validação realiza essas verificações básicas antes que os dados sejam enviados ao servidor para processamento posterior.
⚠️ Nota sobre a versão: O AngularJS (versão 1.x) chegou ao fim de seu ciclo de vida em 31 de dezembro de 2021 e não receberá mais atualizações de segurança. As técnicas descritas abaixo ainda são válidas para aplicações legadas; o Angular moderno realiza a mesma tarefa com formulários baseados em templates ou reativos.
Validação de formulário usando HTML5
A validação de formulários é o processo de pré-validar as informações inseridas em um formulário web antes de serem enviadas ao servidor. Validar no lado do cliente é preferível, pois adiciona muito menos sobrecarga do que apresentar o formulário novamente após uma requisição ao servidor.
O exemplo abaixo mostra um formulário de cadastro simples no qual o usuário insere um nome de usuário, senha, endereço de e-mail e idade. O formulário possui controles de validação que garantem que as informações sejam inseridas corretamente.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> <link rel="stylesheet" href="lib/bootstrap.css"> <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script> </head> <body ng-app="sampleApp"> <h1>Guru99 Global Event</h1> <form> Enter your user name: <input type="text" name="name" required><br><br> Enter your password: <input type="password" name="password"><br><br> Enter your email: <input type="email" name="email"><br><br> Enter your age: <input type="number" name="age"><br><br> <input type="submit" value="Submit"> </form> </body> </html>
⚠️ Correções aplicadas a todos os anúncios desta página. Os originais declararam chrset="UTF 8", que não é um atributo válido nem uma codificação válida, e carregou o AngularJS três vezes — angular-route.js primeiro, que gera um erro porque o módulo de roteamento se registra em um framework que não foi carregado, depois angular.min.js e angular.js, a mesma biblioteca duas vezes. Eles também puxaram bootstrap.css através de uma abordagem <script> tag, portanto nenhum estilo foi aplicado. Cada listagem agora carrega uma biblioteca, versão 1.8.3, e vincula a folha de estilo corretamente. O espaçamento do layout é construído a partir de repetições. As entidades foram removidas.
Code Explicação
- Para o tipo de entrada de texto, o
requiredO atributo significa que a caixa de texto não pode estar vazia quando o formulário for enviado. - O próximo tipo de entrada é senha. Como o tipo está marcado como senha, o texto inserido no campo fica mascarado.
- Como o tipo de entrada foi especificado como e-mail, o texto na caixa deve corresponder ao padrão. nome@site.domínio.
- Quando o tipo de entrada está marcado como número, os caracteres digitados pelo teclado simplesmente não são aceitos pelo campo.
saída
Para ver a validação em ação, clique em Enviar sem digitar nada.
Aparece uma janela pop-up informando que o campo precisa ser preenchido, portanto, o controle marcado como obrigatório bloqueia o envio quando está vazio.
Ao inserir um valor no campo de senha, o símbolo '*' é exibido, ocultando os caracteres.
Ao inserir um endereço de e-mail inválido e clicar em Enviar, uma janela pop-up solicita o símbolo @. Por fim, os caracteres digitados no campo de idade nunca aparecem, pois o campo aceita apenas números.
Os pop-ups do navegador são rápidos de configurar, mas seu texto e estilo não podem ser alterados. É aí que entram as propriedades de validação do AngularJS.
Validação de formulário usando $dirty, $valid, $invalid, $pristine
AngularJS Fornece suas próprias propriedades para validação. As seguintes propriedades são expostas em cada controle nomeado:
- $sujo – O usuário interagiu com o controle
- $válido – O conteúdo do campo é válido
- $inválido – O conteúdo do campo é inválido
- $ impecável – O usuário ainda não interagiu com o controle
A seguir estão os passos para realizar a validação em AngularJS.
Passo 1) Use o novalidate A propriedade é definida ao declarar o formulário. Isso informa ao navegador que a validação será feita pelo AngularJS.
Passo 2) Certifique-se de que o formulário tenha um nome definido, pois esse nome é usado para acessar o estado de validação.
Passo 3) Certifique-se de que cada controle também tenha um name atributo, pelo mesmo motivo. Um controle sem nome nunca é registrado no formulário.
Passo 4) Use o ng-show diretiva para verificar as propriedades $dirty, $invalid e $valid.
O exemplo abaixo possui um único campo de texto no qual o usuário insere o nome de um tópico. Se o campo for deixado em branco, um erro de validação será acionado e a mensagem será exibida.
<form ng-app="DemoApp" ng-controller="DemoController" name="myForm" novalidate> <p>Topic Name:<br> <input type="text" name="user" ng-model="user" required> <span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid"> <span ng-show="myForm.user.$error.required">Username is required</span> </span> </p> <p> <input type="submit" ng-disabled="myForm.$invalid"> </p> </form> <script> var app = angular.module("DemoApp", []); app.controller("DemoController", function($scope) { // Seed the textbox so the form starts in a valid state $scope.user = "AngularJS"; }); </script>
⚠️ Dois erros de lógica corrigidos. O original desativou o botão com ng-disabled="myForm.user.$dirty && myForm.user.$invalid". Porque $dirty é falso até que o usuário toque no campo; o botão permanece pressionado. habilitado em um formulário vazio e intocado, exatamente o caso que deveria bloquear; myForm.$invalid Abrange ambos. O original também envolvia o valor padrão em $scope.Display = function () { $scope.user = 'Angular'; }, uma função que nunca foi chamada, então a caixa de texto abriu vazia apesar do texto afirmar que mostrava “AngularJS”. A atribuição agora é feita diretamente, com o valor entre aspas do texto circundante.
Code Explicação
- O formulário recebeu o nome “myForm”. Isso é necessário para acessar seus controles de validação.
- O
novalidateA propriedade impede que o navegador faça a validação, permitindo que o AngularJS a execute em seu lugar. - A diretiva ng-show verifica as propriedades “$dirty” e “$invalid”. Se a caixa de texto foi modificada, $dirty é verdadeiro; se o seu valor estiver vazio, $invalid é verdadeiro. Quando ambas são verdadeiras, o elemento span com o texto em vermelho é exibido.
- A verificação aninhada lê a propriedade “$error.required”, que é verdadeira sempre que um controle obrigatório não tiver valor, e exibe “O nome de usuário é obrigatório”.
- O botão de envio está desativado.
ng-disabledsempre que o formulário como um todo for inválido. - O controlador define o valor inicial da caixa de texto como “AngularJS”, para que o formulário seja aberto em um estado válido e a validação seja mais fácil de observar à medida que o texto é apagado.
saída
Quando o formulário é exibido pela primeira vez, a caixa de texto mostra "AngularJS" e o botão de envio está habilitado. Assim que o texto é removido, a mensagem de erro aparece e o botão é desabilitado.
A captura de tela acima mostra duas coisas:
- O botão de envio está desativado.
- Não há nome de tópico na caixa de texto Tópico, portanto, a mensagem de erro "Nome de usuário obrigatório" é exibida.
Como exibir erros de validação com ngMessages
O padrão acima funciona, mas não é escalável. Um campo com quatro restrições precisa de quatro restrições aninhadas. ng-show intervalos, e quando vários deles falham ao mesmo tempo, todas as mensagens aparecem juntas. ngMessages O módulo, fornecido separadamente pela equipe do AngularJS, resolve ambos os problemas: ele exibe uma mensagem por vez, na ordem em que as mensagens são escritas.
Carregue o módulo e adicione-o como uma dependência.
<script src="https://code.angularjs.org/1.8.3/angular-messages.js"></script> <script> angular.module("DemoApp", ["ngMessages"]); </script>
A marcação passa então a ser lida como uma lista de regras em vez de uma pilha de condições.
<input type="text" name="user" ng-model="user" required ng-minlength="4" ng-maxlength="20"> <div style="color:red" ng-messages="myForm.user.$error" ng-if="myForm.user.$dirty"> <div ng-message="required">A topic name is required</div> <div ng-message="minlength">Use at least 4 characters</div> <div ng-message="maxlength">Use no more than 20 characters</div> </div>
Três detalhes fazem com que isso funcione bem na prática. O ng-messages O atributo aponta para o controle. $error em vez de um booleano, portanto nenhuma condição precisa ser repetida. Apenas a primeira correspondência. ng-message renderiza, o que significa que um campo em branco reporta que é obrigatório em vez de também reclamar sobre seu comprimento. Adicionando ng-messages-multiple Inverte esse comportamento quando cada falha realmente precisa ser listada.
Embrulheping o bloco em ng-if="myForm.user.$dirty" Mantém o formulário silencioso até que o usuário tenha digitado algo. Substituindo $touched pela $dirty Isso atrasa ainda mais a mensagem, até que o foco saia do campo, o que geralmente é a opção mais amigável em um formulário de inscrição longo.
Uma ressalva: ngMessages Como os arquivos são enviados separadamente, esquecer a tag de script ou a dependência do módulo faz com que o bloco não renderize nada, sem nenhum erro no console para explicar o problema.
Escrever mensagens à mão é preciso, mas repetitivo. A próxima seção aborda um módulo que as gera automaticamente.
Validação de formulário usando AngularJS Auto Validate
O AngularJS pode validar automaticamente todos os controles de um formulário, sem a necessidade de código personalizado para a validação ou para as mensagens de erro. Isso é possível graças à inclusão de um módulo da comunidade chamado "jcs-autoValidate".
Com este módulo instalado, não é necessário nenhum código especial para executar a validação ou exibir as mensagens; tudo é tratado internamente pelo jcs-autoValidate.
O exemplo abaixo apresenta um formulário simples com um único campo de texto obrigatório. Uma mensagem de erro é exibida caso o campo não seja preenchido.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> <link rel="stylesheet" href="lib/bootstrap.css"> <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script> <script src="lib/jcs-auto-validate.min.js"></script> </head> <body> <h1>Guru99 Event</h1> <div ng-app="DemoApp"> <form name="myForm" novalidate> <div class="form-group"> <label for="user">Topic Name:</label> <input class="form-control" type="text" id="user" name="user" ng-model="user" required> </div> <div class="form-group"> <input type="submit"> </div> </form> </div> <script> var app = angular.module('DemoApp', ['jcs-autoValidate']); </script> </body> </html>
⚠️ Correção: o original identificou o controle com id="user" somente. O jcs-autoValidate acessa o controle através do formulário, portanto, um name O atributo é obrigatório e a mensagem nunca apareceu sem ele. O original também carregava duas versões diferentes do AngularJS, 1.6.4 do Google CDN junto com 1.6.9, e nunca vinculado Bootstrap embora o exemplo dependa de seu form-group e form-control classes para posicionar o texto de erro.
💡 Nota: jcs-autoValidate é um projeto da comunidade e não recebe mais manutenção ativa. Ele ainda pode ser usado em aplicações AngularJS existentes, mas o recurso integrado de validação não está mais disponível. ngMessages A abordagem mostrada anteriormente é a escolha mais segura para qualquer novidade.
Code Explicação
- O script “jcs-auto-validate.js”, que contém toda a funcionalidade de validação automática, está incluído.
- Cada controle e sua div envolvente são colocados dentro de uma classe “form-group”, que é onde o módulo injeta sua mensagem.
- O controle carrega um ID e um
namee Bootstrap fornece oform-controlestilo. - O módulo “jcs-autoValidate” está listado como uma dependência do módulo AngularJS.
saída
Por padrão, o formulário é exibido exatamente como está escrito.
Ao enviar o formulário vazio, é exibida a mensagem "Este campo é obrigatório", gerada inteiramente pelo jcs-autoValidate. Após a validação do formulário, resta saber o que o usuário vê durante o envio.
Feedbacks de usuários com botões Ladda
Os botões “Ladda” são uma estrutura construída sobre JavaScript Isso confere aos botões um efeito visual quando são pressionados.
Se um botão receber o atributo “ladda” e for pressionado, um efeito de rotação será exibido. Diferentes estilos de dados estão disponíveis para efeitos visuais adicionais.
O exemplo abaixo mostra um formulário simples com um botão de envio. Ao pressionar o botão, um efeito de rotação aparece sobre ele.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> <link rel="stylesheet" href="lib/bootstrap.css"> <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script> <script src="lib/angular-ladda.min.js"></script> </head> <body> <h1>Guru99 Event</h1> <div ng-app="DemoApp" ng-controller="DemoController"> <form name="myForm" novalidate ng-submit="submit()"> <button class="btn btn-primary" type="submit" ladda="submitting" name="sbutton" data-style="expand-right">Submit</button> </form> </div> <script> var app = angular.module('DemoApp', ['angular-ladda']); app.controller('DemoController', function($scope) { $scope.submitting = false; $scope.submit = function() { $scope.submitting = true; }; }); </script> </body> </html>
⚠️ Correção: o original carregado angular-ladda.js e angular-ladda.min.js juntos, o que registra o mesmo módulo duas vezes e, novamente, puxa duas versões do AngularJS. Também listou jcs-autoValidate como uma dependência que este exemplo nunca usa. Uma cópia de cada biblioteca é carregada aqui.
Code Explicação
- O "ng-enviarA diretiva “ladda” chama uma função chamada “submit”, que altera o atributo ladda do botão.
- O atributo `ladda` pertence ao framework Ladda e é o que adiciona o efeito de rotação. Seu valor está vinculado ao...
submittingvariável. - A propriedade data-style é outro atributo do Ladda que seleciona um efeito visual diferente.
- O módulo 'angular-ladda' precisa ser adicionado à aplicação AngularJS para que o framework funcione.
- O
submittingA variável é inicializada com o valor falso, portanto o botão inicia sem o efeito de rotação. - A função de envio define
submittingpara verdadeiro, o que aplica o efeito. Em uma aplicação real, seria redefinido para falso assim que o servidor respondesse; caso contrário, o botão ficaria girando indefinidamente.
saída
Quando o formulário é exibido pela primeira vez, o botão de envio é mostrado em sua forma simples.
Quando o botão é pressionado, o submitting A variável é definida como verdadeira. Esse valor chega ao atributo “ladda” do botão, produzindo o efeito de giro.















