dev/core#2149 Ensure that if a chained select field is required and there are no...
authorSeamus Lee <seamuslee001@gmail.com>
Thu, 29 Oct 2020 23:08:35 +0000 (10:08 +1100)
committerSeamus Lee <seamuslee001@gmail.com>
Thu, 29 Oct 2020 23:08:35 +0000 (10:08 +1100)
CRM/Core/Form.php
js/Common.js

index 0fa07c8fe4c69871fff5af290f6a30c5813081bf..28417580e3507f686f23f685551c5c31e9c4a246 100644 (file)
@@ -2434,6 +2434,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @return HTML_QuickForm_Element
    */
   public function addChainSelect($elementName, $settings = []) {
+    $required = $settings['required'] ?? FALSE;
     $label = strpos($elementName, 'rovince') ? CRM_Core_DAO_StateProvince::getEntityTitle() : CRM_Core_DAO_County::getEntityTitle();
     $props = $settings += [
       'control_field' => str_replace(['state_province', 'StateProvince', 'county', 'County'], [
@@ -2447,11 +2448,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
       'data-empty-prompt' => strpos($elementName, 'rovince') ? ts('Choose country first') : ts('Choose state first'),
       'data-none-prompt' => ts('- N/A -'),
       'multiple' => FALSE,
-      'required' => FALSE,
+      'required' => $required,
       'placeholder' => ts('- select %1 -', [1 => $label]),
     ];
     CRM_Utils_Array::remove($props, 'label', 'required', 'control_field', 'context');
-    $props['class'] = (empty($props['class']) ? '' : "{$props['class']} ") . 'crm-select2';
+    $props['class'] = (empty($props['class']) ? '' : "{$props['class']} ") . 'crm-select2' . ($required ? ' required crm-field-required' : '');
     $props['data-select-prompt'] = $props['placeholder'];
     $props['data-name'] = $elementName;
 
@@ -2461,7 +2462,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     // CRM-15225 - normally QF will reject any selected values that are not part of the field's options, but due to a
     // quirk in our patched version of HTML_QuickForm_select, this doesn't happen if the options are NULL
     // which seems a bit dirty but it allows our dynamically-popuplated select element to function as expected.
-    return $this->add('select', $elementName, $settings['label'], NULL, $settings['required'], $props);
+    return $this->add('select', $elementName, $settings['label'], NULL, $required, $props);
   }
 
   /**
index 8a1ee54a31b0949a4e616d1d4a58ed526c447bbb..3a4ddbdf989c318c050970a28b61a26e6709b630 100644 (file)
@@ -249,6 +249,11 @@ if (!CRM.vars) CRM.vars = {};
         opts = placeholder || placeholder === '' ? '' : '[value!=""]';
       $elect.find('option' + opts).remove();
       var newOptions = CRM.utils.renderOptions(options, val);
+      if (options.length == 0) {
+        $elect.removeClass('required');
+      } else if ($elect.hasClass('crm-field-required') && !$elect.hasClass('required')) {
+        $elect.addClass('required');
+      }
       if (typeof placeholder === 'string') {
         if ($elect.is('[multiple]')) {
           select.attr('placeholder', placeholder);