Add custom field type Hidden
authorcolemanw <coleman@civicrm.org>
Thu, 31 Aug 2023 23:44:41 +0000 (19:44 -0400)
committercolemanw <coleman@civicrm.org>
Sat, 14 Oct 2023 18:10:55 +0000 (14:10 -0400)
CRM/Core/BAO/CustomField.php
CRM/Core/SelectValues.php
CRM/Custom/Form/Field.php
CRM/Custom/Page/Field.php
Civi/Api4/Generic/BasicGetFieldsAction.php
ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js
ext/afform/admin/ang/afGuiEditor/inputType/Hidden.html [new file with mode: 0644]
ext/afform/core/ang/af/fields/Hidden.html [new file with mode: 0644]
templates/CRM/Custom/Form/Edit/CustomField.tpl
templates/CRM/Custom/Form/Field.tpl
tests/phpunit/api/v4/Custom/CustomFieldGetFieldsTest.php

index 619dbdb042af079e4b7ba49ceb6071671c24a1c0..6472813b53abc99b48e72fd1209a88bbc6d18a1c 100644 (file)
@@ -1132,6 +1132,10 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
 
         $qf->assign('customUrls', $customUrls);
         break;
+
+      case 'Hidden':
+        $element = $qf->add('hidden', $elementName);
+        break;
     }
 
     switch ($field->data_type) {
@@ -2221,7 +2225,7 @@ WHERE  id IN ( %1, %2 )
 
     // create any option group & values if required
     $allowedOptionTypes = ['String', 'Int', 'Float', 'Money'];
-    if ($htmlType !== 'Text' && in_array($dataType, $allowedOptionTypes, TRUE)) {
+    if (!in_array($htmlType, ['Text', 'Hidden'], TRUE) && in_array($dataType, $allowedOptionTypes, TRUE)) {
       //CRM-16659: if option_value then create an option group for this custom field.
       // An option_type of 2 would be a 'message' from the form layer not to handle
       // the option_values key. If not set then it is not ignored.
index 452e4b2556d9892ee7bbe402e69745db632f1723..1eadb3f5beabd0d40b1f5e1b03feb23dfbf5c866 100644 (file)
@@ -219,6 +219,11 @@ class CRM_Core_SelectValues {
         'name' => 'Link',
         'label' => ts('Link'),
       ],
+      [
+        'id' => 'Hidden',
+        'name' => 'Hidden',
+        'label' => ts('Hidden'),
+      ],
     ];
   }
 
index 9a8c2e3d7362462057d5f10a26084748fcf30705..ece46e55555683276992960ba37094c716bdea6c 100644 (file)
@@ -58,10 +58,10 @@ class CRM_Custom_Form_Field extends CRM_Core_Form {
    * @var array[]
    */
   public static $_dataToHTML = [
-    'String' => ['Text', 'Select', 'Radio', 'CheckBox', 'Autocomplete-Select'],
-    'Int' => ['Text', 'Select', 'Radio'],
-    'Float' => ['Text', 'Select', 'Radio'],
-    'Money' => ['Text', 'Select', 'Radio'],
+    'String' => ['Text', 'Select', 'Radio', 'CheckBox', 'Autocomplete-Select', 'Hidden'],
+    'Int' => ['Text', 'Select', 'Radio', 'Hidden'],
+    'Float' => ['Text', 'Select', 'Radio', 'Hidden'],
+    'Money' => ['Text', 'Select', 'Radio', 'Hidden'],
     'Memo' => ['TextArea', 'RichTextEditor'],
     'Date' => ['Select Date'],
     'Boolean' => ['Radio'],
index 8d6b6aefb6531d5fbf5629bddea47392def8ae71..188e48ed4d146653d9b78a722391b764abb9d5ca 100644 (file)
@@ -133,27 +133,9 @@ class CRM_Custom_Page_Field extends CRM_Core_Page {
         $action -= CRM_Core_Action::DISABLE;
       }
 
-      switch ($customFieldBAO->data_type) {
-        case "String":
-        case "Int":
-        case "Float":
-        case "Money":
-          // if Multi Select field is selected in custom field
-          if ($customFieldBAO->html_type == 'Text') {
-            $action -= CRM_Core_Action::BROWSE;
-          }
-          break;
-
-        case "ContactReference":
-        case "Memo":
-        case "Date":
-        case "Boolean":
-        case "StateProvince":
-        case "Country":
-        case "File":
-        case "Link":
-          $action -= CRM_Core_Action::BROWSE;
-          break;
+      // Remove link to edit option group if there isn't one
+      if (!$customFieldBAO->option_group_id) {
+        $action -= CRM_Core_Action::BROWSE;
       }
 
       $customFieldDataType = array_column(CRM_Core_BAO_CustomField::dataType(), 'label', 'id');
index 2dc62f8cb082d0d7bb478b537872dc27ffcfd425..07ba072000fb13ce67b624b3e79b56bb55178db1 100644 (file)
@@ -325,6 +325,7 @@ class BasicGetFieldsAction extends BasicGetAction {
           'Email' => ts('Email'),
           'EntityRef' => ts('Autocomplete Entity'),
           'File' => ts('File'),
+          'Hidden' => ts('Hidden'),
           'Location' => ts('Address Location'),
           'Number' => ts('Number'),
           'Radio' => ts('Radio Buttons'),
index 8772532e281a59f917395ef27528d029e4faaea0..1b9f03495dbe31eedbf325a9613e52228bd6e18d 100644 (file)
             return !(defn.options || defn.data_type === 'Boolean');
 
           case 'DisplayOnly':
+          case 'Hidden':
             return true;
 
           default:
diff --git a/ext/afform/admin/ang/afGuiEditor/inputType/Hidden.html b/ext/afform/admin/ang/afGuiEditor/inputType/Hidden.html
new file mode 100644 (file)
index 0000000..c19e65a
--- /dev/null
@@ -0,0 +1 @@
+<div class="form-inline"></div>
diff --git a/ext/afform/core/ang/af/fields/Hidden.html b/ext/afform/core/ang/af/fields/Hidden.html
new file mode 100644 (file)
index 0000000..3a27423
--- /dev/null
@@ -0,0 +1 @@
+<input type="hidden" id="{{:: fieldId }}" ng-model="getSetValue" ng-model-options="{getterSetter: true}" >
index 24f0e5b7f44f379e92892915e3fe7aa60c42802a..34dd650732ff5ee92d1f923e35664f70dc89fc77 100644 (file)
     <td class="html-adjust description">{$element.help_pre}</td>
   </tr>
 {/if}
-{if $element.options_per_line}
+{if $element.html_type === 'Hidden'}
+  {* Hidden field - render in hidden row *}
+  <tr class="custom_field-row {$element.element_name}-row hiddenElement">
+    <td>{$formElement.html}</td>
+  </tr>
+{elseif $element.options_per_line}
   <tr class="custom_field-row {$element.element_name}-row">
     <td class="label">{$formElement.label}{if $element.help_post}{help id=$element.id file="CRM/Custom/Form/CustomField.hlp" title=$element.label}{/if}</td>
     <td class="html-adjust">
index 4792fdc39fbfacd58eea2e10f03308504e385007..e4476c6442009a33e34ec3adedf960ff2747b6a1 100644 (file)
       }
 
       if (_.includes(['String', 'Int', 'Float', 'Money'], dataType)) {
-        if (htmlType !== "Text") {
+        if (!['Text', 'Hidden'].includes(htmlType)) {
           $("#showoption, #searchable", $form).show();
           $("#hideDefault, #hideDesc, #searchByRange", $form).hide();
         } else {
         $("#showoption").hide();
       }
 
-      if (_.includes(['String', 'Int', 'Float', 'Money'], dataType) && htmlType !== 'Text') {
+      if (_.includes(['String', 'Int', 'Float', 'Money'], dataType) && !['Text', 'Hidden'].includes(htmlType)) {
         if (serialize) {
           $('div[id^=checkbox]', '#optionField').show();
           $('div[id^=radio]', '#optionField').hide();
index 4a8c8a938ba81681a101690bc52ae1e152f0734c..a9549477bb38f3c2c7834f8fff6f70d351861e2c 100644 (file)
@@ -52,7 +52,7 @@ class CustomFieldGetFieldsTest extends CustomTestBase {
       ->execute();
   }
 
-  public function testDisabledFields(): void {
+  public function testDisabledAndHiddenFields(): void {
     // Create a custom group with one enabled and one disabled field
     CustomGroup::create(FALSE)
       ->addValue('extends', 'Activity')
@@ -62,14 +62,20 @@ class CustomFieldGetFieldsTest extends CustomTestBase {
       'records' => [
         ['label' => 'enabled_field'],
         ['label' => 'disabled_field', 'is_active' => FALSE],
+        ['label' => 'hidden_field', 'html_type' => 'Hidden'],
       ],
       'defaults' => ['custom_group_id.name' => 'act_test_grp'],
     ]);
 
-    // Only the enabled field shows up
-    $getFields = Activity::getFields(FALSE)->execute()->column('name');
-    $this->assertContains('act_test_grp.enabled_field', $getFields);
-    $this->assertNotContains('act_test_grp.disabled_field', $getFields);
+    // Only the enabled fields show up
+    $getFields = Activity::getFields(FALSE)->execute()->indexBy('name');
+    $this->assertArrayHasKey('act_test_grp.enabled_field', $getFields);
+    $this->assertArrayHasKey('act_test_grp.hidden_field', $getFields);
+    $this->assertArrayNotHasKey('act_test_grp.disabled_field', $getFields);
+
+    // Hidden field does not have option lists
+    $this->assertFalse($getFields['act_test_grp.hidden_field']['options']);
+    $this->assertNull($getFields['act_test_grp.hidden_field']['suffixes']);
 
     // Disable the entire custom group
     CustomGroup::update(FALSE)