6

I'm running into an issue where ng-message is flashing the 'required' error message despite there being input in the input box. What happens is that it very briefly flashes the error message: "THIS FIELD IS REQUIRED (ALL IN CAPS TO MAKE IT EASIER TO SEE IT FLASH BY!)" on the screen before it disappears right away. Sorry for the caps but I wanted to make the message easier to see before it disappears.

Here is a link to my plunker. Please enter any input and then click elsewhere on the page so that the input field loses focus. Pay attention because the error message in red will flash by briefly then disappear. If you didn't notice the message flash by quickly, you will have to reload the page again to see it happen again.

Why is this happening? I believe it has something to do with ui-date because I'm not able to replicate the problem without ui-date.

Here's a snippet of the code:

<form name="reportform" ng-submit="process_form()" novalidate >
  <input name="startdate" placeholder="Enter a start date" ui-date ng-model="startdatevalue"  required>
  <ng-messages ng-if='reportform.startdate.$touched' for="reportform.startdate.$error">
    <ng-message when="required" class="error-message">
      THIS FIELD IS REQUIRED (ALL IN CAPS TO MAKE IT EASIER TO SEE IT FLASH BY!)
    </ng-message>
  </ng-messages>
  <button ng-disabled="reportform.$invalid" type="submit">
    Submit Query
  </button>
</form>

Thanks for your help.

user45183
  • 529
  • 1
  • 7
  • 16

4 Answers4

1

Okay, this may or may not be relevant to your specific error message displaying, and it appears to be a solution when templating is used only. However, after trying a number of things I came across:

ng-cloak

From the documentation:

The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.

I added this to each of my ngMessages divs and the error flashing briefly went away, makes sense.

edencorbin
  • 2,569
  • 5
  • 29
  • 44
0

try with that:

<ng-messages ng-if='reportform.startdate.$touched && reportform.startdate.$modelValue' for="reportform.startdate.$error">
        <ng-message when="required" class="error-message" > 
          THIS FIELD IS REQUIRED (ALL IN CAPS TO MAKE IT EASIER TO SEE IT FLASH BY!)
        </ng-message>
      </ng-messages>

Just checking that the modelValue is not null before shooting the error.

I suggest you during dev also to check the values in the model:

<pre>reportform.startdate.$error = {{reportform.startdate | json }}</pre>
thegio
  • 1,233
  • 7
  • 27
0

Just cut it down a little. Also remember dots in ng-models!, something to think about.

<form name="reportform" ng-submit="process_form()" novalidate>
  <input name="startdate" placeholder="Enter a start date" ui-date ng-model="startdatevalue" required>
  <ng-messages for="reportform.startdate.$error">
    <ng-message when="required" class="error-message">
      THIS FIELD IS REQUIRED (ALL IN CAPS TO MAKE IT EASIER TO SEE IT FLASH BY!)
    </ng-message>
  </ng-messages>
</form>

See if that fixes it, I haven't tested it though.

Community
  • 1
  • 1
rrd
  • 5,789
  • 3
  • 28
  • 36
0

What's happening is that $touched is being updated when you mouse down on a date in the picker, but the model is not updated till after you mouse up. This is obvious if you click on the date and keep your mouse button pressed.

One (admittedly hacky) way to work around this problem would be to use the ui-date options to check if the date picker has been closed and use that in your ng-messages ng-if.

... ui-date="dateOptions" ng-model="startdatevalue" required>

<ng-messages ng-if='reportform.startdate.$touched && selectionComplete' for="reportform.startdate.$error">

with the following in your controller

 $scope.dateOptions = {
    onClose: function() { 
      $scope.$apply(function(){
        $scope.selectionComplete = true;
      })
    }
 }

Updated plnkr - https://plnkr.co/edit/vgfI8lTnkhDMU0yJ1FTA?p=preview


Just a quick note that the Github page (https://github.com/angular-ui/ui-date) recommends the ui-bootstrap date-picker as an alternative.

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
  • 1
    Thanks for the response. I was able to get it to work in my plunker. Problem is, I pared that down from a much larger example in my project. I'm constructing the ui-date datefields dynamically in an ng-repeat loop. There can be any number of them. I figured I can use: `ui-date="dateOptions[$index]"` but in my controller when I set up each dateOption, I'm unsure how to make $scope.selectionComplete unique for each datepicker. And then in ng-messages how do I reference each unique "selectionComplete..." variable? Thanks again for your help. – user45183 Apr 19 '16 at 13:22
  • Check out https://plnkr.co/edit/6GAtm3Or4ZPxCHyBVGY1?p=preview where both the ng-messages and the options are generic and extendable to multiple controls. – potatopeelings Apr 19 '16 at 22:16