Estoy usando este método: http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview para validar solo los campos en el desenfoque. Esto funciona bien, pero también me gustaría validarlos (y así mostrar los errores de esos campos, si los hubiera) cuando el usuario hace clic en el botón 'enviar' (no es un envío real sino una llamada de data-ng-click a una función)
¿Hay alguna forma de activar la validación en todos los campos nuevamente al hacer clic en ese botón?
Respuestas:
Lo que funcionó para mí fue usar la
$setSubmitted
función, que aparece por primera vez en los documentos angulares en la versión 1.3.20.En el evento de clic en el que quería activar la validación, hice lo siguiente:
vm.triggerSubmit = function() { vm.homeForm.$setSubmitted(); ... }
Eso fue todo lo que necesité para mí. Según los documentos, "establece el formulario en su estado enviado". Se menciona aquí .
fuente
ng-messages
y solo los muestra cuando $ error && $ están sucios .form
... Tuve que recorrer todas las entradas y llamarlas$setDirty()
.Lo sé, es un poco tarde para responder, pero todo lo que necesitas hacer es ensuciar todos los formularios. Eche un vistazo al siguiente fragmento:
angular.forEach($scope.myForm.$error.required, function(field) { field.$setDirty(); });
y luego puede verificar si su formulario es válido usando:
if($scope.myForm.$valid) { //Do something }
y finalmente, supongo, querrás cambiar tu ruta si todo se ve bien:
$location.path('/somePath');
Editar : el formulario no se registrará en el alcance hasta que se active el evento de envío. Simplemente use la directiva ng-submit para llamar a una función, y envuelva lo anterior en esa función, y debería funcionar.
fuente
ng-submit
directiva de activación programática ?ng-submit
simplemente vincula una función al evento de envío, ¿por qué no llamar a esa función?En caso de que alguien vuelva a esto más tarde ... Nada de lo anterior funcionó para mí. Así que indagué en las entrañas de la validación de formas angulares y encontré la función que llaman para ejecutar validadores en un campo determinado. Esta propiedad se llama convenientemente
$validate
.Si tiene un formulario con nombre
myForm
, puede llamar mediante programaciónmyForm.my_field.$validate()
para ejecutar la validación de campo. Por ejemplo:<div ng-form name="myForm"> <input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()"> </div>
Tenga en cuenta que la llamada
$validate
tiene implicaciones para su modelo. De los documentos angulares para ngModelCtrl. $ Validar:Entonces, si planea hacer algo con el valor del modelo no válido (como mostrar un mensaje que se lo indique), debe asegurarse de que
allowInvalid
esté configuradotrue
para su modelo.fuente
allowInvalid
se puede leer aquí: github.com/angular/angular.js/issues/10035Puede usar Angular-Validator para hacer lo que quiera. Es estúpido y simple de usar.
Va a:
$dirty
o ensubmit
$dirty
o el formularioVer la demo
Ejemplo
<form angular-validator angular-validator-submit="myFunction(myBeautifulForm)" name="myBeautifulForm"> <!-- form fields here --> <button type="submit">Submit</button> </form>
Si el campo no pasa el
validator
, el usuario no podrá enviar el formulario.Consulte los casos de uso y ejemplos del validador angular para obtener más información.
Descargo de responsabilidad: soy el autor de Angular-Validator
fuente
Bueno, la forma angular sería dejar que maneje la validación, ya que lo hace en cada cambio de modelo, y solo mostrar el resultado al usuario, cuando lo desee.
En este caso tú decides cuando mostrar los errores, solo tienes que poner una bandera: http://plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview
Hasta donde yo sé, hay un problema archivado en angular para permitirnos tener un control de formulario más avanzado. Como no está resuelto, usaría esto en lugar de reinventar todos los métodos de validación existentes.
editar: Pero si insiste en su camino, aquí está su violín modificado con validación antes de enviar. http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview El controlador transmite un evento cuando se hace clic en el botón, y la directiva hace la magia de validación.
fuente
Un enfoque es forzar a que todos los atributos estén sucios. Puedes hacer eso en cada controlador, pero se vuelve muy complicado. Sería mejor tener una solución general.
La forma más fácil que se me ocurrió fue utilizar una directiva
Aquí está la directiva
myModule.directive('submit', function() { return { restrict: 'A', link: function(scope, formElement, attrs) { var form; form = scope[attrs.name]; return formElement.bind('submit', function() { angular.forEach(form, function(field, name) { if (typeof name === 'string' && !name.match('^[\$]')) { if (field.$pristine) { return field.$setViewValue(field.$value); } } }); if (form.$valid) { return scope.$apply(attrs.submit); } }); } }; });
Y actualice su formulario html, por ejemplo:
se convierte en:
<form name='myForm' novalidate submit='justDoIt()'>
Vea un ejemplo completo aquí: http://plunker.co/edit/QVbisEK2WEbORTAWL7Gu?p=preview
fuente
Aquí está mi función global para mostrar los mensajes de error del formulario.
function show_validation_erros(form_error_object) { angular.forEach(form_error_object, function (objArrayFields, errorName) { angular.forEach(objArrayFields, function (objArrayField, key) { objArrayField.$setDirty(); }); }); };
Y en mis controladores,
if ($scope.form_add_sale.$invalid) { $scope.global.show_validation_erros($scope.form_add_sale.$error); }
fuente
Basado en la respuesta de Thilak, pude encontrar esta solución ...
Dado que los campos de mi formulario solo muestran mensajes de validación si un campo no es válido y el usuario lo ha tocado, pude usar este código activado por un botón para mostrar mis campos no válidos:
// Show/trigger any validation errors for this step angular.forEach(vm.rfiForm.stepTwo.$error, function(error) { angular.forEach(error, function(field) { field.$setTouched(); }); }); // Prevent user from going to next step if current step is invalid if (!vm.rfiForm.stepTwo.$valid) { isValid = false; }
<!-- form field --> <div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }"> <!-- field label --> <label class="control-label">Suffix</label> <!-- end field label --> <!-- field input --> <select name="Parent_Suffix__c" class="form-control" ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes" ng-model="rfi.contact.Parent_Suffix__c" /> <!-- end field input --> <!-- field help --> <span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched"> <span ng-message="required">this field is required</span> </span> <!-- end field help --> </div> <!-- end form field -->
fuente
Nota: Sé que esto es un truco, pero fue útil para Angular 1.2 y versiones anteriores que no proporcionaban un mecanismo simple.
La validación se activa en el evento de cambio , por lo que algunas cosas como cambiar los valores mediante programación no lo activarán. Pero la activación del evento de cambio activará la validación. Por ejemplo, con jQuery:
$('#formField1, #formField2').trigger('change');
fuente
angular way
.Para validar todos los campos de mi formulario cuando quiero, hago una validación en cada campo de controles $$ como este:
angular.forEach($scope.myform.$$controls, function (field) { field.$validate(); });
fuente
Me gusta este enfoque para manejar la validación al hacer clic en el botón.
No es necesario invocar nada desde el controlador,
todo se maneja con una directiva.
en github
fuente
Puedes probar esto:
// The controller $scope.submitForm = function(form){ //Force the field validation angular.forEach(form, function(obj){ if(angular.isObject(obj) && angular.isDefined(obj.$setDirty)) { obj.$setDirty(); } }) if (form.$valid){ $scope.myResource.$save(function(data){ //.... }); } }
<!-- FORM --> <form name="myForm" role="form" novalidate="novalidate"> <!-- FORM GROUP to field 1 --> <div class="form-group" ng-class="{ 'has-error' : myForm.field1.$invalid && myForm.field1.$dirty }"> <label for="field1">My field 1</label> <span class="nullable"> <select name="field1" ng-model="myresource.field1" ng-options="list.id as list.name for list in listofall" class="form-control input-sm" required> <option value="">Select One</option> </select> </span> <div ng-if="myForm.field1.$dirty" ng-messages="myForm.field1.$error" ng-messages-include="mymessages"></div> </div> <!-- FORM GROUP to field 2 --> <div class="form-group" ng-class="{ 'has-error' : myForm.field2.$invalid && myForm.field2.$dirty }"> <label class="control-label labelsmall" for="field2">field2</label> <input name="field2" min="1" placeholder="" ng-model="myresource.field2" type="number" class="form-control input-sm" required> <div ng-if="myForm.field2.$dirty" ng-messages="myForm.field2.$error" ng-messages-include="mymessages"></div> </div> </form> <!-- ... --> <button type="submit" ng-click="submitForm(myForm)">Send</button>
fuente
Hice algo siguiente para que funcione.
<form name="form" name="plantRegistrationForm"> <div ng-class="{ 'has-error': (form.$submitted || form.headerName.$touched) && form.headerName.$invalid }"> <div class="col-md-3"> <div class="label-color">HEADER NAME <span class="red"><strong>*</strong></span></div> </div> <div class="col-md-9"> <input type="text" name="headerName" id="headerName" ng-model="header.headerName" maxlength="100" class="form-control" required> <div ng-show="form.$submitted || form.headerName.$touched"> <span ng-show="form.headerName.$invalid" class="label-color validation-message">Header Name is required</span> </div> </div> </div> <button ng-click="addHeader(form, header)" type="button" class="btn btn-default pull-right">Add Header </button> </form>
En su controlador puede hacer;
addHeader(form, header){ let self = this; form.$submitted = true; ... }
También necesitas algo de CSS;
.label-color { color: $gray-color; } .has-error { .label-color { color: rgb(221, 25, 29); } .select2-choice.ui-select-match.select2-default { border-color: #e84e40; } } .validation-message { font-size: 0.875em; } .max-width { width: 100%; min-width: 100%; }
fuente