diff --git a/Gruntfile.js b/Gruntfile.js index 66afdfe..73d4129 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -43,7 +43,7 @@ module.exports = function(grunt) { } }, jsbeautifier: { - files: ['*.js', 'src/**/*.js'], + files: ['*.js', 'src/**/*.js', 'test/unit/*.js'], options: {} }, jshint: { diff --git a/dist/angular-validation.js b/dist/angular-validation.js index 2765ef6..f5db5ca 100644 --- a/dist/angular-validation.js +++ b/dist/angular-validation.js @@ -550,6 +550,7 @@ if (attrs.validMethod === 'submit') { watch(); // clear previous scope.$watch watch = scope.$watch('model', function(value, oldValue) { + value = ctrl.$viewValue; // don't watch when init if (value === oldValue) { @@ -610,6 +611,7 @@ * This is the default method */ scope.$watch('model', function(value) { + value = ctrl.$viewValue; /** * dirty, pristine, viewValue control here */ diff --git a/dist/angular-validation.min.js b/dist/angular-validation.min.js index 7bb3064..0436ac6 100644 --- a/dist/angular-validation.min.js +++ b/dist/angular-validation.min.js @@ -1 +1 @@ -(function(){angular.module("validation",["validation.provider","validation.directive"])}).call(this),function(){angular.module("validation.provider",[]).provider("$validation",function(){var a,b,c,d,e,f=this,g=function(f){a=f,b=a.get("$rootScope"),c=a.get("$http"),d=a.get("$q"),e=a.get("$timeout")},h={},i={};this.setExpression=function(a){return angular.extend(h,a),f},this.getExpression=function(a){return h[a]},this.setDefaultMsg=function(a){return angular.extend(i,a),f},this.getDefaultMsg=function(a){return i[a]},this.setErrorHTML=function(a){return a.constructor===Function?(f.getErrorHTML=a,f):void 0},this.getErrorHTML=function(a){return'

'+a+"

"},this.setSuccessHTML=function(a){return a.constructor===Function?(f.getSuccessHTML=a,f):void 0},this.getSuccessHTML=function(a){return'

'+a+"

"},this.showSuccessMessage=!0,this.showErrorMessage=!0,this.checkValid=function(a){return void 0===a.$valid?!1:a&&a.$valid===!0},this.validate=function(a){var c=d.defer(),g=0;if(void 0===a)return console.error("This is not a regular Form name scope"),c.reject("This is not a regular Form name scope"),c.promise;if(a.validationId)b.$broadcast(a.$name+"submit-"+a.validationId,g++);else if(a.constructor===Array)for(var h in a)b.$broadcast(a[h].$name+"submit-"+a[h].validationId,g++);else for(var i in a)"$"!==i[0]&&a[i].hasOwnProperty("$dirty")&&b.$broadcast(i+"submit-"+a[i].validationId,g++);return c.promise.success=function(a){return c.promise.then(function(b){a(b)}),c.promise},c.promise.error=function(a){return c.promise.then(null,function(b){a(b)}),c.promise},e(function(){f.checkValid(a)?c.resolve("success"):c.reject("error")}),c.promise},this.validCallback=null,this.invalidCallback=null,this.reset=function(a){if(void 0===a)return void console.error("This is not a regular Form name scope");if(a.validationId)b.$broadcast(a.$name+"reset-"+a.validationId);else if(a.constructor===Array)for(var c in a)b.$broadcast(a[c].$name+"reset-"+a[c].validationId);else for(var d in a)"$"!==d[0]&&a[d].hasOwnProperty("$dirty")&&b.$broadcast(d+"reset-"+a[d].validationId)},this.$get=["$injector",function(a){return g(a),{setErrorHTML:this.setErrorHTML,getErrorHTML:this.getErrorHTML,setSuccessHTML:this.setSuccessHTML,getSuccessHTML:this.getSuccessHTML,setExpression:this.setExpression,getExpression:this.getExpression,setDefaultMsg:this.setDefaultMsg,getDefaultMsg:this.getDefaultMsg,showSuccessMessage:this.showSuccessMessage,showErrorMessage:this.showErrorMessage,checkValid:this.checkValid,validate:this.validate,validCallback:this.validCallback,invalidCallback:this.invalidCallback,reset:this.reset}}]})}.call(this),function(){angular.module("validation.directive",["validation.provider"]).directive("validator",["$injector",function(a){var b=a.get("$validation"),c=a.get("$q"),d=a.get("$timeout"),e=function(a,c,d,e,f){var g,h=c||b.getDefaultMsg(d).success;return g=e.messageId?angular.element(document.querySelector("#"+e.messageId)):a.next(),b.showSuccessMessage&&h&&g.html(b.getSuccessHTML(h)),f.$setValidity(f.$name,!0),e.validCallback&&e.validCallback({message:h}),b.validCallback&&b.validCallback(a),!0},f=function(a,c,d,e,f){var g,h=c||b.getDefaultMsg(d).error;return g=e.messageId?angular.element(document.querySelector("#"+e.messageId)):a.next(),b.showErrorMessage&&h&&g.html(b.getErrorHTML(h)),f.$setValidity(f.$name,!1),e.invalidCallback&&e.invalidCallback({message:h}),b.invalidCallback&&b.invalidCallback(a),!1},g={},h=function(a,d,g,i,j,k){var l=j.slice(0),m=l[0].trim(),n=m.indexOf("="),o=-1===n?m:m.substr(0,n),p=-1===n?null:m.substr(n+1),q=l.slice(1),r=o+"SuccessMessage",s=o+"ErrorMessage",t=b.getExpression(o),u={success:function(){return e(d,g[r],o,a,i),q.length?h(a,d,g,i,q,k):!0},error:function(){return f(d,g[s],o,a,i)}};return void 0===t?(console.error('You are using undefined validator "%s"',o),q.length?h(a,d,g,i,q,k):void 0):t.constructor===Function?c.all([b.getExpression(o)(k,a,d,g,p)]).then(function(a){return a&&a.length>0&&a[0]?u.success():u.error()},function(){return u.error()}):t.constructor===RegExp&&void 0!==k&&null!==k&&b.getExpression(o).test(k)?u.success():u.error()},i=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)},j=function(){return i()+i()+i()+i()};return{restrict:"A",require:"ngModel",scope:{model:"=ngModel",initialValidity:"=initialValidity",validCallback:"&",invalidCallback:"&",messageId:"@"},link:function(a,b,c,e){var f,i=function(){},k=c.validator.split(","),l=e.validationId=j();"boolean"==typeof a.initialValidity&&(f=a.initialValidity),a.messageId||b.after(""),e.$setValidity(e.$name,f),a.$on(e.$name+"reset-"+l,function(){i(),d(function(){e.$setViewValue(""),e.$setPristine(),e.$setValidity(e.$name,void 0),e.$render(),a.messageId?angular.element(document.querySelector("#"+a.messageId)).html(""):b.next().html("")})}),function(){return a.$on(e.$name+"submit-"+l,function(f,j){var l=e.$viewValue,m=!1;m=h(a,b,c,e,k,l),"submit"===c.validMethod&&(i(),i=a.$watch("model",function(d,f){d!==f&&((void 0===d||null===d)&&(d=""),m=h(a,b,c,e,k,d))}));var n=function(a){a?delete g[j]:(g[j]=b[0],d(function(){g[Math.min.apply(null,Object.keys(g))].focus()},0))};m.constructor===Object?m.then(n):n(m)}),"blur"===c.validMethod?void b.bind("blur",function(){var d=e.$viewValue;a.$apply(function(){h(a,b,c,e,k,d)})}):void("submit"!==c.validMethod&&"submit-only"!==c.validMethod&&a.$watch("model",function(d){if(e.$pristine&&e.$viewValue)e.$setViewValue(e.$viewValue);else if(e.$pristine)return void(a.messageId?angular.element(document.querySelector("#"+a.messageId)).html(""):b.next().html(""));h(a,b,c,e,k,d)}))}(),d(function(){c.$observe("noValidationMessage",function(c){var d;d=a.messageId?angular.element(document.querySelector("#"+a.messageId)):b.next(),"true"==c||c===!0?d.css("display","none"):("false"==c||c===!1)&&d.css("display","block")})})}}}]).directive("validationSubmit",["$injector",function(a){var b=a.get("$validation"),c=a.get("$timeout"),d=a.get("$parse");return{priority:1,require:"?ngClick",link:function(a,e,f){var g=d(f.validationSubmit)(a);c(function(){e.off("click"),e.on("click",function(c){c.preventDefault(),b.validate(g).success(function(){d(f.ngClick)(a)})})})}}}]).directive("validationReset",["$injector",function(a){var b=a.get("$validation"),c=a.get("$timeout"),d=a.get("$parse");return{link:function(a,e,f){var g=d(f.validationReset)(a);c(function(){e.on("click",function(a){a.preventDefault(),b.reset(g)})})}}}])}.call(this); \ No newline at end of file +(function(){angular.module("validation",["validation.provider","validation.directive"])}).call(this),function(){angular.module("validation.provider",[]).provider("$validation",function(){var a,b,c,d,e,f=this,g=function(f){a=f,b=a.get("$rootScope"),c=a.get("$http"),d=a.get("$q"),e=a.get("$timeout")},h={},i={};this.setExpression=function(a){return angular.extend(h,a),f},this.getExpression=function(a){return h[a]},this.setDefaultMsg=function(a){return angular.extend(i,a),f},this.getDefaultMsg=function(a){return i[a]},this.setErrorHTML=function(a){return a.constructor===Function?(f.getErrorHTML=a,f):void 0},this.getErrorHTML=function(a){return'

'+a+"

"},this.setSuccessHTML=function(a){return a.constructor===Function?(f.getSuccessHTML=a,f):void 0},this.getSuccessHTML=function(a){return'

'+a+"

"},this.showSuccessMessage=!0,this.showErrorMessage=!0,this.checkValid=function(a){return void 0===a.$valid?!1:a&&a.$valid===!0},this.validate=function(a){var c=d.defer(),g=0;if(void 0===a)return console.error("This is not a regular Form name scope"),c.reject("This is not a regular Form name scope"),c.promise;if(a.validationId)b.$broadcast(a.$name+"submit-"+a.validationId,g++);else if(a.constructor===Array)for(var h in a)b.$broadcast(a[h].$name+"submit-"+a[h].validationId,g++);else for(var i in a)"$"!==i[0]&&a[i].hasOwnProperty("$dirty")&&b.$broadcast(i+"submit-"+a[i].validationId,g++);return c.promise.success=function(a){return c.promise.then(function(b){a(b)}),c.promise},c.promise.error=function(a){return c.promise.then(null,function(b){a(b)}),c.promise},e(function(){f.checkValid(a)?c.resolve("success"):c.reject("error")}),c.promise},this.validCallback=null,this.invalidCallback=null,this.reset=function(a){if(void 0===a)return void console.error("This is not a regular Form name scope");if(a.validationId)b.$broadcast(a.$name+"reset-"+a.validationId);else if(a.constructor===Array)for(var c in a)b.$broadcast(a[c].$name+"reset-"+a[c].validationId);else for(var d in a)"$"!==d[0]&&a[d].hasOwnProperty("$dirty")&&b.$broadcast(d+"reset-"+a[d].validationId)},this.$get=["$injector",function(a){return g(a),{setErrorHTML:this.setErrorHTML,getErrorHTML:this.getErrorHTML,setSuccessHTML:this.setSuccessHTML,getSuccessHTML:this.getSuccessHTML,setExpression:this.setExpression,getExpression:this.getExpression,setDefaultMsg:this.setDefaultMsg,getDefaultMsg:this.getDefaultMsg,showSuccessMessage:this.showSuccessMessage,showErrorMessage:this.showErrorMessage,checkValid:this.checkValid,validate:this.validate,validCallback:this.validCallback,invalidCallback:this.invalidCallback,reset:this.reset}}]})}.call(this),function(){angular.module("validation.directive",["validation.provider"]).directive("validator",["$injector",function(a){var b=a.get("$validation"),c=a.get("$q"),d=a.get("$timeout"),e=function(a,c,d,e,f){var g,h=c||b.getDefaultMsg(d).success;return g=e.messageId?angular.element(document.querySelector("#"+e.messageId)):a.next(),b.showSuccessMessage&&h&&g.html(b.getSuccessHTML(h)),f.$setValidity(f.$name,!0),e.validCallback&&e.validCallback({message:h}),b.validCallback&&b.validCallback(a),!0},f=function(a,c,d,e,f){var g,h=c||b.getDefaultMsg(d).error;return g=e.messageId?angular.element(document.querySelector("#"+e.messageId)):a.next(),b.showErrorMessage&&h&&g.html(b.getErrorHTML(h)),f.$setValidity(f.$name,!1),e.invalidCallback&&e.invalidCallback({message:h}),b.invalidCallback&&b.invalidCallback(a),!1},g={},h=function(a,d,g,i,j,k){var l=j.slice(0),m=l[0].trim(),n=m.indexOf("="),o=-1===n?m:m.substr(0,n),p=-1===n?null:m.substr(n+1),q=l.slice(1),r=o+"SuccessMessage",s=o+"ErrorMessage",t=b.getExpression(o),u={success:function(){return e(d,g[r],o,a,i),q.length?h(a,d,g,i,q,k):!0},error:function(){return f(d,g[s],o,a,i)}};return void 0===t?(console.error('You are using undefined validator "%s"',o),q.length?h(a,d,g,i,q,k):void 0):t.constructor===Function?c.all([b.getExpression(o)(k,a,d,g,p)]).then(function(a){return a&&a.length>0&&a[0]?u.success():u.error()},function(){return u.error()}):t.constructor===RegExp&&void 0!==k&&null!==k&&b.getExpression(o).test(k)?u.success():u.error()},i=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)},j=function(){return i()+i()+i()+i()};return{restrict:"A",require:"ngModel",scope:{model:"=ngModel",initialValidity:"=initialValidity",validCallback:"&",invalidCallback:"&",messageId:"@"},link:function(a,b,c,e){var f,i=function(){},k=c.validator.split(","),l=e.validationId=j();"boolean"==typeof a.initialValidity&&(f=a.initialValidity),a.messageId||b.after(""),e.$setValidity(e.$name,f),a.$on(e.$name+"reset-"+l,function(){i(),d(function(){e.$setViewValue(""),e.$setPristine(),e.$setValidity(e.$name,void 0),e.$render(),a.messageId?angular.element(document.querySelector("#"+a.messageId)).html(""):b.next().html("")})}),function(){return a.$on(e.$name+"submit-"+l,function(f,j){var l=e.$viewValue,m=!1;m=h(a,b,c,e,k,l),"submit"===c.validMethod&&(i(),i=a.$watch("model",function(d,f){d=e.$viewValue,d!==f&&((void 0===d||null===d)&&(d=""),m=h(a,b,c,e,k,d))}));var n=function(a){a?delete g[j]:(g[j]=b[0],d(function(){g[Math.min.apply(null,Object.keys(g))].focus()},0))};m.constructor===Object?m.then(n):n(m)}),"blur"===c.validMethod?void b.bind("blur",function(){var d=e.$viewValue;a.$apply(function(){h(a,b,c,e,k,d)})}):void("submit"!==c.validMethod&&"submit-only"!==c.validMethod&&a.$watch("model",function(d){if(d=e.$viewValue,e.$pristine&&e.$viewValue)e.$setViewValue(e.$viewValue);else if(e.$pristine)return void(a.messageId?angular.element(document.querySelector("#"+a.messageId)).html(""):b.next().html(""));h(a,b,c,e,k,d)}))}(),d(function(){c.$observe("noValidationMessage",function(c){var d;d=a.messageId?angular.element(document.querySelector("#"+a.messageId)):b.next(),"true"==c||c===!0?d.css("display","none"):("false"==c||c===!1)&&d.css("display","block")})})}}}]).directive("validationSubmit",["$injector",function(a){var b=a.get("$validation"),c=a.get("$timeout"),d=a.get("$parse");return{priority:1,require:"?ngClick",link:function(a,e,f){var g=d(f.validationSubmit)(a);c(function(){e.off("click"),e.on("click",function(c){c.preventDefault(),b.validate(g).success(function(){d(f.ngClick)(a)})})})}}}]).directive("validationReset",["$injector",function(a){var b=a.get("$validation"),c=a.get("$timeout"),d=a.get("$parse");return{link:function(a,e,f){var g=d(f.validationReset)(a);c(function(){e.on("click",function(a){a.preventDefault(),b.reset(g)})})}}}])}.call(this); \ No newline at end of file diff --git a/src/directive.js b/src/directive.js index c2ef62e..1a5d403 100644 --- a/src/directive.js +++ b/src/directive.js @@ -258,6 +258,7 @@ if (attrs.validMethod === 'submit') { watch(); // clear previous scope.$watch watch = scope.$watch('model', function(value, oldValue) { + value = ctrl.$viewValue; // don't watch when init if (value === oldValue) { @@ -318,6 +319,7 @@ * This is the default method */ scope.$watch('model', function(value) { + value = ctrl.$viewValue; /** * dirty, pristine, viewValue control here */ diff --git a/test/unit/actualValue.js b/test/unit/actualValue.js new file mode 100644 index 0000000..7b2af23 --- /dev/null +++ b/test/unit/actualValue.js @@ -0,0 +1,119 @@ +'use strict'; + +/* jasmine specs for provider go here */ + +describe('provider', function() { + + var $rootScope, + $compile, + $scope, + $timeout, + element, + validationProvider, + myApp; + + beforeEach(function() { + myApp = angular.module('myApp', ['validation', 'validation.rule']) + .config(function($validationProvider) { + validationProvider = $validationProvider; + }); + + return myApp; + }); + + beforeEach(module('myApp')); + + beforeEach(inject(function($injector) { + $rootScope = $injector.get('$rootScope'); + $compile = $injector.get('$compile'); + $scope = $rootScope.$new(); + $timeout = $injector.get('$timeout'); + + element = $compile('
')($scope); + angular.element(document.body).append(element); + $scope.$digest(); + })); + + it('set value to 123', inject(function() { + + var submitSpy = jasmine.createSpy('submitSpy'), + successSpy = jasmine.createSpy('successSpy'), + errorSpy = jasmine.createSpy('errorSpy'); + + $scope.$apply(function() { + $scope.number = 123; + }); + + $scope.$on('numberWatchsubmit-' + $scope.Form.numberWatch.validationId, function() { + submitSpy(); + }); + + validationProvider.validate($scope.Form) + .success(function() { + successSpy(); + }) + .error(function() { + errorSpy(); + }); + + $timeout.flush(); + expect(submitSpy).toHaveBeenCalled(); + expect(successSpy).toHaveBeenCalled(); + expect(errorSpy).not.toHaveBeenCalled(); + + })); + + it('set value to 1234567', inject(function() { + + var submitSpy = jasmine.createSpy('submitSpy'), + successSpy = jasmine.createSpy('successSpy'), + errorSpy = jasmine.createSpy('errorSpy'); + + $scope.$apply(function() { + $scope.number = 1234567; + }); + + $scope.$on('numberWatchsubmit-' + $scope.Form.numberWatch.validationId, function() { + submitSpy(); + }); + + validationProvider.validate($scope.Form) + .success(function() { + successSpy(); + }) + .error(function() { + errorSpy(); + }); + + $timeout.flush(); + expect(submitSpy).toHaveBeenCalled(); + expect(successSpy).not.toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalled(); + + })); + + it('set value to "ABC"', inject(function() { + + var submitSpy = jasmine.createSpy('submitSpy'), + successSpy = jasmine.createSpy('successSpy'), + errorSpy = jasmine.createSpy('errorSpy'); + + // expect error because we are using not type="text" + try { + $scope.$apply(function() { + $scope.number = 'ABC'; + }); + } catch (e) { + errorSpy(); + } + + $scope.$on('numberWatchsubmit-' + $scope.Form.numberWatch.validationId, function() { + submitSpy(); + }); + + expect(submitSpy).not.toHaveBeenCalled(); + expect(successSpy).not.toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalled(); + + })); +}); diff --git a/test/unit/providerSpec.js b/test/unit/providerSpec.js index e4a09af..69be17b 100644 --- a/test/unit/providerSpec.js +++ b/test/unit/providerSpec.js @@ -2,7 +2,7 @@ /* jasmine specs for provider go here */ -describe('provider', function () { +describe('provider', function() { var $rootScope, $compile, @@ -12,9 +12,9 @@ describe('provider', function () { validationProvider, myApp; - beforeEach(function () { + beforeEach(function() { myApp = angular.module('myApp', ['validation', 'validation.rule']) - .config(function ($validationProvider) { + .config(function($validationProvider) { validationProvider = $validationProvider; }); @@ -23,7 +23,7 @@ describe('provider', function () { beforeEach(module('myApp')); - beforeEach(inject(function ($injector) { + beforeEach(inject(function($injector) { $rootScope = $injector.get('$rootScope'); $compile = $injector.get('$compile'); $scope = $rootScope.$new(); @@ -32,7 +32,7 @@ describe('provider', function () { element = $compile('
')($scope); })); - it('set/get Expression (RegExp or Function)', inject(function () { + it('set/get Expression (RegExp or Function)', inject(function() { var model = { huei: /^huei$/ }; @@ -41,7 +41,7 @@ describe('provider', function () { expect(validationProvider.getExpression('huei')).toEqual(model.huei); model = { - huei: function () { + huei: function() { return true; } }; @@ -50,7 +50,7 @@ describe('provider', function () { expect(validationProvider.getExpression('huei')).toBe(model.huei); })); - it('set/get DefaultMsg (String)', inject(function () { + it('set/get DefaultMsg (String)', inject(function() { var obj = { huei: { error: 'It\'s should be huei', @@ -67,12 +67,12 @@ describe('provider', function () { } })); - it('set/get successHTML', inject(function () { + it('set/get successHTML', inject(function() { validationProvider.setSuccessHTML('sethtml'); expect(validationProvider.getSuccessHTML('true')).not.toEqual('sethtml'); expect(validationProvider.getSuccessHTML('true')).toEqual('

true

'); - validationProvider.setSuccessHTML(function (msg) { + validationProvider.setSuccessHTML(function(msg) { return '

' + msg + '

'; }); @@ -81,19 +81,19 @@ describe('provider', function () { })); - it('set/get errorHTML', inject(function () { + it('set/get errorHTML', inject(function() { validationProvider.setErrorHTML('sethtml'); expect(validationProvider.getErrorHTML('false')).not.toEqual('sethtml'); expect(validationProvider.getErrorHTML('false')).toEqual('

false

'); - validationProvider.setErrorHTML(function (msg) { + validationProvider.setErrorHTML(function(msg) { return '

' + msg + '

'; }); expect(validationProvider.getErrorHTML('error')).toEqual('

error

'); })); - it('checkValid', inject(function () { + it('checkValid', inject(function() { expect(validationProvider.checkValid($scope.Form)).toBe(false); $scope.Form.required.$setViewValue('required'); expect(validationProvider.checkValid($scope.Form)).toBe(true); @@ -101,9 +101,9 @@ describe('provider', function () { expect(validationProvider.checkValid($scope.Form)).toBe(false); })); - it('reset', inject(function () { + it('reset', inject(function() { var resetSpy = jasmine.createSpy('resetSpy'); - $scope.$on('requiredreset-' + $scope.Form.required.validationId, function () { + $scope.$on('requiredreset-' + $scope.Form.required.validationId, function() { resetSpy(); }); validationProvider.reset($scope.Form); @@ -111,7 +111,7 @@ describe('provider', function () { expect(resetSpy).toHaveBeenCalled(); })); - it('validate - submit', inject(function () { + it('validate - submit', inject(function() { var submitSpy = jasmine.createSpy('submitSpy'), successSpy = jasmine.createSpy('successSpy'), errorSpy = jasmine.createSpy('errorSpy'), @@ -120,17 +120,17 @@ describe('provider', function () { errorSpy2 = jasmine.createSpy('errorSpy2'); // test .success() - $scope.$on('requiredsubmit-' + $scope.Form.required.validationId, function () { + $scope.$on('requiredsubmit-' + $scope.Form.required.validationId, function() { submitSpy(); }); - $scope.$apply(function () { + $scope.$apply(function() { $scope.required = 'Required'; }); validationProvider.validate($scope.Form) - .success(function () { + .success(function() { successSpy(); }) - .error(function () { + .error(function() { errorSpy(); }); @@ -140,19 +140,19 @@ describe('provider', function () { expect(errorSpy).not.toHaveBeenCalled(); // test .error() - $scope.$apply(function () { + $scope.$apply(function() { $scope.required = ''; }); - $scope.$on('requiredsubmit-' + $scope.Form.required.validationId, function () { + $scope.$on('requiredsubmit-' + $scope.Form.required.validationId, function() { submitSpy2(); }); validationProvider.validate($scope.Form) - .success(function () { + .success(function() { successSpy2(); }) - .error(function () { + .error(function() { errorSpy2(); });