0

On a form with required-validation and ng-messages I use ng-show to hide the directive on startup and only show error messages after the input got ng-dirty.

To still keep the element filling it's space in the layout I have following css rule to overwrite the default ng-hide behaviour:

ng-messages.ng-hide:not(.ng-hide-animate), [ng-messages].ng-hide:not(.ng-hide-animate)
{
    display: block !important;
    visibility: hidden;
}

When I now enter text in the input field the error message is shortly visible before it is then hidden again (due to the required field being filled). It somehow feels like ng-dirty is resolved before the form validation is done, resulting in this behaviour.

See this Fiddle

or check out the

Code:

var $scope;
var app = angular.module('myapp', ['ngMessages', 'ngAnimate']);
app.controller('UserCtrl', ['$scope', UserCtrl]);

function UserCtrl($scope) {
    $scope.showField = true;
    $scope.reset = function() {
        var master = { name: '' };
        $scope.temp = angular.copy(master);
        $scope.user_form.$setPristine();
    }  
}
ng-messages.ng-hide:not(.ng-hide-animate), [ng-messages].ng-hide:not(.ng-hide-animate)
{
   display: block !important;
   visibility: hidden;
}

ng-messages, [ng-messages]
{
  display: block;
  height: 1em;
}

input
{
   display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.5/angular-messages.min.js"></script>

<div ng-app="myapp">
    <div ng-controller="UserCtrl">
        <form name="user_form" novalidate>
            <input name="name" ng-model="temp.name" ng-show="showField" placeholder="Name" required autocomplete="off"/>
            <ng-messages ng-show="user_form.name.$dirty" for="user_form.name.$error">
              <ng-message when="required">
                Please enter your name
              </ng-message>
            </ng-messages>
            <button type="button" class="button" ng-click="reset()">Reset</button>     
        </form>
        <p>
            Pristine: {{user_form.$pristine}}
        </p>
        
        <pre>Errors: {{user_form.$error | json}}</pre>
              
    </div>
</div>
Aides
  • 3,643
  • 5
  • 23
  • 39

1 Answers1

1
 <ng-messages ng-show="user_form.name.$dirty && !user_form.name.$valid" for="user_form.name.$error">
Mohsin Muzawar
  • 1,202
  • 9
  • 9
  • Oha, that did work! I did try similar things without success. Could you explain why this flicker occurs and how this statement helps preventing it? – Aides Apr 25 '16 at 12:09