Add APIv4-based autocomplete widget
authorColeman Watts <coleman@civicrm.org>
Sat, 30 Jul 2022 22:04:57 +0000 (18:04 -0400)
committerColeman Watts <coleman@civicrm.org>
Wed, 10 Aug 2022 02:28:44 +0000 (22:28 -0400)
CRM/Api4/Page/AJAX.php
Civi/Api4/Generic/AutocompleteAction.php
js/Common.js

index 0aa40e94d9cdea315bd901f0dd25d5be63ce5b68..638d547624f07cb43f011bf05e6ffa6f68b841ed 100644 (file)
@@ -40,7 +40,8 @@ class CRM_Api4_Page_AJAX extends CRM_Core_Page {
       CRM_Utils_System::civiExit();
     }
     if ($_SERVER['REQUEST_METHOD'] == 'GET' &&
-      strtolower(substr($this->urlPath[4], 0, 3)) != 'get') {
+      ($this->urlPath[4] !== 'autocomplete' && strtolower(substr($this->urlPath[4], 0, 3)) !== 'get')
+    ) {
       $response = [
         'error_code' => 400,
         'error_message' => "SECURITY: All requests that modify the database must be http POST, not GET.",
index 339245f1845cb835d64210ddefd7a56ec408e192..4ebbf7c7bdddb265ad6fe4549c9874152cf558a5 100644 (file)
@@ -67,7 +67,7 @@ class AutocompleteAction extends AbstractAction {
     $labelField = CoreUtil::getInfoItem($entityName, 'label_field');
     $map = [
       'id' => $idField,
-      'text' => $labelField,
+      'label' => $labelField,
     ];
     // FIXME: Use metadata
     if (isset($fields['description'])) {
index 07eb96b84ad1b56746ef52260818c29eadaddff7..1c8d621b3f37cd3cc73a129f9d7e5ae1f843de58 100644 (file)
@@ -523,6 +523,47 @@ if (!CRM.vars) CRM.vars = {};
     });
   };
 
+  // Autocomplete based on APIv4 and Select2.
+  $.fn.crmAutocomplete = function(entityName, apiParams, select2Options) {
+    select2Options = select2Options || {};
+    return $(this).each(function() {
+      $(this).crmSelect2({
+        ajax: {
+          quietMillis: 250,
+          url: CRM.url('civicrm/ajax/api4/' + entityName + '/autocomplete'),
+          data: function (input, pageNum) {
+            return {params: JSON.stringify(_.assign({
+              input: input,
+              page: pageNum || 1
+            }, apiParams))};
+          },
+          results: function(data) {
+            return {
+              results: data.values,
+              more: data.count > data.countFetched
+            };
+          },
+        },
+        minimumInputLength: 1,
+        formatResult: CRM.utils.formatSelect2Result,
+        formatSelection: formatEntityRefSelection,
+        escapeMarkup: _.identity,
+        initSelection: function($el, callback) {
+          var
+            multiple = !!select2Options.multiple,
+            val = $el.val();
+          if (val === '') {
+            return;
+          }
+          var params = $.extend({}, apiParams || {}, {ids: val.split(',')});
+          CRM.api4(entityName, 'autocomplete', params).then(function(result) {
+            callback(multiple ? result : result[0]);
+          });
+        }
+      });
+    });
+  };
+
   /**
    * @see CRM_Core_Form::addEntityRef for docs
    * @param options object