From 7a5ab0d910815cfc192c363cbb960fe94815cebe Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 6 Sep 2022 14:19:09 -0400 Subject: [PATCH] Afform - Fix setting default value for date filter fields Fixes dev/core#3111 --- .../elements/afGuiField.component.js | 28 +++++++---- ext/afform/core/ang/af/afField.component.js | 48 ++++++++++--------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js b/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js index 177e9b1700d9..8de37bbf5fc1 100644 --- a/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js +++ b/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js @@ -20,8 +20,6 @@ // When search-by-range is enabled the second element gets a suffix for some properties like "placeholder2" rangeElements = ['', '2'], dateRangeElements = ['1', '2'], - relativeDatesWithPickRange = CRM.afGuiEditor.dateRanges, - relativeDatesWithoutPickRange = relativeDatesWithPickRange.slice(1), yesNo = [ {id: '1', label: ts('Yes')}, {id: '0', label: ts('No')} @@ -30,7 +28,7 @@ this.$onInit = function() { ctrl.hasDefaultValue = !!getSet('afform_default'); - ctrl.fieldDefn = angular.extend({}, ctrl.getDefn(), ctrl.node.defn); + setFieldDefn(); ctrl.inputTypes = _.transform(_.cloneDeep(afGui.meta.inputTypes), function(inputTypes, type) { if (inputTypeCanBe(type.name)) { // Change labels for EntityRef fields @@ -49,6 +47,7 @@ inputTypes.push(type); } }); + setDateOptions(); }; this.getFkEntity = function() { @@ -120,11 +119,8 @@ }; this.getOptions = function() { - if (ctrl.node.defn && ctrl.node.defn.options) { - return ctrl.node.defn.options; - } - if (_.includes(['Date', 'Timestamp'], $scope.getProp('data_type'))) { - return $scope.getProp('search_range') ? relativeDatesWithPickRange : relativeDatesWithoutPickRange; + if (ctrl.fieldDefn.options) { + return ctrl.fieldDefn.options; } if (ctrl.getDefn().input_type === 'EntityRef') { // Build a list of all entities in this form that can be referenced by this field. @@ -218,6 +214,10 @@ if (newVal && getSet('input_attrs.multiple')) { getSet('input_attrs.multiple', false); } + if (ctrl.hasDefaultValue) { + $scope.toggleDefaultValue(); + } + setDateOptions(); }; $scope.toggleRequired = function() { @@ -233,6 +233,16 @@ ($scope.getProp('input_type') === 'CheckBox' || $scope.getProp('input_attrs.multiple'))); } + function setFieldDefn() { + ctrl.fieldDefn = angular.extend({}, ctrl.getDefn(), ctrl.node.defn); + } + + function setDateOptions() { + if (_.includes(['Date', 'Timestamp'], $scope.getProp('data_type'))) { + ctrl.node.defn.options = $scope.getProp('search_range') ? CRM.afGuiEditor.dateRanges : CRM.afGuiEditor.dateRanges.slice(1); + setFieldDefn(); + } + } $scope.toggleDefaultValue = function() { if (ctrl.hasDefaultValue) { @@ -302,7 +312,7 @@ clearOut(ctrl.node, ['defn', 'input_attrs']); } } - ctrl.fieldDefn = angular.extend({}, ctrl.getDefn(), ctrl.node.defn); + setFieldDefn(); // When changing the multiple property, force-reset the default value widget if (ctrl.hasDefaultValue && _.includes(['input_type', 'input_attrs.multiple'], propName)) { diff --git a/ext/afform/core/ang/af/afField.component.js b/ext/afform/core/ang/af/afField.component.js index 63d0021f2478..eb2da82a6ae7 100644 --- a/ext/afform/core/ang/af/afField.component.js +++ b/ext/afform/core/ang/af/afField.component.js @@ -37,26 +37,6 @@ namePrefix = this.fieldName.substr(0, this.fieldName.length - this.defn.name.length); } - if (ctrl.defn.search_range) { - // Initialize value as object unless using relative date select - var initialVal = $scope.dataProvider.getFieldData()[ctrl.fieldName]; - if (!_.isArray($scope.dataProvider.getFieldData()[ctrl.fieldName]) && - (ctrl.defn.input_type !== 'Select' || !ctrl.defn.is_date || initialVal !== '{}') - ) { - $scope.dataProvider.getFieldData()[ctrl.fieldName] = {}; - } - // Initialize inputAttrs (only used for datePickers at the moment) - if (ctrl.defn.is_date) { - this.inputAttrs.push(ctrl.defn.input_attrs || {}); - for (var i = 1; i <= 2; ++i) { - var attrs = _.cloneDeep(ctrl.defn.input_attrs || {}); - attrs.placeholder = attrs['placeholder' + i]; - attrs.timePlaceholder = attrs['timePlaceholder' + i]; - ctrl.inputAttrs.push(attrs); - } - } - } - // is_primary field - watch others in this afRepeat block to ensure only one is selected if (ctrl.fieldName === 'is_primary' && 'repeatIndex' in $scope.dataProvider) { $scope.$watch('dataProvider.afRepeat.getEntityController().getData()', function (items, prev) { @@ -135,6 +115,26 @@ else if (ctrl.defn.afform_default) { setValue(ctrl.defn.afform_default); } + + if (ctrl.defn.search_range) { + // Initialize value as object unless using relative date select + var initialVal = $scope.dataProvider.getFieldData()[ctrl.fieldName]; + if (!_.isArray($scope.dataProvider.getFieldData()[ctrl.fieldName]) && + (ctrl.defn.input_type !== 'Select' || !ctrl.defn.is_date || initialVal === '{}') + ) { + $scope.dataProvider.getFieldData()[ctrl.fieldName] = {}; + } + // Initialize inputAttrs (only used for datePickers at the moment) + if (ctrl.defn.is_date) { + ctrl.inputAttrs.push(ctrl.defn.input_attrs || {}); + for (var i = 1; i <= 2; ++i) { + var attrs = _.cloneDeep(ctrl.defn.input_attrs || {}); + attrs.placeholder = attrs['placeholder' + i]; + attrs.timePlaceholder = attrs['timePlaceholder' + i]; + ctrl.inputAttrs.push(attrs); + } + } + } }); }; @@ -149,13 +149,17 @@ } } else if (ctrl.defn.input_type === 'Number') { value = +value; - } else if (ctrl.defn.search_range && !_.isPlainObject(value)) { + } + // Initialze search range unless the field also has options (as in a date search) and + // the default value is a valid option. + else if (ctrl.defn.search_range && !_.isPlainObject(value) && + !(ctrl.defn.options && _.findWhere(ctrl.defn.options, {id: value})) + ) { value = { '>=': ('' + value).split('-')[0], '<=': ('' + value).split('-')[1] || '', }; } - $scope.dataProvider.getFieldData()[ctrl.fieldName] = value; }