diff --git a/core/modules/file/file.js b/core/modules/file/file.js index 96918a7b030f..70241a181269 100644 --- a/core/modules/file/file.js +++ b/core/modules/file/file.js @@ -18,27 +18,33 @@ attach: function (context, settings) { var $context = $(context); var validateExtension = Drupal.file.validateExtension; - var selector, elements; + var elements; + + function initFileValidation (selector) { + $context.find(selector) + .once('fileValidate') + .on('change.fileValidate', { extensions: elements[selector] }, Drupal.file.validateExtension); + } + if (settings.file && settings.file.elements) { elements = settings.file.elements; - for (selector in elements) { - if (elements.hasOwnProperty(selector)) { - $context.find(selector).on('change', {extensions: elements[selector]}, validateExtension); - } - } + Object.keys(elements).forEach(initFileValidation); } }, - detach: function (context, settings) { + detach: function (context, settings, trigger) { var $context = $(context); var validateExtension = Drupal.file.validateExtension; - var selector, elements; - if (settings.file && settings.file.elements) { + var elements; + + function removeFileValidation (selector) { + $context.find(selector) + .removeOnce('fileValidate') + .off('change.fileValidate', Drupal.file.validateExtension); + } + + if (trigger === 'unload' && settings.file && settings.file.elements) { elements = settings.file.elements; - for (selector in elements) { - if (elements.hasOwnProperty(selector)) { - $context.find(selector).off('change', validateExtension); - } - } + Object.keys(elements).forEach(removeFileValidation); } } }; @@ -115,6 +121,8 @@ }); $(this).closest('div.form-managed-file').prepend('
' + error + '
'); this.value = ''; + // Cancel all other change event handlers. + event.stopImmediatePropagation(); } } }, diff --git a/core/modules/file/file.module b/core/modules/file/file.module index d78f80923f06..6bf4d29474d3 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -1266,7 +1266,7 @@ function file_managed_file_process($element, &$form_state, $form) { $element['upload']['#attached']['js'] = array( array( 'type' => 'setting', - 'data' => array('file' => array('elements' => array('#' . $element['#id'] . '-upload' => $extension_list))) + 'data' => array('file' => array('elements' => array('#' . $element['#id'] => $extension_list))) ) ); }