diff -u b/core/modules/file/file.js b/core/modules/file/file.js
--- b/core/modules/file/file.js
+++ b/core/modules/file/file.js
@@ -25,7 +25,7 @@
attach: function (context) {
var $context = $(context);
- $context.find('.js-form-managed-file .js-form-file')
+ $context.find('[data-drupal-validate-extensions]')
.once('fileValidate')
.on('change.fileValidate', Drupal.file.validateExtension);
},
@@ -33,7 +33,7 @@
var $context = $(context);
if (trigger === 'unload') {
- $context.find('.js-form-managed-file .js-form-file')
+ $context.find('[data-drupal-validate-extensions]')
.removeOnce('fileValidate')
.off('change.fileValidate', Drupal.file.validateExtension);
}
@@ -124,14 +124,11 @@
$('.file-upload-js-error').remove();
// Add client side validation for the input[type=file].
- var extensionPattern = $(event.target).attr('data-drupal-validate-extensions').replace(/,|\s+/g, '|');
- if (extensionPattern.length > 1 && event.target.value.length > 0) {
- var acceptableMatch = new RegExp('\\.(' + extensionPattern + ')$', 'i');
- var testSubjects;
- if (event.target.files) {
- testSubjects = event.target.files;
- }
- else {
+ var validExtensions = JSON.parse(event.target.getAttribute('data-drupal-validate-extensions'));
+ if (validExtensions.length > 1 && event.target.value.length > 0) {
+ var acceptableMatch = new RegExp('\\.(' + validExtensions.join('|') + ')$', 'i');
+ var testSubjects = event.target.files;
+ if (!testSubjects) {
testSubjects = [{name: event.target.value}];
}
var invalidFiles = [];
@@ -149,21 +146,7 @@
}
}
if (invalidFiles.length) {
- var error = Drupal.formatPlural(invalidFiles.length, 'The selected file %filename cannot be uploaded.', '@count of the selected files cannot be uploaded.', {
- '%filename': invalidFiles[0]
- });
- if (invalidFiles.length > 1) {
- error += '
';
- for (var j = 0; j < invalidFiles.length; j++) {
- error += '- ' + Drupal.formatString('%filename', {'%filename': invalidFiles[j]}) + '
';
- }
- error += '
';
- }
- error += ' ';
- error += Drupal.t('Only files with the following extensions are allowed: %extensions.', {
- '%extensions': extensionPattern.replace(/\|/g, ', ')
- });
- $(this).closest('div.js-form-managed-file').prepend('' + error + '
');
+ $(this).closest('div.js-form-managed-file').prepend(Drupal.theme('fileValidationError', invalidFiles, validExtensions));
this.value = '';
// Cancel all other change event handlers.
event.stopImmediatePropagation();
@@ -266,2 +249,32 @@
+ /**
+ * Error message of file validation.
+ *
+ * @param {Array.} invalidFiles
+ * Array of invalid filenames.
+ * @param {string} validExtensions
+ * List of accepted files extensions.
+ *
+ * @return {string}
+ * Error message.
+ */
+ Drupal.theme.fileValidationError = function (invalidFiles, validExtensions) {
+ var error = Drupal.formatPlural(invalidFiles.length, 'The selected file %filename cannot be uploaded.', '@count of the selected files cannot be uploaded.', {
+ '%filename': invalidFiles[0]
+ });
+ if (invalidFiles.length > 1) {
+ error += '';
+ invalidFiles.forEach(function (file) {
+ error += '- ' + Drupal.formatString('%filename', {'%filename': file}) + '
';
+ });
+ error += '
';
+ }
+ error += ' ';
+ error += Drupal.t('Only files with the following extensions are allowed: %extensions.', {
+ '%extensions': validExtensions.join(', ')
+ });
+
+ return '' + error + '
';
+ };
+
})(jQuery, Drupal);
diff -u b/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php
--- b/core/modules/file/src/Element/ManagedFile.php
+++ b/core/modules/file/src/Element/ManagedFile.php
@@ -2,6 +2,7 @@
namespace Drupal\file\Element;
+use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
@@ -343,7 +344,8 @@
}
if (isset($element['#upload_validators']['file_validate_extensions'][0])) {
- $element['upload']['#attributes']['data-drupal-validate-extensions'] = $element['#upload_validators']['file_validate_extensions'][0];
+ $extension_list = array_filter(explode(' ', $element['#upload_validators']['file_validate_extensions'][0]));
+ $element['upload']['#attributes']['data-drupal-validate-extensions'] = Json::encode($extension_list);
}
// Let #id point to the file element, so the field label's 'for' corresponds