Skip to content

Commit

Permalink
wc-3423739/3423740 - fix re-ordering options in CiviCRM Options contr…
Browse files Browse the repository at this point in the history
…ol (#953)

* wc-3423739/3423740 - fix ordering of civicrm options control

* Fake commit to trigger test run

* Add/remove whitespace per coding standards.

---------

Co-authored-by: Bob Silvern <[email protected]>
Co-authored-by: Jitendra Purohit <[email protected]>
  • Loading branch information
3 people authored May 9, 2024
1 parent 79fea2f commit f02bd9c
Showing 1 changed file with 31 additions and 18 deletions.
49 changes: 31 additions & 18 deletions src/Element/CivicrmSelectOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,32 +109,34 @@ public static function processSelectOptions(&$element, FormStateInterface $form_
$element['options']['#empty'] = t('Options are loaded dynamically on the webform based on the value selected in @key field.', ['@key' => $parent_label]);
}

$current_options = $element['#default_value'];
$weight = 0;
$webform = $form_state->getFormObject()->getWebform();
$data = $webform->getHandler('webform_civicrm')->getConfiguration()['settings']['data'] ?? [];
$field_options = static::getFieldOptions($element['#form_key'], $data);

// Sort the field options by the current options.
// $current_options is an array of [value => webform_label] listed in the order defined in the webform.
// Options disabled in the webform are absent from this array.
$current_options = $element['#default_value'];

if (!$element['#civicrm_live_options']) {
uasort($field_options, function ($a, $b) use ($current_options) {
$current_options = array_flip($current_options);
$weight_values = array_flip(array_values(array_flip($current_options)));
// $all_options is an array of [value => civi_label] listed in the order defined in civicrm.
// Options disabed in civi are absent from this array, but it includes options disabled in the webform.
$all_options = static::getFieldOptions($element['#form_key'], $data);

if (!isset($current_options[$b]) && isset($current_options[$a])) {
return -1;
}
if (!isset($current_options[$a]) && isset($current_options[$b])) {
return 1;
}
// build the $field_options array using the order of $current_options, using the labels specified in the webform.
foreach ($current_options as $key => $option) {
$field_options[$key] = $all_options[$key];
}

$a_weight = $weight_values[$a] ?? 0;
$b_weight = $weight_values[$b] ?? 0;
if ($a_weight == $b_weight) {
return 0;
// Add to the $field_options array any options that are disabled in the webform.
// The order of the disabled options cannot be changed, and they will always
// appear below the enabled options.
foreach ($all_options as $key => $option) {
if (!isset($field_options[$key])) {
$field_options[$key] = $all_options[$key];
}
return ($a_weight < $b_weight) ? -1 : 1;
});
}
} else { // static options
$field_options = static::getFieldOptions($element['#form_key'], $data);
}

foreach ($field_options as $key => $option) {
Expand Down Expand Up @@ -183,6 +185,17 @@ public static function processSelectOptions(&$element, FormStateInterface $form_
'#default_value' => $weight,
'#attributes' => ['class' => ['weight']],
'#access' => !$element['#civicrm_live_options'],

// delta theoretically should control the number of items in the weight dropdown for each option, but
// in reality that weight range seems to be fixed at -10 to +10. When there are more than 10 options present,
// the weight dropdown therefore cannot be used to move an option below the 10th spot. In addition,
// a bug related to this fixed -10 to +10 range prevents dragging options below the 22nd spot.
// Therefore, when there are more than 10 options present, it's desireable to switch from a weight
// listbox to an integer edit box. This is accomplished by setting
// delta to a value greater than Drupal::config('system.site')->get('weight_select_max') (default value 100)
// See Drupal\Core\Render\Element\Weight::processWeight()
// Other than that threshold, the value specified here for delta is not significent.
'#delta' => !$element['#civicrm_live_options'] && sizeof($all_options) > 10 ? '101' : "10",
];
$weight++;
}
Expand Down

0 comments on commit f02bd9c

Please sign in to comment.