AngularJS: ¿Hay alguna forma de determinar qué campos hacen que un formulario no sea válido?

94

Tengo el siguiente código en una aplicación AngularJS, dentro de un controlador, que se llama desde una función ng-submit, que pertenece a un formulario con nombre profileForm:

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

Dentro de esta función, ¿hay alguna forma de averiguar qué campos están causando que todo el formulario se llame inválido?

GSto
fuente

Respuestas:

92

nameLa información de validación de cada entrada se expone como propiedad en formel nombre de en 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 }

Las propiedades expuestas son $pristine, $dirty, $valid, $invalid, $error.

Si desea iterar sobre los errores por alguna razón:

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

Cada regla errónea se expondrá en $ error.

Aquí hay un plunkr para jugar con http://plnkr.co/edit/zCircDauLfeMcMUSnYaO?p=preview

Umur Kontacı
fuente
5
Advertencia a otros que caen en mi trampa: debes especificar el nameatributo de la entrada para verla en $ name (por supuesto). El hecho de que AngularJS se vincule a una propiedad del modelo sin la necesidad de un nombre puede hacer que sea difícil diagnosticar qué entrada no es válida.
Bernhard Hofmann
La sugerencia de usar el objeto $ scope para determinar qué campos hacen que un formulario sea inválido me ayudó.
Ram
26

Para comprobar qué campo del formulario no es válido

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

esto generará la matriz de campos no válidos del formulario

Shivek Parmar
fuente
15

Si desea ver qué campos están alterando su validación y tiene jQuery para ayudarlo, simplemente busque la clase "ng-invalid" en la consola de JavaScript.

$('.ng-invalid');

Enumerará todos los elementos DOM que fallaron la validación por cualquier motivo.

Thassae Santos
fuente
12

Puede recorrer 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
fuente
2
Esto funcionó para mí, excepto que en lugar de form. $ Error.pattern, utilicé form. $ Error.required. No hay propiedad de "patrón". ¿Eso cambió o algo así?
Anthony
3
@Anthony que depende del tipo de validación =) ver yearofmoo.com/2014/09/…
oCcSking
2

Cuando algún campo no sea válido, si intenta obtener su valor, lo será undefined.

Supongamos que tiene una entrada de texto adjunta $scope.mynumque es válida solo cuando escribe números y lo ha escrito ABC.

Si intenta obtener el valor de $scope.mynum, sería undefined; no devolvería el ABC.

(Probablemente sepas todo esto, pero de todos modos)

Entonces, usaría una matriz que tenga todos los elementos que necesitan validación que he agregado al alcance y usaría un filtro (con subrayado.js, por ejemplo) para verificar cuáles regresan como typeof undefined.

Y esos serían los campos que causan el estado inválido.

chris-l
fuente
1
Dependiendo de la validación utilizada (por ejemplo, validadores personalizados), es posible que el modelo no siempre esté indefinido cuando no sea válido.
Stewie
@ Stewie Hmm sí, eso es muy cierto. Supongo que no funciona en todos los casos. ^ _ ^
chris-l
2

Quería mostrar todos los errores en la información sobre herramientas del botón Guardar deshabilitado, para que el usuario sepa por qué está deshabilitado en lugar de desplazarse hacia arriba y hacia abajo en el formulario largo.

Nota: recuerde agregar la propiedad de nombre a los campos en su formulario

    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();
    }
Sebastián Castaldi
fuente
2

Para mi aplicación, muestro un error como este:

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

si desea ver todo, simplemente usuario 'err' que mostrará algo como esto:

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

No tan bien formateado, pero verá estas cosas allí ...

hecho un desastre
fuente
1

Si desea encontrar campos que invaliden el formulario en la interfaz de usuario sin programación, simplemente haga clic con el botón derecho en inspeccionar (abrir herramientas de desarrollador en la vista de elementos) y luego busque ng-invalid con ctrl + f dentro de esta pestaña. Luego, para cada campo para el que encuentre una clase ng-invalid, puede verificar si al campo no se le da ningún valor mientras es requerido, u otras reglas que pueda violar (formato de correo electrónico no válido, definición fuera de rango / máximo / mínimo, etc.) . Esta es la manera más fácil.

ozanmut
fuente