Afform - Fix setting default value for date filter fields
authorColeman Watts <coleman@civicrm.org>
Tue, 6 Sep 2022 18:19:09 +0000 (14:19 -0400)
committerColeman Watts <coleman@civicrm.org>
Tue, 6 Sep 2022 18:23:38 +0000 (14:23 -0400)
Fixes dev/core#3111

ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js
ext/afform/core/ang/af/afField.component.js

index 177e9b1700d97b1f5a429752abca4647f059ebd6..8de37bbf5fc1b8c9ce4198d51191cdb5b92c8a44 100644 (file)
@@ -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() {
       };
 
       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.
         if (newVal && getSet('input_attrs.multiple')) {
           getSet('input_attrs.multiple', false);
         }
+        if (ctrl.hasDefaultValue) {
+          $scope.toggleDefaultValue();
+        }
+        setDateOptions();
       };
 
       $scope.toggleRequired = function() {
           ($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) {
               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)) {
index 63d0021f24788c7ca3d7ad12cfe6d1e8768eafc6..eb2da82a6ae720cf797e5b16fa75dfd5f5ce8c22 100644 (file)
           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) {
           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);
+              }
+            }
+          }
         });
       };
 
           }
         } 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;
       }