From d8bc834c2060d37f6db5a1ec21a6417e5f1f8f6a Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 28 Jul 2022 17:01:07 -0400 Subject: [PATCH] Fix Angular datepicker to keep up with $digest cycle --- ang/crmUi.js | 21 ++++++++++++--------- tests/karma/unit/crmMailingRadioDateSpec.js | 7 +++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ang/crmUi.js b/ang/crmUi.js index dde019030d..602e704845 100644 --- a/ang/crmUi.js +++ b/ang/crmUi.js @@ -67,7 +67,7 @@ // Simple wrapper around $.crmDatepicker. // example with no time input: // example with custom date format: - .directive('crmUiDatepicker', function () { + .directive('crmUiDatepicker', function ($timeout) { return { restrict: 'AE', require: 'ngModel', @@ -82,14 +82,17 @@ element .crmDatepicker(scope.crmUiDatepicker) .on('change', function() { - var requiredLength = 19; - if (scope.crmUiDatepicker && scope.crmUiDatepicker.time === false) { - requiredLength = 10; - } - if (scope.crmUiDatepicker && scope.crmUiDatepicker.date === false) { - requiredLength = 8; - } - ngModel.$setValidity('incompleteDateTime', !($(this).val().length && $(this).val().length !== requiredLength)); + // Because change gets triggered from the $render function we could be either inside or outside the $digest cycle + $timeout(function() { + var requiredLength = 19; + if (scope.crmUiDatepicker && scope.crmUiDatepicker.time === false) { + requiredLength = 10; + } + if (scope.crmUiDatepicker && scope.crmUiDatepicker.date === false) { + requiredLength = 8; + } + ngModel.$setValidity('incompleteDateTime', !(element.val().length && element.val().length !== requiredLength)); + }); }); } }; diff --git a/tests/karma/unit/crmMailingRadioDateSpec.js b/tests/karma/unit/crmMailingRadioDateSpec.js index 0e47406b3e..97074bcaa0 100644 --- a/tests/karma/unit/crmMailingRadioDateSpec.js +++ b/tests/karma/unit/crmMailingRadioDateSpec.js @@ -55,6 +55,7 @@ describe('crmMailingRadioDate', function() { model.the_date = ' '; $rootScope.$digest(); + $timeout.flush(); expect($rootScope.myForm.$valid).toBe(false); expect(element.find('.radio-now').prop('checked')).toBe(false); expect(element.find('.radio-at').prop('checked')).toBe(true); @@ -63,6 +64,7 @@ describe('crmMailingRadioDate', function() { model.the_date = '2014-01-01'; $rootScope.$digest(); + $timeout.flush(); expect($rootScope.myForm.$valid).toBe(false); expect(element.find('.radio-now').prop('checked')).toBe(false); expect(element.find('.radio-at').prop('checked')).toBe(true); @@ -72,6 +74,7 @@ describe('crmMailingRadioDate', function() { model.the_date = '02:03:00'; $rootScope.$digest(); + $timeout.flush(); expect($rootScope.myForm.$valid).toBe(false); expect(element.find('.radio-now').prop('checked')).toBe(false); expect(element.find('.radio-at').prop('checked')).toBe(true); @@ -113,6 +116,7 @@ describe('crmMailingRadioDate', function() { var ndate = new Date(year, month-1, day, 0, 0, 0); model.the_date = currentDate; + $timeout.flush(); $rootScope.$digest(); expect($rootScope.myForm.$valid).toBe(true); expect(element.find('.radio-now').prop('checked')).toBe(false); @@ -132,6 +136,7 @@ describe('crmMailingRadioDate', function() { element.find('.radio-now').click().trigger('click').trigger('change'); element.find('.crm-form-date').datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', '2014-01-03')).trigger('change'); + $timeout.flush(); $rootScope.$digest(); expect(model.the_date).toBe('2014-01-03'); expect($rootScope.myForm.$valid).toBe(false); @@ -146,6 +151,7 @@ describe('crmMailingRadioDate', function() { expect(element.find('.radio-at').prop('checked')).toBe(true); element.find('.crm-form-date').datepicker('setDate', '').trigger('change'); + $timeout.flush(); $rootScope.$digest(); expect(model.the_date).toBe('04:05:00'); expect($rootScope.myForm.$valid).toBe(false); @@ -153,6 +159,7 @@ describe('crmMailingRadioDate', function() { expect(element.find('.radio-at').prop('checked')).toBe(true); element.find('.radio-now').click().trigger('click').trigger('change'); + $timeout.flush(); $rootScope.$digest(); expect(model.the_date).toBe(null); expect($rootScope.myForm.$valid).toBe(true); -- 2.25.1