file.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * @file
  3. * Provides JavaScript additions to the managed file field type.
  4. *
  5. * This file provides progress bar support (if available), popup windows for
  6. * file previews, and disabling of other file fields during Ajax uploads (which
  7. * prevents separate file fields from accidentally uploading files).
  8. */
  9. (function ($) {
  10. /**
  11. * Attach behaviors to managed file element upload fields.
  12. */
  13. Drupal.behaviors.fileValidateAutoAttach = {
  14. attach: function (context, settings) {
  15. if (settings.file && settings.file.elements) {
  16. $.each(settings.file.elements, function(selector) {
  17. var extensions = settings.file.elements[selector];
  18. $(selector, context).bind('change', {extensions: extensions}, Drupal.file.validateExtension);
  19. });
  20. }
  21. },
  22. detach: function (context, settings) {
  23. if (settings.file && settings.file.elements) {
  24. $.each(settings.file.elements, function(selector) {
  25. $(selector, context).unbind('change', Drupal.file.validateExtension);
  26. });
  27. }
  28. }
  29. };
  30. /**
  31. * Attach behaviors to the file upload and remove buttons.
  32. */
  33. Drupal.behaviors.fileButtons = {
  34. attach: function (context) {
  35. $('input.form-submit', context).bind('mousedown', Drupal.file.disableFields);
  36. $('div.form-managed-file input.form-submit', context).bind('mousedown', Drupal.file.progressBar);
  37. },
  38. detach: function (context) {
  39. $('input.form-submit', context).unbind('mousedown', Drupal.file.disableFields);
  40. $('div.form-managed-file input.form-submit', context).unbind('mousedown', Drupal.file.progressBar);
  41. }
  42. };
  43. /**
  44. * Attach behaviors to links within managed file elements.
  45. */
  46. Drupal.behaviors.filePreviewLinks = {
  47. attach: function (context) {
  48. $('div.form-managed-file .file a, .file-widget .file a', context).bind('click',Drupal.file.openInNewWindow);
  49. },
  50. detach: function (context){
  51. $('div.form-managed-file .file a, .file-widget .file a', context).unbind('click', Drupal.file.openInNewWindow);
  52. }
  53. };
  54. /**
  55. * File upload utility functions.
  56. */
  57. Drupal.file = Drupal.file || {
  58. /**
  59. * Client-side file input validation of file extensions.
  60. */
  61. validateExtension: function (event) {
  62. // Remove any previous errors.
  63. $('.file-upload-js-error').remove();
  64. // Add client side validation for the input[type=file].
  65. var extensionPattern = event.data.extensions.replace(/,\s*/g, '|');
  66. if (extensionPattern.length > 1 && this.value.length > 0) {
  67. var acceptableMatch = new RegExp('\\.(' + extensionPattern + ')$', 'gi');
  68. if (!acceptableMatch.test(this.value)) {
  69. var error = Drupal.t("The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.", {
  70. '%filename': this.value,
  71. '%extensions': extensionPattern.replace(/\|/g, ', ')
  72. });
  73. $(this).closest('div.form-managed-file').prepend('<div class="messages error file-upload-js-error">' + error + '</div>');
  74. this.value = '';
  75. return false;
  76. }
  77. }
  78. },
  79. /**
  80. * Prevent file uploads when using buttons not intended to upload.
  81. */
  82. disableFields: function (event){
  83. var clickedButton = this;
  84. // Only disable upload fields for Ajax buttons.
  85. if (!$(clickedButton).hasClass('ajax-processed')) {
  86. return;
  87. }
  88. // Check if we're working with an "Upload" button.
  89. var $enabledFields = [];
  90. if ($(this).closest('div.form-managed-file').length > 0) {
  91. $enabledFields = $(this).closest('div.form-managed-file').find('input.form-file');
  92. }
  93. // Temporarily disable upload fields other than the one we're currently
  94. // working with. Filter out fields that are already disabled so that they
  95. // do not get enabled when we re-enable these fields at the end of behavior
  96. // processing. Re-enable in a setTimeout set to a relatively short amount
  97. // of time (1 second). All the other mousedown handlers (like Drupal's Ajax
  98. // behaviors) are excuted before any timeout functions are called, so we
  99. // don't have to worry about the fields being re-enabled too soon.
  100. // @todo If the previous sentence is true, why not set the timeout to 0?
  101. var $fieldsToTemporarilyDisable = $('div.form-managed-file input.form-file').not($enabledFields).not(':disabled');
  102. $fieldsToTemporarilyDisable.attr('disabled', 'disabled');
  103. setTimeout(function (){
  104. $fieldsToTemporarilyDisable.attr('disabled', false);
  105. }, 1000);
  106. },
  107. /**
  108. * Add progress bar support if possible.
  109. */
  110. progressBar: function (event) {
  111. var clickedButton = this;
  112. var $progressId = $(clickedButton).closest('div.form-managed-file').find('input.file-progress');
  113. if ($progressId.length) {
  114. var originalName = $progressId.attr('name');
  115. // Replace the name with the required identifier.
  116. $progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
  117. // Restore the original name after the upload begins.
  118. setTimeout(function () {
  119. $progressId.attr('name', originalName);
  120. }, 1000);
  121. }
  122. // Show the progress bar if the upload takes longer than half a second.
  123. setTimeout(function () {
  124. $(clickedButton).closest('div.form-managed-file').find('div.ajax-progress-bar').slideDown();
  125. }, 500);
  126. },
  127. /**
  128. * Open links to files within forms in a new window.
  129. */
  130. openInNewWindow: function (event) {
  131. $(this).attr('target', '_blank');
  132. window.open(this.href, 'filePreview', 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550');
  133. return false;
  134. }
  135. };
  136. })(jQuery);