From af897ce28608f52db2cccd336255c891ab08f9bc Mon Sep 17 00:00:00 2001 From: Christian Fritsch Date: Fri, 2 Oct 2020 09:24:46 +0200 Subject: [PATCH] Issue #3089842 by xavier.masson: Drag to re-order doesn't work without autocomplete --- js/select2.js | 2 +- src/Element/Select2.php | 23 ++++----- .../ViewsWithAutoCreation.php | 50 +++++++++++++++++++ .../Select2EntityReferenceWidget.php | 2 +- 4 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 src/Plugin/EntityReferenceSelection/ViewsWithAutoCreation.php diff --git a/js/select2.js b/js/select2.js index dde69b11..5e90ac7e 100644 --- a/js/select2.js +++ b/js/select2.js @@ -43,7 +43,7 @@ $(this).select2(config); // Copied from https://github.com/woocommerce/woocommerce/blob/master/assets/js/admin/wc-enhanced-select.js#L118 - if (Object.prototype.hasOwnProperty.call(config, 'ajax') && config.multiple) { + if (config.multiple) { var $select = $(this); var $list = $select.next('.select2-container').find('ul.select2-selection__rendered'); Sortable.create($list[0], { diff --git a/src/Element/Select2.php b/src/Element/Select2.php index 012b5446..025aff57 100644 --- a/src/Element/Select2.php +++ b/src/Element/Select2.php @@ -203,6 +203,17 @@ public static function processSelect(&$element, FormStateInterface $form_state, $element['#options'] = $empty_option + $element['#options']; } + if ($element['#multiple']) { + $values = isset($element['#value']) ? $element['#value'] : $element['#default_value']; + $values = is_array($values) ? $values : [$values]; + + // Apply field values order on the options. + if (!empty($values)) { + $flipped_keys = array_intersect_key(array_flip($values), $element['#options']); + $element['#options'] = array_replace($flipped_keys, $element['#options']); + } + } + // Set the type from select2 to select to get proper form validation. $element['#type'] = 'select'; @@ -305,18 +316,6 @@ public static function preRenderAutocomplete($element) { } $element = call_user_func_array($value_callable, [&$element]); - // Reduce options to the preselected ones and bring them in the correct - // order. - $options = OptGroup::flattenOptions($element['#options']); - $values = isset($element['#value']) ? $element['#value'] : $element['#default_value']; - $values = is_array($values) ? $values : [$values]; - $element['#options'] = []; - foreach ($values as $value) { - if (isset($options[$value])) { - $element['#options'][$value] = $options[$value]; - } - } - /** @var \Drupal\Core\Access\AccessManagerInterface $access_manager */ $access_manager = \Drupal::service('access_manager'); $access = $access_manager->checkNamedRoute($element['#autocomplete_route_name'], $element['#autocomplete_route_parameters'], \Drupal::currentUser(), TRUE); diff --git a/src/Plugin/EntityReferenceSelection/ViewsWithAutoCreation.php b/src/Plugin/EntityReferenceSelection/ViewsWithAutoCreation.php new file mode 100644 index 00000000..84d2fe18 --- /dev/null +++ b/src/Plugin/EntityReferenceSelection/ViewsWithAutoCreation.php @@ -0,0 +1,50 @@ +entityTypeManager->getDefinition($entity_type_id); + $bundle_key = $entity_type->getKey('bundle'); + $label_key = $entity_type->getKey('label'); + $entity = $this->entityTypeManager->getStorage($entity_type_id)->create([ + $bundle_key => $bundle, + $label_key => $label, + ]); + if ($entity instanceof EntityOwnerInterface) { + $entity->setOwnerId($uid); + } + return $entity; + } + + /** + * {@inheritdoc} + */ + public function validateReferenceableNewEntities(array $entities) { + return array_filter($entities, function ($entity) { + if (isset($this->configuration['handler_settings']['auto_create_bundle'])) { + return ($entity->bundle() === $this->configuration['handler_settings']['auto_create_bundle']); + } + return TRUE; + }); + } + +} diff --git a/src/Plugin/Field/FieldWidget/Select2EntityReferenceWidget.php b/src/Plugin/Field/FieldWidget/Select2EntityReferenceWidget.php index b3f798e5..7763b5c7 100644 --- a/src/Plugin/Field/FieldWidget/Select2EntityReferenceWidget.php +++ b/src/Plugin/Field/FieldWidget/Select2EntityReferenceWidget.php @@ -170,7 +170,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen // with 'autocreate' or 'autocomplete' we want to ignore that. $element['#multiple'] = $this->multiple && (count($this->options) > 1 || isset($element['#autocreate']) || $element['#autocomplete']); - if ($element['#autocomplete'] && $element['#multiple']) { + if ($element['#multiple']) { $entity_definition = $this->entityTypeManager->getDefinition($element['#target_type']); $message = $this->t("Drag to re-order @entity_types.", ['@entity_types' => $entity_definition->getPluralLabel()]); if (!empty($element['#description'])) {