file.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. (function ($) {
  2. // Override core JS so it works with "button" tags.
  3. /**
  4. * Attach behaviors to the file upload and remove buttons.
  5. */
  6. Drupal.behaviors.fileButtons = {
  7. attach: function (context) {
  8. $(':input.form-submit', context).bind('mousedown', Drupal.file.disableFields);
  9. $('div.form-managed-file :input.form-submit', context).bind('mousedown', Drupal.file.progressBar);
  10. },
  11. detach: function (context) {
  12. $(':input.form-submit', context).unbind('mousedown', Drupal.file.disableFields);
  13. $('div.form-managed-file :input.form-submit', context).unbind('mousedown', Drupal.file.progressBar);
  14. }
  15. };
  16. if (Drupal.file) {
  17. /**
  18. * Prevent file uploads when using buttons not intended to upload.
  19. */
  20. Drupal.file.disableFields = function (event){
  21. var clickedButton = this;
  22. // Only disable upload fields for Ajax buttons.
  23. if (!$(clickedButton).hasClass('ajax-processed')) {
  24. return;
  25. }
  26. // Check if we're working with an "Upload" button.
  27. var $enabledFields = [];
  28. if ($(this).closest('div.form-managed-file').length > 0) {
  29. $enabledFields = $(this).closest('div.form-managed-file').find(':input.form-file');
  30. }
  31. // Temporarily disable upload fields other than the one we're currently
  32. // working with. Filter out fields that are already disabled so that they
  33. // do not get enabled when we re-enable these fields at the end of behavior
  34. // processing. Re-enable in a setTimeout set to a relatively short amount
  35. // of time (1 second). All the other mousedown handlers (like Drupal's Ajax
  36. // behaviors) are excuted before any timeout functions are called, so we
  37. // don't have to worry about the fields being re-enabled too soon.
  38. // @todo If the previous sentence is true, why not set the timeout to 0?
  39. var $fieldsToTemporarilyDisable = $('div.form-managed-file :input.form-file').not($enabledFields).not(':disabled');
  40. $fieldsToTemporarilyDisable.attr('disabled', 'disabled');
  41. setTimeout(function (){
  42. $fieldsToTemporarilyDisable.attr('disabled', false);
  43. }, 1000);
  44. };
  45. /**
  46. * Add progress bar support if possible.
  47. */
  48. Drupal.file.progressBar = function (event) {
  49. var clickedButton = this;
  50. var $progressId = $(clickedButton).closest('div.form-managed-file').find(':input.file-progress');
  51. if ($progressId.length) {
  52. var originalName = $progressId.attr('name');
  53. // Replace the name with the required identifier.
  54. $progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
  55. // Restore the original name after the upload begins.
  56. setTimeout(function () {
  57. $progressId.attr('name', originalName);
  58. }, 1000);
  59. }
  60. // Show the progress bar if the upload takes longer than half a second.
  61. setTimeout(function () {
  62. $(clickedButton).closest('div.form-managed-file').find('div.ajax-progress-bar').slideDown();
  63. }, 500);
  64. };
  65. /**
  66. * Styling invalid file extension error message (Issue #2331595 by NetTantra).
  67. */
  68. Drupal.file.validateExtension = function (event) {
  69. // Remove any previous errors.
  70. $('.file-upload-js-error').remove();
  71. // Add client side validation for the input[type=file].
  72. var extensionPattern = event.data.extensions.replace(/,\s*/g, '|');
  73. if (extensionPattern.length > 1 && this.value.length > 0) {
  74. var acceptableMatch = new RegExp('\\.(' + extensionPattern + ')$', 'gi');
  75. if (!acceptableMatch.test(this.value)) {
  76. var error = Drupal.t("The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.", {
  77. // According to the specifications of HTML5, a file upload control
  78. // should not reveal the real local path to the file that a user
  79. // has selected. Some web browsers implement this restriction by
  80. // replacing the local path with "C:\fakepath\", which can cause
  81. // confusion by leaving the user thinking perhaps Drupal could not
  82. // find the file because it messed up the file path. To avoid this
  83. // confusion, therefore, we strip out the bogus fakepath string.
  84. '%filename': this.value.replace('C:\\fakepath\\', ''),
  85. '%extensions': extensionPattern.replace(/\|/g, ', ')
  86. });
  87. $(this).closest('div.form-managed-file').parents('.form-item').first().prepend('<div class="alert alert-danger alert-dismissible messages error file-upload-js-error" aria-live="polite" role="alert">\
  88. <button type="button" class="close" data-dismiss="alert">\
  89. <span aria-hidden="true">&times;</span>\
  90. <span class="sr-only">Close</span>\
  91. </button>' + error + '</div>');
  92. this.value = '';
  93. return false;
  94. }
  95. }
  96. };
  97. }
  98. })(jQuery);