Com o AngularJS, posso usar ng-pristine
ou ng-dirty
para detectar se o usuário entrou no campo. No entanto, desejo fazer a validação do lado do cliente somente depois que o usuário tiver deixado a área de campo. Isso ocorre porque quando um usuário insere um campo como e-mail ou telefone, ele sempre receberá um erro até que tenha concluído a digitação de seu e-mail completo, e esta não é uma experiência de usuário ideal.
ATUALIZAR:
O Angular agora vem com um evento de desfoque personalizado: https://docs.angularjs.org/api/ng/directive/ngBlur
Respostas:
O Angular 1.3 agora tem opções de modelo de ng, e você pode definir a opção para,
{ 'updateOn': 'blur'}
por exemplo, e você pode até debounce, quando o uso está digitando muito rápido, ou você deseja salvar algumas operações DOM caras (como a escrita de um modelo para vários locais DOM e você não quer um ciclo de $ digest acontecendo a cada tecla pressionada)https://docs.angularjs.org/guide/forms#custom-triggers e https://docs.angularjs.org/guide/forms#non-immediate-debumped-model-updates
E debounce
fonte
ng-change
eventos antes de o usuário sair do campo. Por exemplo, no meu caso, solicito novos dados de minha API assim que o campo de entrada for válido, mas não quero mostrar uma mensagem de erro assim que for inválido - quero fazer isso apenas quando for inválido e o evento de desfoque ocorreu.1.3.0 rc-3
e ele não disparachange
atéblur
, verifique isto: plnkr.co/edit/RivVU3r7xfHO1hUybqMu?p=previewA partir da versão 1.3.0, isso pode ser feito facilmente com
$touched
, o que é verdade depois que o usuário sai do campo.https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
fonte
updateOn: 'default'
que significa, para entradas,Resolvi isso expandindo o que @jlmcdonald sugeriu. Eu criei uma diretiva que seria aplicada automaticamente a todos os elementos de entrada e seleção:
Isso adicionará
has-focus
ehas-visited
classes a vários elementos conforme o usuário foca / visita os elementos. Você pode então adicionar essas classes às suas regras CSS para mostrar erros de validação:Isso funciona bem porque os elementos ainda obtêm $ propriedades inválidas etc., mas o CSS pode ser usado para dar ao usuário uma experiência melhor.
fonte
formName.inputName.$dirty
. Eu sugeriria editar a diretiva para escrever um booleano semelhanteformName.inputName.$focused
, em vez de usar nomes de classe para desfoque e booleanos para validação.Consegui fazer isso com um pouco de CSS bem simples. Isso exige que as mensagens de erro sejam irmãs da entrada a que se relacionam e que tenham uma classe da qual
error
.Depois de atender a esses dois requisitos, isso ocultará qualquer mensagem de erro relacionada a um campo de entrada focado, algo que acho que o angularjs deveria fazer de qualquer maneira. Parece um descuido.
fonte
Isso parece ser implementado como padrão nas versões mais recentes do angular.
As classes ng-untouched e ng -oked são definidas respectivamente antes e depois que o usuário teve o foco em um elemento validado.
CSS
fonte
Com relação à solução de @lambinator ... Eu estava recebendo o seguinte erro no angular.js 1.2.4:
Não tenho certeza se fiz algo errado ou se isso é uma alteração no Angular, mas remover as
scope.$apply
instruções resolveu o problema e as classes / estados ainda estão sendo atualizados.Se você também estiver vendo esse erro, tente o seguinte:
fonte
Pode funcionar para você escrever uma diretiva personalizada que envolve o método blur () de javascript (e executa uma função de validação quando acionada); há um problema do Angular que tem um exemplo (bem como uma diretiva genérica que pode vincular a outros eventos não suportados nativamente pelo Angular):
https://github.com/angular/angular.js/issues/1277
Se você não quiser seguir esse caminho, sua outra opção seria configurar $ watch no campo, novamente acionando a validação quando o campo for preenchido.
fonte
Para aprender mais sobre as respostas fornecidas, você pode simplificar a marcação de entrada usando pseudo classes CSS3 e apenas marcando os campos visitados com uma classe para atrasar a exibição de erros de validação até que o usuário perca o foco no campo:
(O exemplo requer jQuery)
JavaScript
CSS
HTML
fonte
baseado na resposta do @nicolas. CSS puro deve funcionar, ele só mostrará a mensagem de erro no desfoque
CSS
fonte
Aqui está um exemplo usando ng-messages (disponível no angular 1.3) e uma diretiva personalizada.
A mensagem de validação é exibida em desfoque na primeira vez que o usuário deixa o campo de entrada, mas quando ele corrige o valor, a mensagem de validação é removida imediatamente (não está mais desfocada).
JavaScript
HTML
PS. Não se esqueça de baixar e incluir ngMessages em seu módulo:
fonte
ng-model-options no AngularJS 1.3 (beta no momento desta escrita) está documentado para suportar {updateOn: 'blur'}. Para versões anteriores, algo como o seguinte funcionou para mim:
Com um modelo como este:
fonte
Use o estado do campo $ Touch O campo foi tocado para isso, conforme mostrado no exemplo abaixo.
fonte
Você pode definir dinamicamente a classe css has-error (supondo que você esteja usando bootstrap) usando ng-class e uma propriedade no escopo do controlador associado:
plunkr: http://plnkr.co/edit/HYDlaTNThZE02VqXrUCH?p=info
HTML:
Controlador:
fonte
Se você usar bootstrap 3 e lesscss, poderá ativar a validação de desfoque com o seguinte menos snippet:
fonte
outI usei uma diretiva. Aqui está o código:
Todo o meu controle de entrada tem um elemento span como o próximo elemento, que é onde minha mensagem de validação é exibida e, portanto, a diretiva como um atributo é adicionada a cada controle de entrada.
Eu também tenho (opcional) as classes css .has-focus e has-Visit em meu arquivo css, que você vê sendo referenciado na diretiva.
NOTA: lembre-se de adicionar 'on-blur-val' exatamente desta forma ao seu controle de entrada sem os apóstrofos
fonte
Ao usar o ng-focus, você pode atingir seu objetivo. você precisa fornecer ng-focus em seu campo de entrada. E enquanto escreve seus derivados ng-show, você também tem que escrever uma lógica diferente. Como o código abaixo:
<input type="text" class="form-control" name="inputPhone" ng-model="demo.phoneNumber" required ng-focus> <div ng-show="demoForm.inputPhone.$dirty && demoForm.inputPhone.$invalid && !demoForm.inputPhone.$focused"></div>
fonte
Podemos usar as funções onfocus e onblur. Seria simples e melhor.
Experimente aqui:
http://plnkr.co/edit/NKCmyru3knQiShFZ96tp?p=preview
fonte