2

Like others, I have been looking for a good way to validate my forms with Angular without the messages being too aggressive. The closest I have gotten is checking for $dirty and $touched prior to firing the messages. Which works for most situations.

The one situation I can't figure out is when the user edits, for example, a required field. The field has text in it, is valid, dirty, and touched. The user goes back into the field to change it. They backspace what is in the input and immediately the message fires because the input is now dirty, touched, and invalid. I'd rather it "reset" at that point and reevaluate when the user blurs the input again. Give them a chance to fill in the input while it's still focused.

Make sense? Any ideas?

Thanks! Matt

Mattaton
  • 247
  • 2
  • 10

3 Answers3

1

Perhaps this works:

ng-model-options="{ updateOn: 'blur' }"

Add it to your input element. I believe the validation will occur when the model is updated, this way the model gets updated on blur.

Here you can see more options for this directive: https://docs.angularjs.org/guide/forms in Custom model update triggers. And a more detailed explanations in ngModelOptions.

Let me know if it works :)

Ariel
  • 1,507
  • 2
  • 20
  • 28
  • Thanks! I think this works and I'm about to click that check mark to make it the answer. I'm just trying to figure out if there's a downside to the model only updating onBlur. For example, I have a heading that is tied to one of the input models. It doesn't appear until after the input is blurred now. That may be fine, though. Just have to think about it. :-D – Mattaton Mar 18 '16 at 15:30
  • Whatever works for you, I did not know that part of the problem heh, but as long as it solves your problem. This is the simpler way I believe. Perhaps you can use `{{ yourInputModel || 'Your waiting message here' }}` in your template. So when `$scope.yourInputModel` is not set, it shows that message. There are many workarounds. Cheers! – Ariel Mar 18 '16 at 15:38
  • Hmmm, yeah, the other downside is that it also doesn't tell them they're right once they fix a field until after they blur the field. Gotta take the good with the bad, I suppose! :-) – Mattaton Mar 18 '16 at 16:30
  • Yes you can, with FormController, check my answer to another question: http://stackoverflow.com/questions/35660346/show-div-using-angular-ng-show/35660523#35660523 – Ariel Mar 18 '16 at 17:35
  • A mix of both can lead to the desired objective :) – Ariel Mar 18 '16 at 17:37
0

Use function on ng-blur to validate and show messages if invalid.

ng-blur="validate()"

In your controller -

$scope.validate = function(){
   //Validate logic
     //If invalid
        //Show message logic here  
}
Amit Sirohiya
  • 333
  • 1
  • 13
  • Thanks. I'm trying to determine if this is more complicated than I need it to be to accomplish what I'm looking for. How would you use the validate() function to show the ngMessages? And do I have to pass the validate() function the actual element that called it or does angular already handle that connection? I'm new to angular, so these things aren't apparent to me yet. :-) – Mattaton Mar 18 '16 at 15:34
  • I believe you would have to pass an argument to the `validate()` function in order to know which input field is being blurred and act accordingly. – Ariel Mar 18 '16 at 15:45
  • @Ariel Why pass an argument cant you check values in $scope to validate them? – Amit Sirohiya Mar 21 '16 at 05:10
  • I suggested that because I'd try to access `$scope` properties dynamically, instead of checking all the properties every time one input loses focus. – Ariel Mar 21 '16 at 20:09
0

Take a look at the ngMessages documentation: https://docs.angularjs.org/api/ngMessages/directive/ngMessages

You have an example there that shows you how to use it:

<form name="myForm">
  <label>
    Enter your name:
    <input type="text"
           name="myName"
           ng-model="name"
           ng-minlength="5"
           ng-maxlength="20"
           required />
  </label>
  <pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>

  <div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
    <div ng-message="required">You did not enter a field</div>
    <div ng-message="minlength">Your field is too short</div>
    <div ng-message="maxlength">Your field is too long</div>
  </div>
</form>

I think this is the best way to do it (at least it's how I do it).

Astaroth
  • 763
  • 6
  • 25
  • Thanks, but I don't see how this helps with my question. I already know how to use ngMessages, at least as far as this example shows (I have almost this exact setup sprinkled all over my code). I was looking for a very specific case for when to show the message. – Mattaton Mar 18 '16 at 15:27