Validate form field only on submit or user input

I have form fields that are validated using required. The problem is, that the error is displayed immediately when the form is rendered. I want it only to be displayed after the user actually typed in the text field, or on submit.

How can I implement this?


Use $dirty flag to show the error only after user interacted with the input:

<div>
  <input type="email" name="email" ng-model="user.email" required />
  <span ng-show="form.email.$dirty && form.email.$error.required">Email is required</span>
</div>

If you want to trigger the errors only after the user has submitted the form than you may use a separate flag variable as in:

<form ng-submit="submit()" name="form" ng-controller="MyCtrl">
  <div>
    <input type="email" name="email" ng-model="user.email" required />
    <span ng-show="(form.email.$dirty || submitted) && form.email.$error.required">
      Email is required
    </span>
  </div>

  <div>
    <button type="submit">Submit</button>
  </div>
</form>
function MyCtrl($scope){
  $scope.submit = function(){
    // Set the 'submitted' flag to true
    $scope.submitted = true;
    // Send the form to server
    // $http.post ...
  } 
};

Then, if all that JS inside ng-showexpression looks too much for you, you can abstract it into a separate method:

function MyCtrl($scope){
  $scope.submit = function(){
    // Set the 'submitted' flag to true
    $scope.submitted = true;
    // Send the form to server
    // $http.post ...
  }

  $scope.hasError = function(field, validation){
    if(validation){
      return ($scope.form[field].$dirty && $scope.form[field].$error[validation]) || ($scope.submitted && $scope.form[field].$error[validation]);
    }
    return ($scope.form[field].$dirty && $scope.form[field].$invalid) || ($scope.submitted && $scope.form[field].$invalid);
  };

};
<form ng-submit="submit()" name="form">
  <div>
    <input type="email" name="email" ng-model="user.email" required />
    <span ng-show="hasError('email', 'required')">required</span>
  </div>

  <div>
    <button type="submit">Submit</button>
  </div>
</form>

If you want to show error messages on form submission, you can use condition form.$submitted to check if an attempt was made to submit the form. Check following example.

<form name="myForm" novalidate ng-submit="myForm.$valid && createUser()">
  <input type="text" name="name" ng-model="user.name" placeholder="Enter name of user" required>
  <div ng-messages="myForm.name.$error" ng-if="myForm.$submitted">
    <div ng-message="required">Please enter user name.</div>
  </div>

  <input type="text" name="address" ng-model="user.address" placeholder="Enter Address" required ng-maxlength="30">
  <div ng-messages="myForm.name.$error" ng-if="myForm.$submitted">
    <div ng-message="required">Please enter user address.</div>
    <div ng-message="maxlength">Should be less than 30 chars</div>
  </div>

  <button type="submit">
    Create user
  </button>
</form>

You can use angularjs form state form.$submitted. Initially form.$submitted value will be false and will became true after successful form submit.