Support is_primary fields and boolean options.
authorColeman Watts <coleman@civicrm.org>
Thu, 16 Jan 2020 15:53:24 +0000 (10:53 -0500)
committerCiviCRM <info@civicrm.org>
Wed, 16 Sep 2020 02:13:21 +0000 (19:13 -0700)
Civi 5.23 changes boolean options to be real true and false instead of '1' and '0'
so added version bump to keep in step.

13 files changed:
ext/afform/core/ang/af/Field.js
ext/afform/core/ang/af/Repeat.js
ext/afform/core/ang/af/afRepeat.html
ext/afform/core/ang/af/fields/CheckBox.html
ext/afform/core/ang/af/fields/Radio.html
ext/afform/core/ang/afjoinAddressDefault.aff.html
ext/afform/core/ang/afjoinEmailDefault.aff.html
ext/afform/core/ang/afjoinIMDefault.aff.html
ext/afform/core/ang/afjoinPhoneDefault.aff.html
ext/afform/core/info.xml
ext/afform/gui/info.xml
ext/afform/html/info.xml
ext/afform/mock/info.xml

index e23beaefbd0341279b6ec3af31679f6a04e6ff7c..12c1726ad001936a3520a559638c1547fb54e285 100644 (file)
         var ts = $scope.ts = CRM.ts('afform'),
           closestController = $($el).closest('[af-fieldset],[af-join],[af-repeat-item]'),
           afForm = ctrls[0],
-          boolOptions = [{key: '1', label: ts('Yes')}, {key: '0', label: ts('No')}];
+          boolOptions = [{key: true, label: ts('Yes')}, {key: false, label: ts('No')}],
+          // Only used for is_primary radio button
+          noOptions = [{key: true, label: ''}];
         $scope.dataProvider = closestController.is('[af-repeat-item]') ? ctrls[3] : ctrls[2] || ctrls[1];
         $scope.fieldId = afForm.getFormMeta().name + '-' + $scope.fieldName + '-' + id++;
 
         $el.addClass('af-field-type-' + _.kebabCase($scope.defn.input_type));
 
         $scope.getOptions = function() {
-          return $scope.defn.options || boolOptions;
+          return $scope.defn.options || ($scope.fieldName === 'is_primary' && $scope.defn.input_type === 'Radio' ? noOptions : boolOptions);
         };
 
         $scope.select2Options = function() {
           };
         };
 
