mostrar mensagens de erro de validação no envio em angularjs

Eu tenho um formulário que precisa mostrar mensagens de erro de validação se clicou em enviar.

Aqui está uma plunker de trabalho

 
First Name is required
Last Name is required
Email is required. Invalid Email address.
YOU ARE NOW REGISTERED USER

A validação funciona normalmente quando o usuário começa a fazer alterações. Mas não mostra nenhuma mensagem de erro Se clicou em enviar sem digitar nada.

Qualquer pensamento de conseguir isso? Ou, de outra forma, como posso tornar cada campo de input $ sujo quando clica no botão Enviar

Eu encontrei este violino http://jsfiddle.net/thomporter/ANxmv/2/ que faz um truque bacana para causar a validação de controle.

Basicamente, ele declara um membro de escopo submitted e o define quando você clica em enviar. A binding de erro do modelo usa essa expressão extra para mostrar a mensagem de erro

 submitted && form.email.$error.required 

ATUALIZAR

Como apontado no comentário de @ Hafez (dê-lhe alguns votos positivos !), A solução Angular 1.3+ é simplesmente:

 form.$submitted && form.email.$error.required 

Desde que eu estou usando o Bootstrap 3, eu uso uma diretiva: (veja 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); 

e depois no meu HTML:

 

please enter your email

please enter a valid email

ATUALIZADA

No meu último projeto, eu uso o Ionic, então tenho o seguinte, que coloca automaticamente .valid ou .invalid no 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(); } }) ; } }; }]) 

e depois no HTML:

  

e no controlador:

  self.signin = function (form, data) { if (!form.$valid) return; Authentication.emailLogin(data) //... 

então, agora, no CSS, você pode fazer coisas como:

 .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; */ } 

MUITO MAIS SIMPLES!

Eu também tive o mesmo problema, resolvi o problema adicionando um ng-submit que define a variável submetida a true.

 
invalid email address required
required

Eu gosto da idéia de usar $ submited, acho que tenho que atualizar Angular para 1.3;)

Eu posso encontrar duas maneiras de conseguir isso.

O primeiro deles é remover o novalidate para ativar a validação do navegador.

Em segundo lugar, você pode desativar o botão save quando o formulário não é válido como este

  

Espero que ajude.

Minha solução com o bootstrap 3

http://jsfiddle.net/rimian/epxrbzn9/

 
First Name is Required
Last Name is Required

Você só precisa verificar se o formulário está sujo e válido antes de enviá-lo. Confira o código a seguir.

 

E também você pode desativar seu botão de envio com a seguinte alteração:

  

Isso deve ajudar na sua inicial

Tantas respostas complicadas.

aqui está o meu jeito simples.

Basicamente, há duas maneiras de resolver o seu problema.

Maneira CSS:
Quando você envia um formulário, qualquer que seja seu formulário, ou não, o Angular adicionará uma class ng-submitted para o elemento do formulário. Podemos usar .ng-submitted para controlar nosso elemento.
por exemplo

 .error { display: none } .ng-submitted .error { display: block; } 

Caminho do escopo:
Quando você envia um formulário, seja qual for o seu formulário, ou não, o Angular definirá [your form name].$submitted como verdadeiro.

 
error message

http://jsfiddle.net/LRD5x/30/ Uma solução simples.

HTML

 

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; } 

Eu gosto da solução de realcrowd o melhor.

HTML:

 
{{rc.form.getErrMsg(form.firstName)}}

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); 
 // This worked for me. 
Name is required.
// in controller $scope.Save(invalid) { if(invalid) return; // save form }

G45

Eu enfrentei o mesmo problema, eu criei uma directiva, por favor, verifique abaixo espero que possa 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:

  

Experimente este código:

  

Este funvtion validará seu 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() } }