Form cache causes issues with media library widget

Created on 24 December 2024, 4 months ago

Problem/Motivation

Seems to be some issue with the form cache interaction with the media library widget, and possibly other complex widgets. Not sure where the issue is exactly though. The problem is that after clicking the "remove" button in the media library widget to remove an already-selected item, the form builder doesn't know that the remove button was clicked, and it instead assumes the first button in the form was clicked, which could be anything. On a simple node form with just a media library widget, the button it clicks is the "add media" button so the media library selection modal opens up incorrectly.

Steps to reproduce

  1. Clean install of Drupal with the Media Library module enabled
  2. Create a content type with a media reference field with all default settings
  3. Create a node of that type, select a media item (upload one), and save the node
  4. Edit the node and click the "remove" button in the media library widget. Observe the correct behavior of the item being removed and the widget reverting to its original empty state
  5. Don't save the node, reload the form in your browser
  6. Again, click the "remove" button in the media library widget. Observe that instead of removing the item and reverting the widget to its original state, the media library selection modal opens up incorrectly.

If you have a more complex node form, like one with a paragraphs field on it, what might end up happening instead of the media library modal opening is it that the entire media library widget gets replaced with a paragraph form for a paragraph item!

The wrong behavior is because of this code in FormBuilder:

      // If a form contains a single textfield, and the ENTER key is pressed
      // within it, Internet Explorer submits the form with no POST data
      // identifying any submit button. Other browsers submit POST data as
      // though the user clicked the first button. Therefore, to be as
      // consistent as we can be across browsers, if no 'triggering_element' has
      // been identified yet, default it to the first button.
      $buttons = $form_state->getButtons();
      if (!$form_state->isProgrammed() && !$form_state->getTriggeringElement() && !empty($buttons)) {
        $form_state->setTriggeringElement($buttons[0]);
      }

The wrong element is set as the triggering element for the form submission. Why? Because the form object that's being acted on is used a cached version of the form which is missing the "remove" button for the media library widget. After step #4 above, the state of the form without the selected media item is saved to the cache. And that version of the form is used on the next page reload when you try to click the remove button again.

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Active

Version

11.1 πŸ”₯

Component

forms system

Created by

πŸ‡ΊπŸ‡ΈUnited States bkosborne New Jersey, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024