+        // is_primary field - watch others in this afRepeat block to ensure only one is selected
+        if ($scope.fieldName === 'is_primary' && 'repeatIndex' in $scope.dataProvider) {
+          $scope.$watch('dataProvider.afRepeat.getEntityController().getData()', function (items, prev) {
+            var index = $scope.dataProvider.repeatIndex;
+            // Set first item to primary if there isn't a primary
+            if (items && !index && !_.find(items, 'is_primary')) {
+              $scope.dataProvider.getFieldData().is_primary = true;
+            }
+            // Set this item to not primary if another has been selected
+            if (items && prev && items.length === prev.length && items[index].is_primary && prev[index].is_primary &&
+              _.filter(items, 'is_primary').length > 1
+            ) {
+              $scope.dataProvider.getFieldData().is_primary = false;
+            }
+          }, true);
+        }
+
         // ChainSelect - watch control field & reload options as needed
         if ($scope.defn.input_type === 'ChainSelect') {
           $scope.$watch('dataProvider.getFieldData()[defn.input_attrs.controlField]', function(val) {
index bb25e5f820e9f9c012666e99efdc98283f5b6b84..2055f7edce47ba85dd3cd4c052ed1837775525a5 100644 (file)
@@ -59,7 +59,8 @@
         restrict: 'A',
         require: ['afRepeatItem', '^^afRepeat'],
         bindToController: {
-          item: '=afRepeatItem'
+          item: '=afRepeatItem',
+          repeatIndex: '='
         },
         link: function($scope, $el, $attr, ctrls) {
           var self = ctrls[0];
index 98346d3fe92d60c499364cf7680f8661bed0dff0..7c7ef36eb1ef4603ff864fa4d11892e1e4e3d41a 100644 (file)
@@ -1,4 +1,4 @@
-<div af-repeat-item="item" ng-repeat="item in getItems()">
+<div af-repeat-item="item" repeat-index="$index" ng-repeat="item in getItems()">
   <ng-transclude />
   <button crm-icon="fa-ban" class="btn btn-xs af-repeat-remove-btn" ng-if="canRemove()" ng-click="removeItem($index)"></button>
 </div>
index de7d94c85f5cd21a17e3bb792b4d6a409ab7ee41..8788043cb98d54482367d0ad04c8a988cf529a5e 100644 (file)
@@ -4,4 +4,4 @@
     <label for="{{ fieldId + opt.key }}">{{ opt.label }}</label>
   </li>
 </ul>
-<input type="checkbox" ng-if="!defn.options" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" ng-true-value="'1'" ng-false-value="'0'" />
+<input type="checkbox" ng-if="!defn.options" id="{{ fieldId }}" ng-model="dataProvider.getFieldData()[fieldName]" />
index 5df0bba49e6c32418a81148b13057471b8846e98..7237a698c5119c1afa89c687cbc4103b4b1f9436 100644 (file)
@@ -1,4 +1,4 @@
 <label ng-repeat="opt in getOptions() track by opt.key" >
-  <input class="crm-form-radio" type="radio" ng-model="dataProvider.getFieldData()[fieldName]" value="{{ opt.key }}" />
+  <input class="crm-form-radio" type="radio" ng-model="dataProvider.getFieldData()[fieldName]" ng-value="opt.key" />
   {{ opt.label }}
 </label>
index 76d21e406ff779a30826768a4e237eb8ba732df3..ddb1f017ed45524c6a38492ef5b914d0715e6cbf 100644 (file)
@@ -1,6 +1,7 @@
 <div class="af-container af-layout-inline">
   <af-field name="street_address" />
   <af-field name="location_type_id" />
+  <af-field name="is_primary" />
 </div>
 <div class="af-container af-layout-inline">
   <af-field name="city" />
index 71feccef5bcef9673d3a8c14cbf1f226f8dc22b2..9b1ed00145c198ad5b4389bdf1d145cf22482210 100644 (file)
@@ -1,4 +1,5 @@
 <div class="af-container af-layout-inline">
   <af-field name="email" />
   <af-field name="location_type_id" />
+  <af-field name="is_primary" />
 </div>
index 796881103d90fda7438b97b128d6abda2e304860..decf4c7af1ab1871cfd7f4540f814e2c74366961 100644 (file)
@@ -2,4 +2,5 @@
   <af-field name="name" />
   <af-field name="location_type_id" />
   <af-field name="provider_id" />
+  <af-field name="is_primary" />
 </div>
index c1ffc3ebc84d2266040fb0e36d1aff5ebbf350b4..9d9ebc5108541bc9b2859dfc073bc69c0e18c691 100644 (file)
@@ -2,4 +2,5 @@
   <af-field name="phone" />
   <af-field name="location_type_id" />
   <af-field name="phone_type_id" />
+  <af-field name="is_primary" />
 </div>
index 5cc0e38e69a4d841f50f890bac47cc4cd54050de..a0c34129e1b8b56fa75fb98e1485ded551d6a471 100644 (file)
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>0.4</version>
+  <version>0.5</version>
   <develStage>alpha</develStage>
   <compatibility>
-    <ver>5.22</ver>
+    <ver>5.23</ver>
   </compatibility>
   <requires>
     <ext version="~4.5">org.civicrm.api4</ext>
index 4f38c118b54dd4016a00cf338f8d4550da299139..b03aca593ef88ea8d332e805af12abf66b1bf29b 100644 (file)
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>0.4</version>
+  <version>0.5</version>
   <develStage>alpha</develStage>
   <compatibility>
-    <ver>5.22</ver>
+    <ver>5.23</ver>
   </compatibility>
   <comments>Drag-n-drop form builder for CiviCRM Afforms.</comments>
   <requires>
index 12073096b25b17fe303fe0b2cf207a9a008d39ad..fca64082a3fa0c6e24656c7270f90403770f2c1a 100644 (file)
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>0.4</version>
+  <version>0.5</version>
   <develStage>alpha</develStage>
   <compatibility>
-    <ver>5.22</ver>
+    <ver>5.23</ver>
   </compatibility>
   <requires>
     <ext>org.civicrm.afform</ext>
index 7e7ea1cca042da4e3b70a46fcc5331165d94f487..7fefe5b47e539dcf1aa3de7e07d895b15b87eb10 100644 (file)
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>0.4</version>
+  <version>0.5</version>
   <develStage>alpha</develStage>
   <compatibility>
-    <ver>5.22</ver>
+    <ver>5.23</ver>
   </compatibility>
   <requires>
     <ext>org.civicrm.afform</ext>