From e45207cb663fc81cdaa26497a9695776925006d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A5=E1=86=BC?= =?UTF-8?q?=E1=84=80=E1=85=B5/=E1=84=92=E1=85=A7=E1=86=B8=E1=84=8B?= =?UTF-8?q?=E1=85=A5=E1=86=B8=E1=84=89=E1=85=B5=E1=84=89=E1=85=B3=E1=84=90?= =?UTF-8?q?=E1=85=A6=E1=86=B7=E1=84=80=E1=85=A2=E1=84=87=E1=85=A1=E1=86=AF?= =?UTF-8?q?=E1=84=90=E1=85=B5=E1=86=B7?= Date: Tue, 6 Jan 2015 14:41:56 +0900 Subject: [PATCH 1/2] add .gitignore ( ignore web storm or intelij files ) reformat code and fix jshint error replace console to $log updateOnBlur directive only use scope.$apply method when scope.$root.$$phase is null when destroy updateOnBlur directive, remove element event handler ( prevent memory leak ) add submit event handler to updateOnBlur directive ( check validation not only blur but also submit ) --- .gitignore | 1 + validationdirectives.js | 187 ++++++++++++++++++++++------------------ 2 files changed, 103 insertions(+), 85 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/validationdirectives.js b/validationdirectives.js index 9e4f88c..aa2d03f 100644 --- a/validationdirectives.js +++ b/validationdirectives.js @@ -1,97 +1,114 @@ +'use strict'; + +/** + * Anularjs Module for form validation directives + * http://blog.technovert.com/2014/03/angularjs-form-validation-library-directives/#remote + */ angular.module('validation', []) - .directive('customValidator', [function () { - return { - restrict: 'A', - require: 'ngModel', - link: function (scope, elm, attr, ngModelCtrl) { - var validateFunctionNames = attr["validateFunctions"].split(","); - var validatorNames = attr["customValidator"].split(","); - ngModelCtrl.$parsers.push(function (value) { - var hasErrors = false; - angular.forEach(validateFunctionNames, function (functionName, index) { - if (!scope[functionName]) { - console.log('There is no function with name ' + functionName + ' available on the scope. Please make sure the function exists on current scope or its parent.'); - } else { - var result = scope[functionName](value); - if (result && result != false) { - ngModelCtrl.$setValidity(validatorNames[index], true); + .directive('customValidator', ['$log', function ($log) { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, elm, attr, ngModelCtrl) { + var validateFunctionNames = attr.validateFunctions.split(','); + var validatorNames = attr.customValidator.split(','); + ngModelCtrl.$parsers.push(function (value) { + var hasErrors = false; + angular.forEach(validateFunctionNames, function (functionName, index) { + if (!scope[functionName]) { + $log.log('There is no function with name ' + functionName + ' available on the scope. Please make sure the function exists on current scope or its parent.'); } else { - ngModelCtrl.$setValidity(validatorNames[index], false); - hasErrors = true; - } - - } - }); - return hasErrors ? undefined : value; - }); - } - }; -}]) - .directive('customRemoteValidator', [function () { - return { - restrict: 'A', - require: 'ngModel', - link: function (scope, elm, attr, ngModelCtrl) { - var validateFunctionNames = attr["remoteValidateFunctions"].split(","); - var validatorNames = attr["customRemoteValidator"].split(","); - ngModelCtrl.$parsers.push(function (value) { - angular.forEach(validateFunctionNames, function (functionName, index) { - if (!scope[functionName]) { - console.log('There is no function with ' + functionName + ' available on the scope. Please make sure the function exists on current scope or its parent.'); - } else { - var result = scope[functionName](value); - if (result.then) { - result.then(function (data) { //For promise type result object - ngModelCtrl.$setValidity(validatorNames[index], data); - }, function (error) { + var result = scope[functionName](value); + if (result && result !== false) { + ngModelCtrl.$setValidity(validatorNames[index], true); + } else { ngModelCtrl.$setValidity(validatorNames[index], false); - }); + hasErrors = true; + } + } - } + }); + return hasErrors ? undefined : value; }); - return value; - }); - } - }; -}]) - .directive('validationMessages', function () { - return { - scope: { - modelController: '=' - }, - restrict: 'EA', - link: function (scope, elm, attrs) { - if (!scope.modelController) { - console.log('Requires a html attribute data-model-controller. This should point to the input field model controller.'); } - scope.$watch('modelController.$error', function (newValue) { - if (newValue) { - scope.errorMessages = []; - angular.forEach(newValue, function (value, key) { - if (value && attrs[key + 'Error']) { - scope.errorMessages.push(attrs[key + 'Error']); + }; + }]) + .directive('customRemoteValidator', ['$log', function ($log) { + return { + restrict: 'A', + require: 'ngModel', + link: function (scope, elm, attr, ngModelCtrl) { + var validateFunctionNames = attr.remoteValidateFunctions.split(','); + var validatorNames = attr.customRemoteValidator.split(','); + ngModelCtrl.$parsers.push(function (value) { + angular.forEach(validateFunctionNames, function (functionName, index) { + if (!scope[functionName]) { + $log.log('There is no function with ' + functionName + ' available on the scope. Please make sure the function exists on current scope or its parent.'); + } else { + var result = scope[functionName](value); + if (result.then) { + result.then(function (data) { //For promise type result object + ngModelCtrl.$setValidity(validatorNames[index], data); + }, function (/*error*/) { + ngModelCtrl.$setValidity(validatorNames[index], false); + }); + } } }); + return value; + }); + } + }; + }]) + .directive('validationMessages', ['$log', function ($log) { + return { + scope: { + modelController: '=' + }, + restrict: 'EA', + link: function (scope, elm, attrs) { + if (!scope.modelController) { + $log.log('Requires a html attribute data-model-controller. This should point to the input field model controller.'); + } + scope.$watch('modelController.$error', function (newValue) { + if (newValue) { + scope.errorMessages = []; + angular.forEach(newValue, function (value, key) { + if (value && attrs[key + 'Error']) { + scope.errorMessages.push(attrs[key + 'Error']); + } + }); + } + }, true); + }, + template: '
{{message}}
' + }; + }]) + .directive('updateOnBlur', [ function () { + return { + restrict: 'A', + require: 'ngModel', + priority: '100', + link: function (scope, elm, attr, ngModelCtrl) { + if (attr.type === 'radio' || attr.type === 'checkbox') { + return; } - }, true); - }, - template: '
{{message}}
' - } -}) - .directive('updateOnBlur', function () { - return { - restrict: 'A', - require: 'ngModel', - priority: '100', - link: function (scope, elm, attr, ngModelCtrl) { - if (attr.type === 'radio' || attr.type === 'checkbox') return; - elm.unbind('input').unbind('keydown').unbind('change'); - elm.bind('blur', function () { - scope.$apply(function () { + function updateNgModel() { ngModelCtrl.$setViewValue(elm.val()); + } + + elm.unbind('input').unbind('keydown').unbind('change'); + elm.bind('blur submit', function () { + updateNgModel(); + if(scope.$root.$$phase){ + scope.$apply(); + } + }); + + scope.$on('$destroy', function () { + elm.unbind('blur').unbind('submit'); }); - }); - } - }; -}); \ No newline at end of file + } + }; + }]); From 1113b0b84c2436d7c0155b8d920f63822f033039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A5=E1=86=BC?= =?UTF-8?q?=E1=84=80=E1=85=B5/=E1=84=92=E1=85=A7=E1=86=B8=E1=84=8B?= =?UTF-8?q?=E1=85=A5=E1=86=B8=E1=84=89=E1=85=B5=E1=84=89=E1=85=B3=E1=84=90?= =?UTF-8?q?=E1=85=A6=E1=86=B7=E1=84=80=E1=85=A2=E1=84=87=E1=85=A1=E1=86=AF?= =?UTF-8?q?=E1=84=90=E1=85=B5=E1=86=B7?= Date: Tue, 6 Jan 2015 17:32:48 +0900 Subject: [PATCH 2/2] scope.$apply execution condition of updateOnBlur directive is changed --- validationdirectives.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validationdirectives.js b/validationdirectives.js index aa2d03f..43d22be 100644 --- a/validationdirectives.js +++ b/validationdirectives.js @@ -84,7 +84,7 @@ angular.module('validation', []) template: '
{{message}}
' }; }]) - .directive('updateOnBlur', [ function () { + .directive('updateOnBlur', [function () { return { restrict: 'A', require: 'ngModel', @@ -101,7 +101,7 @@ angular.module('validation', []) elm.unbind('input').unbind('keydown').unbind('change'); elm.bind('blur submit', function () { updateNgModel(); - if(scope.$root.$$phase){ + if (!scope.$root.$$phase) { scope.$apply(); } });