javascript - formulario - mostrar los mensajes de error de validación en submit in angularjs
validar formulario angular 6 (12)
Como uso Bootstrap 3, utilizo una directiva: (ver plunkr )
var ValidSubmit = [''$parse'', function ($parse) {
return {
compile: function compile(tElement, tAttrs, transclude) {
return {
post: function postLink(scope, element, iAttrs, controller) {
var form = element.controller(''form'');
form.$submitted = false;
var fn = $parse(iAttrs.validSubmit);
element.on(''submit'', function(event) {
scope.$apply(function() {
element.addClass(''ng-submitted'');
form.$submitted = true;
if(form.$valid) {
fn(scope, {$event:event});
}
});
});
scope.$watch(function() { return form.$valid}, function(isValid) {
if(form.$submitted == false) return;
if(isValid) {
element.removeClass(''has-error'').addClass(''has-success'');
} else {
element.removeClass(''has-success'');
element.addClass(''has-error'');
}
});
}
}
}
}
}]
app.directive(''validSubmit'', ValidSubmit);
y luego en mi HTML:
<form class="form-horizontal" role="form" name="form" novalidate valid-submit="connect()">
<div class="form-group">
<div class="input-group col col-sm-11 col-sm-offset-1">
<span class="input-group-addon input-large"><i class="glyphicon glyphicon-envelope"></i></span>
<input class="input-large form-control" type="email" id="email" placeholder="Email" name="email" ng-model="email" required="required">
</div>
<p class="col-sm-offset-3 help-block error" ng-show="form.$submitted && form.email.$error.required">please enter your email</p>
<p class="col-sm-offset-3 help-block error" ng-show="form.$submitted && form.email.$error.email">please enter a valid email</p>
</div>
</form>
ACTUALIZADO
En mi último proyecto, uso Ionic, así que tengo lo siguiente, que coloca automáticamente .valid
o .invalid
en los input-item
:
.directive(''input'', [''$timeout'', function ($timeout) {
function findParent(element, selector) {
selector = selector || ''item'';
var parent = element.parent();
while (parent && parent.length) {
parent = angular.element(parent);
if (parent.hasClass(selector)) {
break;
}
parent = parent && parent.parent && parent.parent();
}
return parent;
}
return {
restrict: ''E'',
require: [''?^ngModel'', ''^form''],
priority: 1,
link: function (scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0];
var form = ctrls[1];
if (!ngModelCtrl || form.$name !== ''form'' || attrs.type === ''radio'' || attrs.type === ''checkbox'') {
return;
}
function setValidClass() {
var parent = findParent(element);
if (parent && parent.toggleClass) {
parent.addClass(''validated'');
parent.toggleClass(''valid'', ngModelCtrl.$valid && (ngModelCtrl.$dirty || form.$submitted));
parent.toggleClass(''invalid'', ngModelCtrl.$invalid && (ngModelCtrl.$dirty || form.$submitted));
$timeout(angular.noop);
}
}
scope.$watch(function () {
return form.$submitted;
}, function (b, a) {
setValidClass();
});
var before = void 0;
var update = function () {
before = element.val().trim();
ngModelCtrl.$setViewValue(before);
ngModelCtrl.$render();
setValidClass();
};
element
.on(''focus'', function (e) {
if (ngModelCtrl.$pristine) {
element.removeClass(''$blurred'');
}
})
.on(''blur'', function (e) {
if (ngModelCtrl.$dirty) {
setValidClass();
element.addClass(''$blurred'');
}
}).on(''change'', function (e) {
if (form.$submitted || element.hasClass(''$blurred'')) {
setValidClass();
}
}).on(''paste'', function (e) {
if (form.$submitted || element.hasClass(''$blurred'')) {
setValidClass();
}
})
;
}
};
}])
y luego en el HTML:
<form name=''form'' novalidate="novalidate" ng-submit="auth.signin(form, vm)">
<label class="item item-input item-floating-label">
<span class="input-label">Email</span>
<input type="email" placeholder="Email" ng-model="vm.email" autofocus="true" required
>
</label>
<button ng-if="!posting" type="submit" class="item button-block item-balanced item-icon-right call-to-action">Login<i class="icon ion-chevron-right"></i>
</button>
y en el controlador:
self.signin = function (form, data) {
if (!form.$valid) return;
Authentication.emailLogin(data)
//...
entonces, ahora, en el CSS, puedes hacer cosas como estas:
.item.valid::before{
float: right;
font-family: "Ionicons";
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
text-rendering: auto;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #66cc33;
margin-right: 8px;
font-size: 24px;
content: "/f122";
}
.item.invalid::before{
float: right;
font-family: "Ionicons";
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
text-rendering: auto;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #ef4e3a;
margin-right: 8px;
font-size: 24px;
content: "/f12a";
/*
border-left: solid 2px #ef4e3a !important;
border-right: solid 2px #ef4e3a !important;
*/
}
¡MUCHO MÁS SIMPLE!
Tengo un formulario que necesita mostrar los mensajes de error de validación si se hace clic en enviar.
Aquí hay un plunker funciona
<form name="frmRegister" ng-submit="register();" novalidate>
<div>
<input placeholder="First Name" name="first_name" type="text" ng-model="user.firstName" required />
<span ng-show="frmRegister.first_name.$dirty && frmRegister.first_name.$error.required">First Name is required</span>
</div>
<div>
<input placeholder="Last Name" name="last_name" type="text" ng-model="user.lastName" required />
<span ng-show="frmRegister.last_name.$dirty && frmRegister.last_name.$error.required">Last Name is required</span>
</div>
<div>
<input placeholder="Email" name="email" type="email" ng-model="user.email" required />
<span ng-show="frmRegister.email.$dirty && frmRegister.email.$error.required">Email is required.</span>
<span ng-show="frmRegister.email.$dirty && frmRegister.email.$error.email">Invalid Email address.</span>
</div>
<input type="submit" value="Save" />
<span ng-show="registered">YOU ARE NOW REGISTERED USER</span>
</form>
La validación funciona normalmente cuando el usuario comienza a hacer cambios. Pero no muestra ningún mensaje de error si se hace clic en enviar sin ingresar nada.
¿Alguna idea de lograr esto ?. O de otra manera, ¿cómo puedo hacer que cada campo de entrada $ esté sucio cuando haga clic en el botón Enviar?
Encontré este violín http://jsfiddle.net/thomporter/ANxmv/2/ que hace un ingenioso truco para provocar la validación del control.
Básicamente declara que un miembro de ámbito submitted
y lo establece verdadero al hacer clic en enviar. El enlace de error del modelo usa esta expresión adicional para mostrar el mensaje de error como
submitted && form.email.$error.required
ACTUALIZAR
Como se señaló en el comentario de @Hafez (¡dele algunos votos al alza!), La solución Angular 1.3+ es simplemente:
form.$submitted && form.email.$error.required
G45,
Me enfrenté al mismo problema, he creado una directiva, por favor revise a continuación espero que pueda ser útil
Directiva:
app.directive(''formSubmitValidation'', function () {
return {
require: ''form'',
compile: function (tElem, tAttr) {
tElem.data(''augmented'', true);
return function (scope, elem, attr, form) {
elem.on(''submit'', function ($event) {
scope.$broadcast(''form:submit'', form);
if (!form.$valid) {
$event.preventDefault();
}
scope.$apply(function () {
scope.submitted = true;
});
});
}
}
};
})
HTML:
<form name="loginForm" class="c-form-login" action="" method="POST" novalidate="novalidate" form-submit-validation="">
<div class="form-group">
<input type="email" class="form-control c-square c-theme input-lg" placeholder="Email" ng-model="_username" name="_username" required>
<span class="glyphicon glyphicon-user form-control-feedback c-font-grey"></span>
<span ng-show="submitted || loginForm._username.$dirty && loginForm._username.$invalid">
<span ng-show="loginForm._username.$invalid" class="error">Please enter a valid email.</span>
</span>
</div>
<button type="submit" class="pull-right btn btn-lg c-theme-btn c-btn-square c-btn-uppercase c-btn-bold">Login</button>
</form>
Me gusta la solución de realcrowd the best.
HTML:
<form role="form" id="form" name="form" autocomplete="off" novalidate rc-submit="signup()">
<div class="form-group" ng-class="{''has-error'': rc.form.hasError(form.firstName)}">
<label for="firstName">Your First Name</label>
<input type="text" id="firstName" name="firstName" class="form-control input-sm" placeholder="First Name" ng-maxlength="40" required="required" ng-model="owner.name.first"/>
<div class="help-block" ng-show="rc.form.hasError(form.firstName)">{{rc.form.getErrMsg(form.firstName)}}</div>
</div>
</form>
javascript:
//define custom submit directive
var rcSubmitDirective = {
''rcSubmit'': [''$parse'', function ($parse) {
return {
restrict: ''A'',
require: [''rcSubmit'', ''?form''],
controller: [''$scope'', function ($scope) {
this.attempted = false;
var formController = null;
this.setAttempted = function() {
this.attempted = true;
};
this.setFormController = function(controller) {
formController = controller;
};
this.hasError = function (fieldModelController) {
if (!formController) return false;
if (fieldModelController) {
return fieldModelController.$invalid && this.attempted;
} else {
return formController && formController.$invalid && this.attempted;
}
};
this.getErrMsg=function(ctrl){
var e=ctrl.$error;
var errMsg;
if (e.required){
errMsg=''Please enter a value'';
}
return errMsg;
}
}],
compile: function(cElement, cAttributes, transclude) {
return {
pre: function(scope, formElement, attributes, controllers) {
var submitController = controllers[0];
var formController = (controllers.length > 1) ? controllers[1] : null;
submitController.setFormController(formController);
scope.rc = scope.rc || {};
scope.rc[attributes.name] = submitController;
},
post: function(scope, formElement, attributes, controllers) {
var submitController = controllers[0];
var formController = (controllers.length > 1) ? controllers[1] : null;
var fn = $parse(attributes.rcSubmit);
formElement.bind(''submit'', function (event) {
submitController.setAttempted();
if (!scope.$$phase) scope.$apply();
if (!formController.$valid) return false;
scope.$apply(function() {
fn(scope, {$event:event});
});
});
}
};
}
};
}]
};
app.directive(rcSubmitDirective);
Mi solución con bootstrap 3
http://jsfiddle.net/rimian/epxrbzn9/
<form class="form" name="form" ng-app novalidate>
<div class="form-group">
<input name="first_name"
type="text"
class="form-control"
ng-model="first_name"
placeholder="First Name"
required />
</div>
<div class="form-group">
<input name="last_name"
type="text"
class="form-control"
ng-model="last_name"
placeholder="Last Name"
required />
</div>
<button
type="submit"
class="btn btn-primary btn-large"
ng-click="submitted=true">
Submit
</button>
<div ng-show="submitted && form.$invalid" class="alert alert-danger">
<div ng-show="form.first_name.$error.required">
First Name is Required
</div>
<div ng-show="form.last_name.$error.required">
Last Name is Required
</div>
</div>
</form>
Prueba este código:
<INPUT TYPE="submit" VALUE="Save" onClick="validateTester()">
Esta función validará su resultado
function validateTester() {
var flag = true
var Tester = document.forms.Tester
if (Tester.line1.value!="JavaScript") {
alert("First box must say ''JavaScript''!")
flag = false
}
if (Tester.line2.value!="Kit") {
alert("Second box must say ''Kit''!")
flag = false
}
if (flag) {
alert("Form is valid! Submitting form...")
document.forms.Tester.submit()
}
}
Puedo encontrar 2 formas de lograrlo.
El primero es eliminar novalidate
para habilitar la validación del navegador.
En segundo lugar, puede desactivar el botón save
cuando el formulario no es válido como este
<input ng-disabled="!frmRegister.$valid" type="submit" value="Save" />
Espero eso ayude.
Solo necesita verificar si el formulario está sucio y válido antes de enviarlo. Verifica el siguiente código.
<form name="frmRegister" data-ng-submit="frmRegister.$valid && frmRegister.$dirty ? register() : return false;" novalidate>
Y también puedes deshabilitar tu botón de enviar con el siguiente cambio:
<input type="submit" value="Save" data-ng-disable="frmRegister.$invalid || !frmRegister.$dirty" />
Esto debería ayudar a su inicial
También tuve el mismo problema, resolví el problema agregando un ng-submit que establece la variable enviada como verdadera.
<form name="form" ng-submit="submitted = true" novalidate>
<div>
<span ng-if="submitted && form.email.$error.email">invalid email address</span>
<span ng-if="submitted && form.email.$error.required">required</span>
<label>email</label>
<input type="email" name="email" ng-model="user.email" required>
</div>
<div>
<span ng-if="submitted && form.name.$error.required">required</span>
<label>name</label>
<input type="text" name="name" ng-model="user.name" required>
</div>
<button ng-click="form.$valid && save(user)">Save</button>
</form>
Me gusta la idea de usar $ submit, creo que debo actualizar Angular a 1.3;)
Tantas respuestas complicadas
aquí está mi manera simple.
Básicamente, hay dos formas de resolver tu problema.
Forma de CSS:
Cuando envía un formulario cualquiera que sea su formulario válido o no, Angular agregará una clase ng-submitted
al elemento del formulario. Podemos usar .ng-submitted
a nuestro elemento controlador.
p.ej
.error { display: none }
.ng-submitted .error {
display: block;
}
Manera del alcance:
Cuando envía un formulario cualquiera que sea su formulario válido o no, Angular configurará [your form name].$submitted
a verdadero.
<div ng-show="customizedFormName.$submitted">error message</div>
<form name="customizedFormName"></form>
http://jsfiddle.net/LRD5x/30/ Una solución simple.
HTML
<form ng-submit="sendForm($event)" ng-class={submitted:submitted}>
JS
$scope.sendForm = function($event) {
$event.preventDefault()
$scope.submitted = true
};
CSS
.submitted input.ng-invalid:not(:focus) {
background-color: #FA787E;
}
input.ng-invalid ~ .alert{
display:none;
}
.submitted input.ng-invalid ~ .alert{
display:block;
}
// This worked for me.
<form name="myForm" class="css-form" novalidate ng-submit="Save(myForm.$invalid)">
<input type="text" name="uName" ng-model="User.Name" required/>
<span ng-show="User.submitted && myForm.uName.$error.required">Name is required.</span>
<input ng-click="User.submitted=true" ng-disabled="User.submitted && tForm.$invalid" type="submit" value="Save" />
</form>
// in controller
$scope.Save(invalid)
{
if(invalid) return;
// save form
}