Problem/Motivation

When working with managed files in a regular form (opposed to using the field widget), the managed file elements gets wrapped on each file upload over and over again.

After uploading a file the AJAX return contains:

  1. an optional error messages element (this is also the case for the field widget),
  2. the AJAX wrapper and
  3. an extra placeholder <span class="ajax-new-content"></span>.

AJAX returns that consist out of more than one element are being wrapped in a plain DIV by Drupal.ajax.prototype.commands.insert(). On the next file upload the AJAX wrapper is being replaced with another plain DIV element containing again an optional messages element, AJAX container and placeholder.

After a few uploads the results are multiple nested plain DIV's, each with an optional messages element and always with the placeholder. Though the nested plain DIV's and empty placeholders are probably invisible to the user (depending on the site's CSS), it does clutter up the DOM. The error messages that are never being removed is obviously more of a problem.

Proposed resolution

Alter file_ajax_upload() so elements are moved to inside the AJAX wrapper or stop inserting them to the DOM them at all.

The error messages are very much needed of course, the patch from #1792032-15: File validation error message not removed after subsequent upload of valid file moves them to inside the AJAX wrapper.

The placeholder could also be easily moved to the inside of the AJAX wrapper by not appending it to the #suffix property as in:

$form['#suffix'] .= '<span class="ajax-new-content"></span>';

but prepending it as in:

$form['#suffix'] = '<span class="ajax-new-content"></span>' . $form['#suffix'];

But... What is the use of the placeholder? .ajax-new-content elements are used by Drupal.ajax.prototype.commands.insert() to show / hide content that is being inserted by AJAX, but the placeholder is inserted empty and seems to never receive any content. Drupal.ajax.prototype.commands.insert() does not require such an element, so maybe we can remove this element from code completely?

Remaining tasks

Find out the use of the placeholder and remove it from code if there is none.

User interface changes

None.

API changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

lmeurs’s picture

FileSize
70.12 KB

I attached a screenshot to point out the nesting and extra elements not being removed after I tried to upload a too large file three times and then a valid file.

The placeholders are styled to make them visible, in the DOM inspector I highlighted all the excessive elements that would not be there if all elements would be placed inside the AJAX wrapper.

dcam’s picture

Sounds like a duplicate of the last post in #736066: ajax.js insert command sometimes wraps content in a div, potentially producing invalid HTML and other bugs. I'll leave this issue open though since it's probably better to start a new one rather than keep open an issue that was fixed and closed.

lmeurs’s picture

For D7: As stated earlier, the patch from #1792032-15: File validation error message not removed after subsequent upload of valid file moves the error messages to inside the AJAX wrapper. I made a small improvement so the error messages will be removed on a successful upload, see #1792032-29: File validation error message not removed after subsequent upload of valid file.

Now only the <span class="ajax-new-content"></span> placeholder still is placed outside the AJAX form wrapper. I just did another search on this empty placeholder element: Drupal core does not seem to insert any content to it and the empty element does not seem to serve any purpose, so instead of moving it to the inside of the AJAX wrapper I just removed it at all. See attached patch for D7.

droplet’s picture