Allowed file extensions not populating widget upload field accept attributes

Created on 23 April 2024, 2 months ago

Problem/Motivation

When a file or image field on an entity is configured to use s3fs_cors_* field widgets, the file upload input field DOM element in the widget is not being populated with the configured allowed file extensions for the entity field. Then when the input is clicked, the browser's file browser modal does not filter files for the correct extensions. Users can easily upload the wrong file type by mistake. Though a validation error appears when a wrong file is uploaded, submit buttons on the form that were disabled by the upload are not re-enabled, which means users may have to reload the page to be able to interact with those parts of the form again.

Steps to reproduce

Note that the patch for

  1. Install Drupal (10.2.5) with standard profile
  2. Install and configure s3fs_cors module. Note that patch for [#3413623} may need to be applied to prevent error when creating node later
  3. Change the upload destination for the Image field on Article content type to S3 File system
  4. Manage the form display for Article content type and change the widget for the Image field to S3fs Cors Image Upload
  5. Go to /node/add/article to create a new Article node
  6. Use browser inspector (or view page source) and confirm that the Image upload input element is missing the accept="image/*" attribute. Markup will look something like this: <input class="s3fs-cors-upload js-form-file form-file form-element form-element--type-file form-element--api-file" data-drupal-selector="edit-field-image-0-upload" type="file" id="edit-field-image-0-upload" name="files[field_image_0]" size="22" data-once="s3fs-cors-auto-upload">
  7. Click the file upload input and observe that selectable files in the file modal are not filtered to image types (presentation will vary browser and operating system)
  8. Select a file of the wrong type to upload
  9. Observe that an error correctly displays: "Only files with the following extensions are allowed: png gif jpg jpeg webp."
  10. Observe that the Save & Preview buttons remain disabled
  11. Note that with an image field/widget, it may be possible to re-enable buttons because the widget will present a "Remove" button after uploading finishes, but if using a File field instead (by adding a File field to the ctype and configuring), the Remove button is never presented

Proposed resolution

The missing accept="image/*" attribute on the input is happening because the render array attributes for the element are being clobbered in Drupal\s3fs_cors\Element\S3fsCorsFile::processManagedFile() with this line: $element['upload']['#attributes'] = ['class' => ['s3fs-cors-upload']];. $element['upload']['#attributes'] could already be set by the call to parent::processManagedFile() directly before this. The fix would be safely add the class attribute to the existing array.

For the disabled button issue, the fix would be Drupal.s3fsCors.triggerUploadButton() in s3fs_cors.js for this code:

        if (error) {
          $(this).closest('div.js-form-managed-file').prepend('<div class="messages messages--error file-upload-js-error" aria-live="polite">' + error + '</div>');
          this.value = '';
          return;

        }

The submit buttons need to be re-enabled before `return;`

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Needs review

Version

1.0

Component

Documentation

Created by

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

Merge Requests

Comments & Activities

Production build 0.69.0 2024