CRM-21849: Switch loading relationship data from backend to frontend
authorMichael Devery <michael@compucorp.co.uk>
Mon, 16 Apr 2018 12:06:05 +0000 (13:06 +0100)
committerMichael Devery <michael@compucorp.co.uk>
Mon, 16 Apr 2018 13:24:32 +0000 (14:24 +0100)
The formatting of relationship data is a FE related task and can be done
 in Javascript. This also allows reloading the data if some options
 change after editing relationship types.

CRM/Contact/Form/Relationship.php
templates/CRM/Contact/Form/Relationship.tpl

index 16932158ad099225b04ed83c3c87a9fbdf43b835..f4d9a147811938c6188c2d2e279193b3f4fbb96a 100644 (file)
@@ -299,9 +299,6 @@ class CRM_Contact_Form_Relationship extends CRM_Core_Form {
     // Select list
     $relationshipList = CRM_Contact_BAO_Relationship::getContactRelationshipType($this->_contactId, $this->_rtype, $this->_relationshipId);
 
-    // Metadata needed on clientside
-    $this->assign('relationshipData', self::getRelationshipTypeMetadata($relationshipList));
-
     foreach ($this->_allRelationshipNames as $id => $vals) {
       if ($vals['name_a_b'] === 'Employee of') {
         $this->assign('employmentRelationship', $id);
index 77a3244014735d9a69e69071cc47b124be11895f..1c69d1032ef880b8c56be532d5c1e672701d927e 100644 (file)
       CRM.$(function($) {
         var
           $form = $("form.{/literal}{$form.formClass}{literal}"),
-          relationshipData = {/literal}{$relationshipData|@json_encode}{literal};
-        $('[name=relationship_type_id]', $form).change(function() {
+          $relationshipTypeSelect = $('[name=relationship_type_id]', $form),
+          relationshipData = {},
+          contactTypes = {};
+
+        $('body').on('crmOptionsEdited', 'a.crm-option-edit-link', refreshRelationshipData);
+
+        // Initial load and trigger change on select
+        refreshRelationshipData().done(function() {
+          $relationshipTypeSelect.change();
+        });
+
+        /**
+         * Fetch contact types and reset relationship data
+         */
+        function refreshRelationshipData() {
+          var defer = $.Deferred();
+
+          // reset
+          relationshipData = {};
+
+          getContactTypes().then(function() {
+            getRelationshipData().then(function() {
+              defer.resolve();
+            });
+          });
+
+          return defer.promise();
+        }
+
+        /**
+         * Fetches the relationship data using latest relationship types
+         */
+        function getRelationshipData() {
+          var subtype,
+            type,
+            label,
+            placeholder,
+            defer = $.Deferred();
+
+          if ($.isEmptyObject(relationshipData)) {
+            CRM.api3("RelationshipType", "get").done(function (data) {
+              $.each(data.values, function (key, relType) {
+                $.each(["a", "b"], function (index, suffix) {
+                  subtype = relType["contact_subtype_" + suffix];
+                  type = subtype || relType["contact_type_" + suffix];
+                  label = getContactTypeLabel(type) || "Contact";
+                  placeholder = "- select " + label.toLowerCase() + " -";
+                  relType["placeholder_" + suffix] = placeholder;
+                });
+                relationshipData[relType["id"]] = relType;
+              });
+
+              defer.resolve(relationshipData);
+            });
+          } else {
+            defer.resolve(relationshipData);
+          }
+
+          return defer.promise();
+        }
+
+        /**
+         * Gets a contact type label based on a provided name
+         * @param {String} name - the name of the contact type
+         */
+        function getContactTypeLabel(name) {
+          var label = "";
+
+          $.each(contactTypes, function(index, contactType) {
+            if (contactType.name === name) {
+              label = contactType.label;
+              return false;
+            }
+          });
+
+          return label;
+        }
+
+        /**
+         * Fetches contact types
+         */
+        function getContactTypes() {
+          var defer = $.Deferred();
+          if ($.isEmptyObject(contactTypes)) {
+            CRM.api3("ContactType", "get").done(function (data) {
+              contactTypes = data.values;
+              defer.resolve(contactTypes);
+            });
+          } else {
+            defer.resolve(contactTypes);
+          }
+
+          return defer.promise();
+        }
+
+        $relationshipTypeSelect.change(function() {
+          var $select = $(this);
+
+          // ensure we have relationship data before changing anything
+          getRelationshipData().then(function() {
+            updateSelect($select);
+          })
+        });
+
+        function updateSelect($select) {
           var
-            val = $(this).val(),
+            val = $select.val(),
             $contactField = $('#related_contact_id[type=text]', $form);
           if (!val && $contactField.length) {
             $contactField
 
             CRM.buildCustomData('Relationship', rType);
           }
-        }).change();
+        }
       });
       {/literal}
     </script>