Skip to content
Snippets Groups Projects
Unverified Commit 3e90900f authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3115054 by chr.fritsch, vsujeetkumar, Vidushi Mehta, sergiuteaca,...

Issue #3115054 by chr.fritsch, vsujeetkumar, Vidushi Mehta, sergiuteaca, janmejaig, ranjith_kumar_k_u, phenaproxima: Media library widget forgets ordering when adding or removing items

(cherry picked from commit 6470ab79)
parent 79ad4249
No related branches found
No related tags found
No related merge requests found
......@@ -286,6 +286,22 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter
return parent::form($items, $form, $form_state, $get_delta);
}
/**
* {@inheritdoc}
*/
public function extractFormValues(FieldItemListInterface $items, array $form, FormStateInterface $form_state) {
parent::extractFormValues($items, $form, $form_state);
// Update reference to 'items' stored during add or remove to take into
// account changes to values like 'weight' etc.
// @see Drupal\media_library\Plugin\Field\FieldWidget\MediaLibraryWidget::addItems
// @see Drupal\media_library\Plugin\Field\FieldWidget\MediaLibraryWidget::removeItem
$field_name = $this->fieldDefinition->getName();
$field_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
$field_state['items'] = $items->getValue();
static::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
}
/**
* {@inheritdoc}
*/
......@@ -744,7 +760,15 @@ public static function updateWidget(array $form, FormStateInterface $form_state)
* The form state.
*/
public static function removeItem(array $form, FormStateInterface $form_state) {
// During the form rebuild, formElement() will create field item widget
// elements using re-indexed deltas, so clear out FormState::$input to
// avoid a mismatch between old and new deltas. The rebuilt elements will
// have #default_value set appropriately for the current state of the field,
// so nothing is lost in doing this.
// @see Drupal\media_library\Plugin\Field\FieldWidget\MediaLibraryWidget::extractFormValues
$triggering_element = $form_state->getTriggeringElement();
$parents = array_slice($triggering_element['#parents'], 0, -2);
NestedArray::setValue($form_state->getUserInput(), $parents, NULL);
// Get the parents required to find the top-level widget element.
if (count($triggering_element['#array_parents']) < 4) {
......@@ -844,7 +868,17 @@ public static function validateItems(array $form, FormStateInterface $form_state
* The form state.
*/
public static function addItems(array $form, FormStateInterface $form_state) {
// During the form rebuild, formElement() will create field item widget
// elements using re-indexed deltas, so clear out FormState::$input to
// avoid a mismatch between old and new deltas. The rebuilt elements will
// have #default_value set appropriately for the current state of the field,
// so nothing is lost in doing this.
// @see Drupal\media_library\Plugin\Field\FieldWidget\MediaLibraryWidget::extractFormValues
$button = $form_state->getTriggeringElement();
$parents = array_slice($button['#parents'], 0, -1);
$parents[] = 'selection';
NestedArray::setValue($form_state->getUserInput(), $parents, NULL);
$element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
$field_state = static::getFieldState($element, $form_state);
......
......@@ -3,6 +3,7 @@
namespace Drupal\Tests\media_library\FunctionalJavascript;
use Drupal\field\Entity\FieldConfig;
use Drupal\FunctionalJavascriptTests\SortableTestTrait;
/**
* Tests the Media library entity reference widget.
......@@ -11,6 +12,8 @@
*/
class EntityReferenceWidgetTest extends MediaLibraryTestBase {
use SortableTestTrait;
/**
* {@inheritdoc}
*/
......@@ -256,6 +259,7 @@ public function testWidget() {
$this->openMediaLibraryForField('field_twin_media');
$page->checkField('Select Dog');
$this->pressInsertSelected('Added one media item.');
$this->waitForElementsCount('css', '.field--name-field-twin-media [data-media-library-item-delta]', 2);
// Assert that we can toggle the visibility of the weight inputs when the
// field contains more than one item.
$wrapper = $assert_session->elementExists('css', '.field--name-field-twin-media');
......@@ -485,4 +489,86 @@ public function testRequiredMediaField() {
$this->assertSession()->pageTextContains('Basic page My page has been created.');
}
/**
* Tests that changed order is maintained after removing a selection.
*/
public function testRemoveAfterReordering(): void {
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
$this->drupalGet('node/add/basic_page');
$page->fillField('Title', 'My page');
$this->openMediaLibraryForField('field_unlimited_media');
$page->checkField('Select Dog');
$page->checkField('Select Cat');
$page->checkField('Select Bear');
// Order: Dog - Cat - Bear.
$this->pressInsertSelected('Added 3 media items.');
// Move first item (Dog) to the end.
// Order: Cat - Bear - Dog.
$this->sortableAfter('[data-media-library-item-delta="0"]', '[data-media-library-item-delta="2"]', '.js-media-library-selection');
$wrapper = $assert_session->elementExists('css', '.field--name-field-unlimited-media');
// Remove second item (Bear).
// Order: Cat - Dog.
$wrapper->find('css', "[aria-label='Remove Bear']")->press();
$this->waitForText('Bear has been removed.');
$page->pressButton('Save');
$assert_session->elementTextContains('css', '.field--name-field-unlimited-media > .field__items > .field__item:last-child', 'Dog');
}
/**
* Tests that order is correct after re-order and adding another item.
*/
public function testAddAfterReordering(): void {
$assert_session = $this->assertSession();
$page = $this->getSession()->getPage();
$this->drupalGet('node/add/basic_page');
$page->fillField('Title', 'My page');
$this->openMediaLibraryForField('field_unlimited_media');
$page->checkField('Select Dog');
$page->checkField('Select Cat');
// Order: Dog - Cat.
$this->pressInsertSelected('Added 2 media items.');
// Change positions.
// Order: Cat - Dog.
$this->sortableAfter('[data-media-library-item-delta="0"]', '[data-media-library-item-delta="1"]', '.js-media-library-selection');
$this->openMediaLibraryForField('field_unlimited_media');
$this->selectMediaItem(2);
// Order: Cat - Dog - Bear.
$this->pressInsertSelected('Added one media item.');
$page->pressButton('Save');
$assert_session->elementTextContains('css', '.field--name-field-unlimited-media > .field__items > .field__item:first-child', 'Cat');
$assert_session->elementTextContains('css', '.field--name-field-unlimited-media > .field__items > .field__item:last-child', 'Bear');
}
/**
* {@inheritdoc}
*/
protected function sortableUpdate($item, $from, $to = NULL) {
// See core/modules/media_library/js/media_library.widget.es6.js.
$script = <<<JS
(function ($) {
var selection = document.querySelectorAll('.js-media-library-selection');
selection.forEach(function (widget) {
$(widget).children().each(function (index, child) {
$(child).find('.js-media-library-item-weight').val(index);
});
});
})(jQuery)
JS;
$this->getSession()->executeScript($script);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment