AngularJS: Existe alguma maneira de determinar quais campos estão invalidando um formulário?

94

Eu tenho o seguinte código em um aplicativo AngularJS, dentro de um controlador, que é chamado de uma função ng-submit, que pertence a um formulário com nome profileForm:

$scope.updateProfile = function() {
  if($scope.profileForm.$invalid) { 
    //error handling..
  }
  //etc.
};

Dentro dessa função, há alguma maneira de descobrir quais campos estão fazendo com que todo o formulário seja chamado de inválido?

GSto
fonte

Respostas:

92

Cada nameinformação de validação de entrada é exposta como propriedade em formnome de em scope.

HTML

<form name="someForm" action="/">
    <input name="username" required />
    <input name="password" type="password" required />
</form>

JS

$scope.someForm.username.$valid
// > false
$scope.someForm.password.$error
// > { required: true }

As propriedades expostas são $pristine, $dirty, $valid, $invalid, $error.

Se você quiser iterar os erros por algum motivo:

$scope.someForm.$error
// > { required: [{$name: "username", $error: true /*...*/},
//                {$name: "password", /*..*/}] }

Cada regra com erro será exposta em $ error.

Aqui está um plunkr para brincar com http://plnkr.co/edit/zCircDauLfeMcMUSnYaO?p=preview

Umur Kontacı
fonte
5
Aviso aos outros que caem na minha armadilha - você deve especificar o nameatributo da entrada para vê-lo em $ name (é claro). O fato de AngularJS se vincular a uma propriedade de modelo sem a necessidade de um nome pode resultar na dificuldade de diagnosticar qual entrada é inválida.
Bernhard Hofmann
A dica de usar o objeto $ scope para determinar quais campos estão tornando um formulário inválido me ajudou.
Ram de
26

Para verificar qual campo do formulário é inválido

console.log($scope.FORM_NAME.$error.required);

isso irá gerar a matriz de campos inválidos do formulário

Shivek Parmar
fonte
15

Se você quiser ver quais campos estão atrapalhando sua validação e tiver o jQuery para ajudá-lo, basta pesquisar a classe "ng-invalid" no console javascript.

$('.ng-invalid');

Ele listará todos os elementos DOM que falharam na validação por qualquer motivo.

Thassae Santos
fonte
12

Você pode fazer um loop form.$error.pattern.

$scope.updateProfile = function() {
    var error = $scope.profileForm.$error;
    angular.forEach(error.pattern, function(field){
        if(field.$invalid){
            var fieldName = field.$name;
            ....
        }
    });
}
zs2020
fonte
2
Isso funcionou para mim, exceto em vez de form. $ Error.pattern, usei form. $ Error.required. Não existe uma propriedade "padrão". Isso mudou ou algo assim?
Anthony
3
@Anthony que depende do tipo de validação =) ver yearofmoo.com/2014/09/…
oCcSking
2

Quando algum campo for inválido, se você tentar obter seu valor, ele o será undefined.

Vamos dizer que você tem uma entrada de texto anexada $scope.mynumque é válida apenas quando você digita números e você digitou ABCnela.

Se você tentar obter o valor de $scope.mynum, seria undefined; ele não retornaria o ABC.

(Provavelmente você sabe de tudo isso, mas enfim)

Portanto, eu usaria uma matriz que tivesse todos os elementos que precisam de validação que adicionei ao escopo e usaria um filtro (com underscore.js, por exemplo) para verificar quais retornam como typeof undefined.

E esses seriam os campos que causam o estado inválido.

chris-l
fonte
1
Dependendo da validação usada (por exemplo, validadores personalizados), o modelo pode nem sempre ser indefinido quando inválido.
Stewie
@Stewie Hmm sim, isso é verdade. Acho que não funciona em todos os casos. ^ _ ^
chris-l
2

Eu queria exibir todos os erros na dica de ferramenta do botão Salvar desativado, para que o usuário soubesse por que está desativado em vez de rolar para cima e para baixo no formulário longo.

Observação: lembre-se de adicionar a propriedade do nome aos campos do seu formulário

    if (frm) {
        disable = frm.$invalid;
        if (frm.$invalid && frm.$error && frm.$error.required) {
            frm.$error.required.forEach(function (error) {
                disableArray.push(error.$name + ' is required'); 
            });
        }
    }
    if (disableArray.length > 0) {
        vm.disableMessage = disableArray.toString();
    }
Sebastian castaldi
fonte
2

Para meu aplicativo, eu exibo um erro como este:

<ul ng-repeat="errs in myForm.$error">
<li ng-repeat="err in errs">{{err.$name}}</li></ul>

se quiser ver tudo, basta o usuário 'errar' que exibirá algo assim:

 "$validators": {},
"$asyncValidators": {},
"$parsers": [],
"$formatters": [],
"$viewChangeListeners": [],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": { "required": true },
"$name": "errorfieldName",
"$options": {}

Não está bem formatado, mas você vai ver essas coisas lá ...

bagunçado
fonte
1

Se você quiser encontrar campo (s) que invalida o formulário na IU sem programação, apenas clique com o botão direito em inspecionar (abrir as ferramentas do desenvolvedor na visualização de elementos) e procurar por ng-invalid com ctrl + f dentro desta guia. Em seguida, para cada campo para o qual encontrar a classe ng-invalid, você pode verificar se o campo não recebe nenhum valor enquanto é obrigatório ou se outras regras que ele pode violar (formato de e-mail inválido, fora do intervalo / definição máx. / Mín., Etc.) . Esta é a maneira mais fácil.

Ozanmut
fonte