<!DOCTYPE html>
<html ng-app="LoginApp">

<head>
  <link data-require="bootstrap-css@3.2.0" data-semver="3.2.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  <script data-require="angular.js@1.3.3" data-semver="1.3.3" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
  <script src="rcSubmit.js"></script>
  <script src="loginApp.js"></script>
</head>

<body>
  <div ng-controller="DirectiveDemoCtrl as demoCtrl">
    <h2>First Form</h2>
    <div>
      <form name="firstFormName" novalidate rc-submit="demoCtrl.login(formObj)">
        <demo-directive formname="firstFormName" ctrl="demoCtrl"></demo-directive>
        <div class="form-group">
          <button type="submit" class="btn btn-primary pull-right" value="Login" title="Login">
            <span>Login</span>
          </button>
        </div>
      </form>
    </div>
  </div>
</body>

</html>
// define custom submit directive
var rcSubmitDirective = {
    'rcSubmit': ['$parse', function ($parse) {
        return {
            restrict: 'A',
            require: ['rcSubmit', '?form'],
            controller: ['$scope', function ($scope) {
                this.attempted = false;
                
                var formController = null;
                
                this.setAttempted = function() {
                    this.attempted = true;
                };
                
                this.setFormController = function(controller) {
                  formController = controller;
                };
                
                this.needsAttention = function (fieldModelController) {
                    if (!formController) return false;
                    
                    if (fieldModelController) {
                        return fieldModelController.$invalid && (fieldModelController.$dirty || this.attempted);
                    } else {
                        return formController && formController.$invalid && (formController.$dirty || this.attempted);
                    }
                };
            }],
            compile: function(cElement, cAttributes, transclude) {
                return {
                    pre: function(scope, formElement, attributes, controllers) {
                      
                        var submitController = controllers[0];
                        var formController = (controllers.length > 1) ? controllers[1] : null;
                        
                        submitController.setFormController(formController);
                        
                        scope.rc = scope.rc || {};
                        scope.rc[attributes.name] = submitController;
                    },
                    post: function(scope, formElement, attributes, controllers) {
                      
                        var submitController = controllers[0];
                        var formController = (controllers.length > 1) ? controllers[1] : null;
                        var fn = $parse(attributes.rcSubmit);
                        
                        formElement.bind('submit', function (event) {
                            submitController.setAttempted();
                            if (!scope.$$phase) scope.$apply();
                            
                            if (!formController.$valid) return false;
                    
                            scope.$apply(function() {
                                fn(scope, {$event:event});
                            });
                        });
                    }
              };
            }
        };
    }]
};
// create a module to make it easier to include in the app module
angular.module('rcForm', [])
  .directive(rcSubmitDirective);

// define module for app
angular.module('LoginApp', ['rcForm']);
angular.module('LoginApp').directive('demoDirective', function() {
  return {
    restrict: 'E',
    templateUrl: 'template.html',
    link: {
      pre: function(scope, element, attrs) {
        scope.formname = attrs.formname;
        scope.ctrl = attrs.ctrl;
      }
    }
  };
});
angular.module('LoginApp').factory('dataService', function() {
  return {
    getAddressType: function() {
      var addressData = [{
        'id': '1',
        'desc': 'Home'
      }, {
        'id': '2',
        'desc': 'Office'
      }];
      return addressData;
    }
  }
});
angular.module('LoginApp').controller('DirectiveDemoCtrl', ['dataService',
  function(dataService) {
    var demoCtrl = this;
    demoCtrl.addressList = dataService.getAddressType();
    demoCtrl.login = function(data) {
      demoCtrl.formObj = data;
      console.log(demoCtrl.formObj);
      alert('logged in!');
    };
  }
]);
<div class="col-xs-12 col-sm-6 col-sm-offset-3">
    <div class="form-group" ng-class="{'has-error': rc.{{formname}}.needsAttention({{formname}}.username)}">
      <input class="form-control" name="username" type="text" placeholder="Username" ng-required="true" ng-model="formObj.username" />
      <span class="help-block" ng-show="{{formname}}.username.$error.required">Required</span>
    </div>
    <div class="form-group" ng-class="{'has-error': rc.{{formname}}.needsAttention({{formname}}.password)}">
      <input class="form-control" name="password"  type="password" placeholder="Password" ng-required="true" ng-model="formObj.password" />
      <span class="help-block" ng-show="{{formname}}.password.$error.required">Required</span>
    </div>
    <div class="form-group" ng-class="{'has-error': rc.{{formname}}.needsAttention({{formname}}.addressType)}">
              <label class="col-sm-5 control-label text-right"><i class="fa fa-asterisk font-color-e93207 margin-right-5px"></i>Address Type :</label>
              <div class="col-sm-7">
                <select class="form-control" ng-required="true" name="addressType" ng-model="formObj.addressType" ng-options="eachtype.desc for eachtype in {{ctrl}}.addressList">
                  <option value="">--Select One--</option>
                </select>
              </div>
    </div>
</div>