summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLauri Eskola <lauri.eskola@acquia.com>2023-04-20 19:09:36 +0300
committerLauri Eskola <lauri.eskola@acquia.com>2023-04-20 19:10:52 +0300
commit1996c9d44d336255c9788ed26b7f8cf24656601c (patch)
tree9fe5b857ec048f86d32435358f844e93c54687ff
parentd7bd8ac42006fb5eb4c68acf5b99cc2a6a79d496 (diff)
downloaddrupal-1996c9d44d336255c9788ed26b7f8cf24656601c.tar.gz
drupal-1996c9d44d336255c9788ed26b7f8cf24656601c.zip
Issue #857312 by bnjmnm, tim.plunkett, yched, swentel, nod_, nick_schuch, smustgrave: Add a "changes not applied until saved" warning when changing widget/formatter settings
-rw-r--r--core/core.libraries.yml8
-rw-r--r--core/lib/Drupal/Core/Ajax/TabledragWarningCommand.php53
-rw-r--r--core/misc/tabledrag-ajax.js36
-rw-r--r--core/misc/tabledrag.js50
-rw-r--r--core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5AllowedTagsTest.php1
-rw-r--r--core/modules/field_ui/field_ui.js60
-rw-r--r--core/modules/field_ui/src/Form/EntityDisplayFormBase.php22
-rw-r--r--core/modules/field_ui/tests/src/Functional/EntityDisplayFormBaseTest.php73
-rw-r--r--core/modules/field_ui/tests/src/FunctionalJavascript/ManageDisplayTest.php81
-rw-r--r--core/phpstan-baseline.neon2
-rw-r--r--core/themes/claro/js/tabledrag.js1
11 files changed, 360 insertions, 27 deletions
diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 01909a756e3..06579085cf9 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -678,6 +678,14 @@ drupal.tabledrag:
- core/once
- core/drupal.touchevents-test
+drupal.tabledrag.ajax:
+ version: VERSION
+ js:
+ misc/tabledrag-ajax.js: { }
+ dependencies:
+ - core/ajax
+ - core/tabledrag
+
drupal.tableheader:
version: VERSION
js:
diff --git a/core/lib/Drupal/Core/Ajax/TabledragWarningCommand.php b/core/lib/Drupal/Core/Ajax/TabledragWarningCommand.php
new file mode 100644
index 00000000000..e1cc60892e3
--- /dev/null
+++ b/core/lib/Drupal/Core/Ajax/TabledragWarningCommand.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\Core\Ajax;
+
+use Drupal\Core\Asset\AttachedAssets;
+
+/**
+ * AJAX command for conveying changed tabledrag rows.
+ *
+ * This command is provided an id of a table row then does the following:
+ * - Marks the row as changed.
+ * - If a message generated by the tableDragChangedWarning is not present above
+ * the table the row belongs to, that message is added there.
+ *
+ * @see Drupal.AjaxCommands.prototype.tabledragChanged
+ *
+ * @ingroup ajax
+ */
+class TabledragWarningCommand implements CommandInterface, CommandWithAttachedAssetsInterface {
+
+ /**
+ * Constructs a TableDragWarningCommand object.
+ *
+ * @param string $id
+ * The id of the changed row.
+ * @param string $tabledrag_instance
+ * The identifier of the tabledrag instance.
+ */
+ public function __construct(
+ protected string $id,
+ protected string $tabledrag_instance) {}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ return [
+ 'command' => 'tabledragChanged',
+ 'id' => $this->id,
+ 'tabledrag_instance' => $this->tabledrag_instance,
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAttachedAssets() {
+ $assets = new AttachedAssets();
+ $assets->setLibraries(['core/drupal.tabledrag.ajax']);
+ return $assets;
+ }
+
+}
diff --git a/core/misc/tabledrag-ajax.js b/core/misc/tabledrag-ajax.js
new file mode 100644
index 00000000000..11df818dd88
--- /dev/null
+++ b/core/misc/tabledrag-ajax.js
@@ -0,0 +1,36 @@
+/**
+ * Ajax command for highlighting elements.
+ *
+ * @param {Drupal.Ajax} [ajax]
+ * An Ajax object.
+ * @param {object} response
+ * The Ajax response.
+ * @param {string} response.id
+ * The row id.
+ * @param {string} response.tabledrag_instance
+ * The tabledrag instance identifier.
+ * @param {number} [status]
+ * The HTTP status code.
+ */
+Drupal.AjaxCommands.prototype.tabledragChanged = function (
+ ajax,
+ response,
+ status,
+) {
+ if (status !== 'success') {
+ return;
+ }
+
+ const tableDrag = Drupal.tableDrag[response.tabledrag_instance];
+
+ // eslint-disable-next-line new-cap
+ const rowObject = new tableDrag.row(
+ document.getElementById(response.id),
+ '',
+ tableDrag.indentEnabled,
+ tableDrag.maxDepth,
+ true,
+ );
+ rowObject.markChanged();
+ rowObject.addChangedWarning();
+};
diff --git a/core/misc/tabledrag.js b/core/misc/tabledrag.js
index ea05dc8215e..bd25008347f 100644
--- a/core/misc/tabledrag.js
+++ b/core/misc/tabledrag.js
@@ -180,6 +180,14 @@
* @type {boolean}
*/
this.indentEnabled = false;
+
+ /**
+ * Keeps track of rows that have changed.
+ */
+ this.changedRowIds = Drupal.tableDrag[table.id]
+ ? Drupal.tableDrag[table.id].changedRowIds
+ : new Set();
+
Object.keys(tableSettings || {}).forEach((group) => {
Object.keys(tableSettings[group] || {}).forEach((n) => {
if (tableSettings[group][n].relationship === 'parent') {
@@ -269,6 +277,20 @@
}
}, this),
);
+
+ // Check for any rows marked as changed before this tabledrag was rerendered
+ // and mark them as changed for this current render.
+ this.changedRowIds.forEach((changedRowId) => {
+ // eslint-disable-next-line new-cap
+ const rowObject = new self.row(
+ document.getElementById(changedRowId),
+ '',
+ self.indentEnabled,
+ self.maxDepth,
+ true,
+ );
+ rowObject.markChanged();
+ });
};
/**
@@ -842,10 +864,7 @@
self.rowObject.markChanged();
if (self.changed === false) {
- $(Drupal.theme('tableDragChangedWarning'))
- .insertBefore(self.table)
- .hide()
- .fadeIn('slow');
+ self.rowObject.addChangedWarning();
self.changed = true;
}
}
@@ -1335,6 +1354,28 @@
};
/**
+ * Adds a warning above the table informing users they must save changes.
+ */
+ Drupal.tableDrag.prototype.row.prototype.addChangedWarning = function () {
+ // Do not add the changed warning if one is already present.
+ if (!$(this.table.parentNode).find('.tabledrag-changed-warning').length) {
+ const $form = $(this.table).closest('form');
+ $(Drupal.theme('tableDragChangedWarning'))
+ .insertBefore(this.table)
+ .hide()
+ // If a warning has already been shown, do not fade the warning in, so
+ // it appears static when the table is rebuilt.
+ .fadeIn(
+ $form[0].hasAttribute('data-tabledrag-save-warning') ? 0 : 'slow',
+ );
+
+ // Keep track of the warning having been added in an element that lives
+ // outside the table which rebuilds when certain changes occur.
+ $form[0].setAttribute('data-tabledrag-save-warning', true);
+ }
+ };
+
+ /**
* Find all children of rowObject by indentation.
*
* @param {boolean} addClasses
@@ -1619,6 +1660,7 @@
if (cell.find('abbr.tabledrag-changed').length === 0) {
cell.append(marker);
}
+ Drupal.tableDrag[this.table.id].changedRowIds.add(this.element.id);
};
/**
diff --git a/core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5AllowedTagsTest.php b/core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5AllowedTagsTest.php
index a20df5ee56b..60ccc9e85fc 100644
--- a/core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5AllowedTagsTest.php
+++ b/core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5AllowedTagsTest.php
@@ -382,6 +382,7 @@ class CKEditor5AllowedTagsTest extends CKEditor5TestBase {
$this->assertNotNull($assert_session->waitForElementVisible('css', '[data-drupal-selector=edit-filters-media-embed-settings]', 0));
$page->clickLink('Embed media');
+ $assert_session->waitForField('filters[media_embed][settings][allowed_view_modes][view_mode_2]');
$page->checkField('filters[media_embed][settings][allowed_view_modes][view_mode_1]');
$page->checkField('filters[media_embed][settings][allowed_view_modes][view_mode_2]');
$assert_session->assertWaitOnAjaxRequest();
diff --git a/core/modules/field_ui/field_ui.js b/core/modules/field_ui/field_ui.js
index d6e2b5c55e5..a381226dfb1 100644
--- a/core/modules/field_ui/field_ui.js
+++ b/core/modules/field_ui/field_ui.js
@@ -149,8 +149,14 @@
onChange() {
const $trigger = $(this);
const $row = $trigger.closest('tr');
- const rowHandler = $row.data('fieldUIRowHandler');
+ // Do not fire change listeners for items within forms that have their
+ // own AJAX callbacks to process a change.
+ if ($trigger.closest('.ajax-new-content').length !== 0) {
+ return;
+ }
+
+ const rowHandler = $row.data('fieldUIRowHandler');
const refreshRows = {};
refreshRows[rowHandler.name] = $trigger.get(0);
@@ -168,8 +174,27 @@
rowHandler.region = region;
}
- // Ajax-update the rows.
- Drupal.fieldUIOverview.AJAXRefreshRows(refreshRows);
+ // Fields inside `.tabledrag-hide` are typically hidden. They can be
+ // visible when "Show row weights" are enabled. If their value is changed
+ // while visible, the row should be marked as changed, but they should not
+ // be processed via AJAXRefreshRows as they are intended to be fields AJAX
+ // updates the value of.
+ if ($trigger.closest('.tabledrag-hide').length) {
+ const thisTableDrag = Drupal.tableDrag['field-display-overview'];
+ // eslint-disable-next-line new-cap
+ const rowObject = new thisTableDrag.row(
+ $row[0],
+ '',
+ thisTableDrag.indentEnabled,
+ thisTableDrag.maxDepth,
+ true,
+ );
+ rowObject.markChanged();
+ rowObject.addChangedWarning();
+ } else {
+ // Ajax-update the rows.
+ Drupal.fieldUIOverview.AJAXRefreshRows(refreshRows);
+ }
},
/**
@@ -262,7 +287,6 @@
rowNames.push(rowName);
ajaxElements.push(rows[rowName]);
});
-
if (rowNames.length) {
// Add a throbber next each of the ajaxElements.
$(ajaxElements).after(Drupal.theme.ajaxProgressThrobber());
@@ -285,9 +309,11 @@
// jQuery trigger().
$(input).on('mousedown', () => {
returnFocus = {
- drupalSelector: document.activeElement.getAttribute(
+ drupalSelector: document.activeElement.hasAttribute(
'data-drupal-selector',
- ),
+ )
+ ? document.activeElement.getAttribute('data-drupal-selector')
+ : false,
scrollY: window.scrollY,
};
});
@@ -300,14 +326,13 @@
`[data-drupal-selector="${returnFocus.drupalSelector}"]`,
)
.focus();
-
- // Ensure the scroll position is the same as when the input was
- // initially changed.
- window.scrollTo({
- top: returnFocus.scrollY,
- });
- returnFocus = {};
}
+ // Ensure the scroll position is the same as when the input was
+ // initially changed.
+ window.scrollTo({
+ top: returnFocus.scrollY,
+ });
+ returnFocus = {};
});
});
$('input[data-drupal-selector="edit-refresh"]').trigger('mousedown');
@@ -347,14 +372,11 @@
this.region = data.region;
this.tableDrag = data.tableDrag;
this.defaultPlugin = data.defaultPlugin;
-
- // Attach change listener to the 'plugin type' select.
this.$pluginSelect = $(row).find('.field-plugin-type');
- this.$pluginSelect.on('change', Drupal.fieldUIOverview.onChange);
-
- // Attach change listener to the 'region' select.
this.$regionSelect = $(row).find('select.field-region');
- this.$regionSelect.on('change', Drupal.fieldUIOverview.onChange);
+
+ // Attach change listeners to select and input elements in the row.
+ $(row).find('select, input').on('change', Drupal.fieldUIOverview.onChange);
return this;
};
diff --git a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
index 6cc3f6bd058..a92618a728b 100644
--- a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
+++ b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
@@ -4,6 +4,10 @@ namespace Drupal\field_ui\Form;
use Drupal\Component\Plugin\Factory\DefaultFactory;
use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Utility\Html;
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\Core\Ajax\TabledragWarningCommand;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityInterface;
@@ -299,7 +303,7 @@ abstract class EntityDisplayFormBase extends EntityForm {
// Disable fields without any applicable plugins.
if (empty($this->getApplicablePluginOptions($field_definition))) {
- $this->entity->removeComponent($field_name)->save();
+ $this->entity->removeComponent($field_name);
$display_options = $this->entity->getComponent($field_name);
}
@@ -679,6 +683,7 @@ abstract class EntityDisplayFormBase extends EntityForm {
* Ajax handler for multistep buttons.
*/
public function multistepAjax($form, FormStateInterface $form_state) {
+ $response = new AjaxResponse();
$trigger = $form_state->getTriggeringElement();
$op = $trigger['#op'];
@@ -709,8 +714,19 @@ abstract class EntityDisplayFormBase extends EntityForm {
}
}
- // Return the whole table.
- return $form['fields'];
+ // Replace the whole table.
+ $response->addCommand(new ReplaceCommand('#field-display-overview-wrapper', $form['fields']));
+
+ // Add "row updated" warning after the table has been replaced.
+ if (!in_array($op, ['cancel', 'edit'])) {
+ foreach ($updated_rows as $name) {
+ // The ID of the rendered table row is `$name` processed by getClass().
+ // @see \Drupal\field_ui\Element\FieldUiTable::tablePreRender
+ $response->addCommand(new TabledragWarningCommand(Html::getClass($name), 'field-display-overview'));
+ }
+ }
+
+ return $response;
}
/**
diff --git a/core/modules/field_ui/tests/src/Functional/EntityDisplayFormBaseTest.php b/core/modules/field_ui/tests/src/Functional/EntityDisplayFormBaseTest.php
new file mode 100644
index 00000000000..a2fb83175b3
--- /dev/null
+++ b/core/modules/field_ui/tests/src/Functional/EntityDisplayFormBaseTest.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Drupal\Tests\field_ui\Functional;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the UI for configuring entity displays.
+ *
+ * @group field_ui
+ */
+class EntityDisplayFormBaseTest extends BrowserTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = ['field_ui', 'entity_test', 'field_test'];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $defaultTheme = 'stark';
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp(): void {
+ parent::setUp();
+
+ foreach (entity_test_entity_types() as $entity_type) {
+ // Auto-create fields for testing.
+ FieldStorageConfig::create([
+ 'entity_type' => $entity_type,
+ 'field_name' => 'field_test_no_plugin',
+ 'type' => 'field_test',
+ 'cardinality' => 1,
+ ])->save();
+ FieldConfig::create([
+ 'entity_type' => $entity_type,
+ 'field_name' => 'field_test_no_plugin',
+ 'bundle' => $entity_type,
+ 'label' => 'Test field with no plugin',
+ 'translatable' => FALSE,
+ ])->save();
+
+ \Drupal::service('entity_display.repository')
+ ->getFormDisplay($entity_type, $entity_type)
+ ->setComponent('field_test_no_plugin', [])
+ ->save();
+ }
+
+ $this->drupalLogin($this->drupalCreateUser([
+ 'administer entity_test form display',
+ ]));
+ }
+
+ /**
+ * Ensures the entity is not affected when there are no applicable formatters.
+ */
+ public function testNoApplicableFormatters(): void {
+ $storage = $this->container->get('entity_type.manager')->getStorage('entity_form_display');
+ $id = 'entity_test.entity_test.default';
+
+ $entity_before = $storage->load($id);
+ $this->drupalGet('entity_test/structure/entity_test/form-display');
+ $entity_after = $storage->load($id);
+
+ $this->assertSame($entity_before->toArray(), $entity_after->toArray());
+ }
+
+}
diff --git a/core/modules/field_ui/tests/src/FunctionalJavascript/ManageDisplayTest.php b/core/modules/field_ui/tests/src/FunctionalJavascript/ManageDisplayTest.php
index 03ed77eb7a2..fbc61854948 100644
--- a/core/modules/field_ui/tests/src/FunctionalJavascript/ManageDisplayTest.php
+++ b/core/modules/field_ui/tests/src/FunctionalJavascript/ManageDisplayTest.php
@@ -485,4 +485,85 @@ class ManageDisplayTest extends WebDriverTestBase {
$this->assertNotEmpty($row, 'Field was created and appears in the overview page.');
}
+ /**
+ * Confirms that notifications to save appear when necessary.
+ */
+ public function testNotAppliedUntilSavedWarning() {
+ $assert_session = $this->assertSession();
+ $page = $this->getSession()->getPage();
+
+ // Admin Manage Fields page.
+ $manage_fields = 'admin/structure/types/manage/' . $this->type;
+
+ $this->fieldUIAddNewField($manage_fields, 'test', 'Test field');
+ $manage_display = 'admin/structure/types/manage/' . $this->type . '/display';
+ $manage_form = 'admin/structure/types/manage/' . $this->type . '/form-display';
+
+ // Form display, change widget type.
+ $this->drupalGet($manage_form);
+ $assert_session->elementNotExists('css', '.tabledrag-changed-warning');
+ $assert_session->elementNotExists('css', 'abbr.tabledrag-changed');
+ $page->selectFieldOption('fields[uid][type]', 'options_buttons');
+ $this->assertNotNull($changed_warning = $assert_session->waitForElementVisible('css', '.tabledrag-changed-warning'));
+ $this->assertNotNull($assert_session->waitForElementVisible('css', ' #uid abbr.tabledrag-changed'));
+ $this->assertSame('* You have unsaved changes.', $changed_warning->getText());
+
+ // Form display, change widget settings.
+ $this->drupalGet($manage_form);
+ $edit_widget_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-uid-settings-edit"]');
+ $edit_widget_button->press();
+ $assert_session->waitForText('3rd party formatter settings form');
+
+ // Confirm the AJAX operation of opening the form does not result in the row
+ // being set as changed. New settings must be submitted for that to happen.
+ $assert_session->elementNotExists('css', 'abbr.tabledrag-changed');
+ $cancel_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-uid-settings-edit-form-actions-cancel-settings"]');
+ $cancel_button->press();
+ $assert_session->assertNoElementAfterWait('css', '[data-drupal-selector="edit-fields-uid-settings-edit-form-actions-cancel-settings"]');
+ $assert_session->elementNotExists('css', '.tabledrag-changed-warning');
+ $assert_session->elementNotExists('css', 'abbr.tabledrag-changed');
+ $edit_widget_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-uid-settings-edit"]');
+ $edit_widget_button->press();
+ $widget_field = $assert_session->waitForField('fields[uid][settings_edit_form][third_party_settings][field_third_party_test][field_test_widget_third_party_settings_form]');
+ $widget_field->setValue('honk');
+ $update_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-uid-settings-edit-form-actions-save-settings"]');
+ $update_button->press();
+ $assert_session->assertNoElementAfterWait('css', '[data-drupal-selector="edit-fields-field-test-settings-edit-form-actions-cancel-settings"]');
+ $this->assertNotNull($changed_warning = $assert_session->waitForElementVisible('css', '.tabledrag-changed-warning'));
+ $this->assertNotNull($assert_session->waitForElementVisible('css', ' #uid abbr.tabledrag-changed'));
+ $this->assertSame('* You have unsaved changes.', $changed_warning->getText());
+
+ // Content display, change formatter type.
+ $this->drupalGet($manage_display);
+ $assert_session->elementNotExists('css', '.tabledrag-changed-warning');
+ $assert_session->elementNotExists('css', 'abbr.tabledrag-changed');
+ $page->selectFieldOption('edit-fields-field-test-label', 'inline');
+ $this->assertNotNull($changed_warning = $assert_session->waitForElementVisible('css', '.tabledrag-changed-warning'));
+ $this->assertNotNull($assert_session->waitForElementVisible('css', ' #field-test abbr.tabledrag-changed'));
+ $this->assertSame('* You have unsaved changes.', $changed_warning->getText());
+
+ // Content display, change formatter settings.
+ $this->drupalGet($manage_display);
+ $assert_session->elementNotExists('css', '.tabledrag-changed-warning');
+ $assert_session->elementNotExists('css', 'abbr.tabledrag-changed');
+ $edit_formatter_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-field-test-settings-edit"]');
+ $edit_formatter_button->press();
+ $assert_session->waitForText('3rd party formatter settings form');
+ $cancel_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-field-test-settings-edit-form-actions-cancel-settings"]');
+ $cancel_button->press();
+ $assert_session->assertNoElementAfterWait('css', '[data-drupal-selector="edit-fields-field-test-settings-edit-form-actions-cancel-settings"]');
+ $assert_session->elementNotExists('css', '.tabledrag-changed-warning');
+ $assert_session->elementNotExists('css', 'abbr.tabledrag-changed');
+ $edit_formatter_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-field-test-settings-edit"]');
+ $edit_formatter_button->press();
+ $formatter_field = $assert_session->waitForField('fields[field_test][settings_edit_form][third_party_settings][field_third_party_test][field_test_field_formatter_third_party_settings_form]');
+ $formatter_field->setValue('honk');
+ $update_button = $assert_session->waitForElementVisible('css', '[data-drupal-selector="edit-fields-field-test-settings-edit-form-actions-save-settings"]');
+ $update_button->press();
+ $assert_session->assertNoElementAfterWait('css', '[data-drupal-selector="edit-fields-field-test-settings-edit-form-actions-cancel-settings"]');
+ $this->assertNotNull($changed_warning = $assert_session->waitForElementVisible('css', '.tabledrag-changed-warning'));
+ $this->assertNotNull($assert_session->waitForElementVisible('css', ' #field-test abbr.tabledrag-changed'));
+ $this->assertSame('* You have unsaved changes.', $changed_warning->getText());
+ }
+
}
diff --git a/core/phpstan-baseline.neon b/core/phpstan-baseline.neon
index efb5e397649..a09976ba7d1 100644
--- a/core/phpstan-baseline.neon
+++ b/core/phpstan-baseline.neon
@@ -1217,7 +1217,7 @@ parameters:
-
message: "#^Variable \\$updated_rows might not be defined\\.$#"
- count: 1
+ count: 2
path: modules/field_ui/src/Form/EntityDisplayFormBase.php
-
diff --git a/core/themes/claro/js/tabledrag.js b/core/themes/claro/js/tabledrag.js
index b6a9d331116..79df748de15 100644
--- a/core/themes/claro/js/tabledrag.js
+++ b/core/themes/claro/js/tabledrag.js
@@ -122,6 +122,7 @@
if (cell.find('.js-tabledrag-changed-marker').length === 0) {
cell.find('.js-tabledrag-handle').after(marker);
}
+ Drupal.tableDrag[this.table.id].changedRowIds.add(this.element.id);
},
/**