diff --git a/ang/civicase-base/constants.js b/ang/civicase-base/constants.js index 9e1d1a78a..2f1d1de35 100644 --- a/ang/civicase-base/constants.js +++ b/ang/civicase-base/constants.js @@ -1,4 +1,4 @@ -(function (angular, configuration) { +(function (angular, configuration, civiCrmConfig) { var module = angular.module('civicase-base'); module @@ -9,8 +9,9 @@ .constant('showFullContactNameOnActivityFeed', configuration.showFullContactNameOnActivityFeed) .constant('includeActivitiesForInvolvedContact', configuration.includeActivitiesForInvolvedContact) .constant('civicaseSingleCaseRolePerType', configuration.civicaseSingleCaseRolePerType) + .constant('dateInputFormatValue', civiCrmConfig.dateInputFormat) .constant('webformsList', { isVisible: configuration.showWebformsListSeparately, buttonLabel: configuration.webformsDropdownButtonLabel }); -})(angular, CRM['civicase-base']); +})(angular, CRM['civicase-base'], CRM.config); diff --git a/ang/civicase-base/directives/inline-datepicker.directive.js b/ang/civicase-base/directives/inline-datepicker.directive.js index e6e675f38..ec5384361 100644 --- a/ang/civicase-base/directives/inline-datepicker.directive.js +++ b/ang/civicase-base/directives/inline-datepicker.directive.js @@ -2,7 +2,7 @@ var module = angular.module('civicase-base'); module.directive('civicaseInlineDatepicker', function ($timeout, - removeDatePickerHrefs) { + dateInputFormatValue, removeDatePickerHrefs) { return { restrict: 'A', link: civicaseInlineDatepickerLink, @@ -19,6 +19,7 @@ */ function civicaseInlineDatepickerLink (scope, element, attributes, controllers) { var DATEPICKER_WRAPPER = '
'; + var API_DATE_FORMAT = 'yy-mm-dd'; var model = controllers[0]; (function init () { @@ -30,44 +31,65 @@ element.datepicker({ beforeShow: removeDatePickerHrefs, + dateFormat: dateInputFormatValue, onChangeMonthYear: removeDatePickerHrefs }); })(); /** * @param {string} modelValue the value stored in the model. - * @returns {string|undefined} it returns the date in a DD/MM/YYYY format, - * if defined. This makes the value stored in the model more user - * friendly. + * @returns {string|undefined} it returns the date in the date format + * configured by CiviCRM. This makes the value stored in the model more + * user friendly. If no value is provided then it returns undefined. */ function modelDateFormatter (modelValue) { if (modelValue) { - return moment(modelValue).format('DD/MM/YYYY'); + return $.datepicker.formatDate( + dateInputFormatValue, + $.datepicker.parseDate(API_DATE_FORMAT, modelValue) + ); } } /** * @param {string} inputValue the value stored in the input element. - * @returns {string|undefined} it returns the date in a YYYY-MM-DD format, - * if defined. This is useful when converting the human readable format - * from the input to one that can be stored in the model and passed down - * to APIs. + * @returns {string|undefined} it returns the date in a year-month-day + * format, if defined. This is useful when converting the human readable + * format from the input to one that can be stored in the model and + * passed down to APIs. */ function inputDateParser (inputValue) { if (inputValue) { - return moment(inputValue, 'DD/MM/YYYY', true).format('YYYY-MM-DD'); + try { + return $.datepicker.formatDate( + API_DATE_FORMAT, + $.datepicker.parseDate(dateInputFormatValue, inputValue) + ); + } catch (exception) { + model.$setValidity('isValidDate', false); + } } } /** * Checks if the given value is a valid date. * - * @param {string} inputValue input's date value. + * @param {string} modelValue input's date value. * @returns {boolean} true when the date is in a valid format or no value * is provided. */ - function isValidDate (inputValue) { - return !inputValue || moment(inputValue).isValid(); + function isValidDate (modelValue) { + if (!modelValue) { + return true; + } + + try { + $.datepicker.parseDate(API_DATE_FORMAT, modelValue); + + return true; + } catch (exception) { + return false; + } } } }); diff --git a/ang/test/civicase-base/directives/inline-datepicker.directive.spec.js b/ang/test/civicase-base/directives/inline-datepicker.directive.spec.js index e8428568a..9d3e2f838 100644 --- a/ang/test/civicase-base/directives/inline-datepicker.directive.spec.js +++ b/ang/test/civicase-base/directives/inline-datepicker.directive.spec.js @@ -3,14 +3,16 @@ (($) => { describe('civicaseInlineDatepicker', () => { const NG_INVALID_CLASS = 'ng-invalid'; - let $compile, $rootScope, $scope, element, originalDatepickerFunction, - removeDatePickerHrefs; + let $compile, $rootScope, $scope, dateInputFormatValue, element, + originalDatepickerFunction, removeDatePickerHrefs; beforeEach(module('civicase-base', 'civicase.data')); - beforeEach(inject((_$compile_, _$rootScope_, _removeDatePickerHrefs_) => { + beforeEach(inject((_$compile_, _$rootScope_, _dateInputFormatValue_, + _removeDatePickerHrefs_) => { $compile = _$compile_; $rootScope = _$rootScope_; + dateInputFormatValue = _dateInputFormatValue_; removeDatePickerHrefs = _removeDatePickerHrefs_; $scope = $rootScope.$new(); originalDatepickerFunction = $.fn.datepicker; @@ -32,11 +34,17 @@ expect($.fn.datepicker).toHaveBeenCalled(); }); + it('sets the date format as the one specified by CiviCRM setting', () => { + expect($.fn.datepicker).toHaveBeenCalledWith(jasmine.objectContaining({ + dateFormat: dateInputFormatValue + })); + }); + it('removes the HREF attributes from the datepicker links', () => { - expect($.fn.datepicker).toHaveBeenCalledWith({ + expect($.fn.datepicker).toHaveBeenCalledWith(jasmine.objectContaining({ beforeShow: removeDatePickerHrefs, onChangeMonthYear: removeDatePickerHrefs - }); + })); }); }); @@ -48,11 +56,11 @@ initDirective(); }); - it('sets the input format in DD/MM/YYYY', () => { + it('sets the input format in day/month/year', () => { expect(element.val()).toBe('31/01/1999'); }); - it('keeps the model value in the YYYY-MM-DD format', () => { + it('keeps the model value in the year-month-day format', () => { expect($scope.date).toBe('1999-01-31'); }); }); @@ -67,11 +75,11 @@ $scope.$digest(); }); - it('sets the input format in DD/MM/YYYY', () => { + it('sets the input format in day/month/year', () => { expect(element.val()).toBe('28/02/1999'); }); - it('keeps the model value in the YYYY-MM-DD format', () => { + it('keeps the model value in the year-month-day format', () => { expect($scope.date).toBe('1999-02-28'); }); }); diff --git a/ang/test/global.js b/ang/test/global.js index 2b925dee2..b4741bc4c 100644 --- a/ang/test/global.js +++ b/ang/test/global.js @@ -5,6 +5,7 @@ CRM.civicase = {}; CRM['civicase-base'].currentCaseCategory = 'cases'; CRM.angular = { requires: {} }; + CRM.config = {}; /** * Dependency Injection for civicase module, defined in ang/civicase.ang.php * For unit testing they needs to be mentioned here diff --git a/ang/test/mocks/data/constants.data.js b/ang/test/mocks/data/constants.data.js index 90f061973..bed45de7e 100644 --- a/ang/test/mocks/data/constants.data.js +++ b/ang/test/mocks/data/constants.data.js @@ -12,6 +12,7 @@ }; module.config(($provide) => { + $provide.constant('dateInputFormatValue', CRM.config.dateInputFormat); $provide.constant('allowMultipleCaseClients', CRM['civicase-base'].allowMultipleCaseClients); $provide.constant('allowCaseLocks', CRM['civicase-base'].allowCaseLocks); $provide.constant('currentCaseCategory', CRM['civicase-base'].currentCaseCategory); diff --git a/ang/test/mocks/data/crm.data.js b/ang/test/mocks/data/crm.data.js index 00ac6243d..29689bd1d 100644 --- a/ang/test/mocks/data/crm.data.js +++ b/ang/test/mocks/data/crm.data.js @@ -15,7 +15,7 @@ userFramework: 'Drupal', resourceBase: 'http://civicase.local/sites/all/modules/civicrm/', lcMessages: 'en_US', - dateInputFormat: 'mm/dd/yy', + dateInputFormat: 'dd/mm/yy', timeIs24Hr: false, ajaxPopupsEnabled: true, allowAlertAutodismissal: true,