Angular - How do I validate the input field on blur

Problem

I made a simple testing input fields, But I trying to convert the validation on blur, But i don't have any idea to achive this, since I am not such familiar with angularjs.

any one help me to validate only one blur in this example please..

myJs:

angular.module('myApp', [])
.controller('FormController', function($scope) {
  $scope.fields = [
    {placeholder: 'Username', isRequired: true},
    {placeholder: 'Password', isRequired: true},
    {placeholder: 'Email (optional)', isRequired: false}
  ];

  $scope.submitForm = function() {
    alert("it works!");
  };
});

html:

<div ng-app="myApp">
<form name="signup_form" ng-controller="FormController" ng-submit="submitForm()" novalidate>
  <div ng-repeat="field in fields" ng-form="signup_form_input">
    <input type="text"
           name="dynamic_input"
           ng-required="field.isRequired"
           ng-model="field.name"
           placeholder="{{field.placeholder}}" />
    <div ng-show="signup_form_input.dynamic_input.$dirty && signup_form_input.dynamic_input.$invalid">
      <span class="error" ng-show="signup_form_input.dynamic_input.$error.required">The field is required.</span>
    </div>
  </div>
  <button type="submit" ng-disabled="signup_form.$invalid">Submit All</button>
</form>
</div>

Live Demo

Problem courtesy of: 3gwebtrain

Solution

You can simply create a directive that has the same name as ngModel. Add a blur event on the element that changes the $dirty state of the ngModel to true. Make sure to change ngModel's $dirty state to false when changes are made on the element by adding a callback inside ngModel.$viewChangeListeners array.

FORKED SAMPLE

The directive looks something like this:

.directive('ngModel', function() {
    return {
        require: 'ngModel',
        link: function(scope, elem, attr, ngModel) {
            elem.on('blur', function() {
                ngModel.$dirty = true;
                scope.$apply();
            });

            ngModel.$viewChangeListeners.push(function() {
                ngModel.$dirty = false;
            });

            scope.$on('$destroy', function() {
                elem.off('blur');
            });
        }
    }
});

Note: Don't worry if the custom directive name, ngModel, is the same with Angular's default ngModel, it will simply run both of them (it won't overwrite it). The scope.$on('$destroy') listener, removes the blur event handler when the scope is destroyed, e.g. when route changes and the controller is destroyed or when a field is removed which triggers a rebuild of the repeated DOM elements again(destroying the child scope created by ng-repeat).

Solution courtesy of: ryeballar

Discussion

If you have a custom validation, a simple way to go is using ngBlur. Add the following to your field and write a validation function in your controller:

<input type="text"
       ng-model="fieldVal" 
       ng-blur="validate(fieldVal)"/>

You can also use ng-model-options combined with ng-change

<input type="text" 
       ng-modle="fildsVal" 
       ng-model-option="{ updateOn: 'blur' }" 
       ng-change="validate(fieldVal)" />

I also found the debounce option very nice to trigger the validation. You can time it so that when user is done typing, the validation triggers:

<input type="text"
       ng-model-options="{ debounce: 800 }" 
       ng-pattern="/^[0-9]{1,9}$/" />
Discussion courtesy of: iMad
            angular.module('myApp', [])
        .controller('FormController', function($scope) {
             $(document).ready(function(){
                $("#form input").on('blur', function(){
                    alert("Cannot be null");
                });
            });
          $scope.fields = [
            {placeholder: 'Username', isRequired: true},
            {placeholder: 'Password', isRequired: true},
            {placeholder: 'Email (optional)', isRequired: false}
          ];

          $scope.submitForm = function() {
            alert("it works!");
          };

        });

just give id to form and add the javascript code. Thats all. For live demo "http://jsfiddle.net/SaurabhGhewari/2ko9bamk/"

Discussion courtesy of: Saurabh Ghewari

If you update to Angular 1.3 you can use ng-model-options to update the model on blur.

<input type="text"
       name="dynamic_input"
       ng-required="field.isRequired"
       ng-model="field.name"
       ng-model-options="{ updateOn: 'blur' }"
       placeholder="{{field.placeholder}}" />

fiddle

However, if you can't update then there are plenty of ways to do this here.

Discussion courtesy of: Ben Fortune

This recipe can be found in it's original form on Stack Over Flow.