diff --git a/docroot/core/config/schema/core.data_types.schema.yml b/docroot/core/config/schema/core.data_types.schema.yml | |
index 73db361..c6e4f8c 100644 | |
--- a/docroot/core/config/schema/core.data_types.schema.yml | |
+++ b/docroot/core/config/schema/core.data_types.schema.yml | |
@@ -392,6 +392,9 @@ field_config_base: | |
required: | |
type: boolean | |
label: 'Required field' | |
+ orderable: | |
+ type: boolean | |
+ label: 'Orderable' | |
translatable: | |
type: boolean | |
label: 'Translatable' | |
diff --git a/docroot/core/includes/theme.inc b/docroot/core/includes/theme.inc | |
index 9b89250..6ddbba1 100644 | |
--- a/docroot/core/includes/theme.inc | |
+++ b/docroot/core/includes/theme.inc | |
@@ -1682,6 +1682,66 @@ function template_preprocess_field_multiple_value_form(&$variables) { | |
} | |
/** | |
+ * Prepares variables for individual form element templates. | |
+ * | |
+ * Default template: field-multiple-value-without-order-form.html.twig. | |
+ * | |
+ * Combines multiple values. | |
+ * | |
+ * @param array $variables | |
+ * An associative array containing: | |
+ * - element: A render element representing the form element. | |
+ */ | |
+function template_preprocess_field_multiple_value_without_order_form(&$variables) { | |
+ $element = $variables['element']; | |
+ $variables['multiple'] = $element['#cardinality_multiple']; | |
+ | |
+ if ($variables['multiple']) { | |
+ $items = []; | |
+ $variables['button'] = []; | |
+ foreach (Element::children($element) as $key) { | |
+ if ($key === 'add_more') { | |
+ $variables['button'] = &$element[$key]; | |
+ } | |
+ else { | |
+ $items[$key] = &$element[$key]; | |
+ if (isset($items[$key]['_weight'])) { | |
+ $items[$key]['_weight']['#access'] = FALSE; | |
+ } | |
+ } | |
+ } | |
+ usort($items, '_field_multiple_value_form_sort_helper'); | |
+ | |
+ $variables['title'] = []; | |
+ if (!empty($element['#title'])) { | |
+ $variables['title'] = [ | |
+ '#type' => 'label', | |
+ '#title' => $element['#title'], | |
+ '#required' => !empty($element['#required']) ? $element['#required'] : FALSE, | |
+ '#title_display' => 'before', | |
+ ]; | |
+ } | |
+ $variables['items'] = $items; | |
+ | |
+ if (!empty($element['#description'])) { | |
+ $description_id = $element['#attributes']['aria-describedby']; | |
+ $description_attributes['id'] = $description_id; | |
+ $variables['description']['attributes'] = new Attribute($description_attributes); | |
+ $variables['description']['content'] = $element['#description']; | |
+ | |
+ // Add the description's id to the table aria attributes. | |
+ $variables['table']['#attributes']['aria-describedby'] = $element['#attributes']['aria-describedby']; | |
+ } | |
+ } | |
+ else { | |
+ $variables['elements'] = []; | |
+ foreach (Element::children($element) as $key) { | |
+ $variables['elements'][] = $element[$key]; | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
* Prepares variables for breadcrumb templates. | |
* | |
* Default template: breadcrumb.html.twig. | |
@@ -1861,5 +1921,8 @@ function drupal_common_theme() { | |
'field_multiple_value_form' => array( | |
'render element' => 'element', | |
), | |
+ 'field_multiple_value_without_order_form' => array( | |
+ 'render element' => 'element', | |
+ ), | |
); | |
} | |
diff --git a/docroot/core/lib/Drupal/Core/Field/BaseFieldDefinition.php b/docroot/core/lib/Drupal/Core/Field/BaseFieldDefinition.php | |
index 594f31d..aadaefe 100644 | |
--- a/docroot/core/lib/Drupal/Core/Field/BaseFieldDefinition.php | |
+++ b/docroot/core/lib/Drupal/Core/Field/BaseFieldDefinition.php | |
@@ -233,6 +233,27 @@ public function setTranslatable($translatable) { | |
/** | |
* {@inheritdoc} | |
*/ | |
+ public function isOrderable() { | |
+ return !empty($this->definition['orderable']); | |
+ } | |
+ | |
+ /** | |
+ * Sets whether the field is orderable. | |
+ * | |
+ * @param bool $orderable | |
+ * Whether the field is orderable. | |
+ * | |
+ * @return $this | |
+ * The object itself for chaining. | |
+ */ | |
+ public function setOrderable($orderable) { | |
+ $this->definition['orderable'] = $orderable; | |
+ return $this; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
public function isRevisionable() { | |
return !empty($this->definition['revisionable']); | |
} | |
diff --git a/docroot/core/lib/Drupal/Core/Field/FieldConfigBase.php b/docroot/core/lib/Drupal/Core/Field/FieldConfigBase.php | |
index d7ddd18..5f80f9b 100644 | |
--- a/docroot/core/lib/Drupal/Core/Field/FieldConfigBase.php | |
+++ b/docroot/core/lib/Drupal/Core/Field/FieldConfigBase.php | |
@@ -103,6 +103,15 @@ | |
protected $required = FALSE; | |
/** | |
+ * Flag indicating whether the field is orderable. | |
+ * | |
+ * Defaults to TRUE. | |
+ * | |
+ * @var bool | |
+ */ | |
+ protected $orderable = TRUE; | |
+ | |
+ /** | |
* Flag indicating whether the field is translatable. | |
* | |
* Defaults to TRUE. | |
@@ -332,6 +341,23 @@ public function setTranslatable($translatable) { | |
/** | |
* {@inheritdoc} | |
*/ | |
+ public function isOrderable() { | |
+ // Make the default state TRUE even when the cardinality doesn't allow | |
+ // multiple values. | |
+ return $this->orderable || $this->getFieldStorageDefinition()->getCardinality() == 1; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function setOrderable($orderable) { | |
+ $this->orderable = $orderable; | |
+ return $this; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
public function getSettings() { | |
return $this->settings + $this->getFieldStorageDefinition()->getSettings(); | |
} | |
diff --git a/docroot/core/lib/Drupal/Core/Field/FieldConfigInterface.php b/docroot/core/lib/Drupal/Core/Field/FieldConfigInterface.php | |
index d8b055a..e9dc4ce 100644 | |
--- a/docroot/core/lib/Drupal/Core/Field/FieldConfigInterface.php | |
+++ b/docroot/core/lib/Drupal/Core/Field/FieldConfigInterface.php | |
@@ -50,6 +50,16 @@ public function setDescription($description); | |
public function setTranslatable($translatable); | |
/** | |
+ * Sets whether the field is orderable. | |
+ * | |
+ * @param bool $orderable | |
+ * Whether the field is orderable. | |
+ * | |
+ * @return $this | |
+ */ | |
+ public function setOrderable($orderable); | |
+ | |
+ /** | |
* Sets field settings. | |
* | |
* Note that the method does not unset existing settings not specified in the | |
diff --git a/docroot/core/lib/Drupal/Core/Field/WidgetBase.php b/docroot/core/lib/Drupal/Core/Field/WidgetBase.php | |
index 3d0db4c..b7ca726 100644 | |
--- a/docroot/core/lib/Drupal/Core/Field/WidgetBase.php | |
+++ b/docroot/core/lib/Drupal/Core/Field/WidgetBase.php | |
@@ -210,7 +210,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f | |
if ($elements) { | |
$elements += array( | |
- '#theme' => 'field_multiple_value_form', | |
+ '#theme' => $this->fieldDefinition->isOrderable() ? 'field_multiple_value_form' : 'field_multiple_value_without_order_form', | |
'#field_name' => $field_name, | |
'#cardinality' => $cardinality, | |
'#cardinality_multiple' => $this->fieldDefinition->getFieldStorageDefinition()->isMultiple(), | |
diff --git a/docroot/core/modules/block_content/config/install/field.storage.block_content.body.yml b/docroot/core/modules/block_content/config/install/field.storage.block_content.body.yml | |
index f7c504d..2a73f84 100644 | |
--- a/docroot/core/modules/block_content/config/install/field.storage.block_content.body.yml | |
+++ b/docroot/core/modules/block_content/config/install/field.storage.block_content.body.yml | |
@@ -12,6 +12,7 @@ settings: { } | |
module: text | |
locked: false | |
cardinality: 1 | |
+orderable: true | |
translatable: true | |
indexes: { } | |
persist_with_no_fields: true | |
diff --git a/docroot/core/modules/field_ui/src/Form/FieldConfigEditForm.php b/docroot/core/modules/field_ui/src/Form/FieldConfigEditForm.php | |
index ff6d157..1e817c9 100644 | |
--- a/docroot/core/modules/field_ui/src/Form/FieldConfigEditForm.php | |
+++ b/docroot/core/modules/field_ui/src/Form/FieldConfigEditForm.php | |
@@ -71,6 +71,16 @@ public function form(array $form, FormStateInterface $form_state) { | |
'#weight' => -5, | |
); | |
+ if ($this->entity->getFieldStorageDefinition()->getCardinality() != 1) { | |
+ $form['orderable'] = [ | |
+ '#type' => 'checkbox', | |
+ '#title' => $this->t('Orderable'), | |
+ '#default_value' => $this->entity->isOrderable(), | |
+ '#weight' => -5, | |
+ '#description' => t('Orderable multiple fields widgets are in a table with drag and drop.'), | |
+ ]; | |
+ } | |
+ | |
// Create an arbitrary entity object (used by the 'default value' widget). | |
$ids = (object) array( | |
'entity_type' => $this->entity->getTargetEntityTypeId(), |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment