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