PageSourceSearch

https://www.minnesotaalumni.org/files/library/scripts/xhrupload.js

js minnesotaalumni.org collected 2026-09-24 20:38:14 UTC 15,562 bytes, 415 lines download raw bytes

1(function($){
2
3  $.fn.WebEditionXHRUpload = function(action){
4
5    var actions = {
6      
7      init: function(options){
8        var $field  = $(this),
9            $form   = $field.closest('form'),
10            config  = {
11              // URL to post this XHR Upload to
12              url: '/asset/upload',
13              
14              // Valid jQuery object that can be used as a progress bar
15              progressBar: $("<progress class='upload-bar' value='0' max='100'></progress>"),
16
17              // wrapper for the progress bar area and image (if preview is enabled)
18              progressWrapper: $("<div class='upload-area'></div>"),
19
20              // wrapper to report status messages in
21              messageWrapper: $("<div class='upload-message'></div>"),
22
23              // wrapper to place file name and details
24              fileWrapper: $("<div class='upload-file'></div>"),
25
26              // Class prefix for message statuses. For example a message status of 'fail' with a messageStatusPrevix of 'upload-' would apply a class of upload-fail to the messageWrapper when that message is displayed
27              messageStatusPrefix: 'upload-',
28
29              // By default, this is how long you should wait to remove a failed upload
30              failRemove: 5000,
31
32              // Class applied to the progress bar before uploading
33              preUploadClass: 'is-preupload',
34
35              // Applied once an object uploading
36              uploading: 'is-uploading',
37
38              // Applied to wrapper once an object is done uploading
39              uploadComplete: 'is-complete',
40
41              // Applied to wrapper once an object fails to upload
42              uploadFailed: 'is-failed',
43
44              // Applied to progress wrapper once object is done
45              progressComplete: 'is-progress-complete',
46
47              // Wrapper area, this becomes droppable NOTE: $this [input type file] must be a child of this wrapper!
48              wrapper: 'div',
49
50              // Class to apply when the droppable area is activated
51              dropActive: 'is-droppable',
52
53              // class to apply when hovering a drag over the drop area
54              dropHover: 'is-drophover',
55
56              // after a drop upload takes place this gets added
57              dropOver: 'is-dropover',
58
59              // Allow multiple file uploads
60              multiple: false,
61
62              // enable drag/drop uploader
63              droppable: true,
64
65              // Allowed file types
66              images: true,
67
68              // Use thumbnail
69              preview: true,
70
71              // Thumbnail class applied to wrapper when uploading images
72              previewClass: 'upload-preview',
73              
74              // Amount of ms to wait till firing the success event
75              successDelay: 1000,
76
77              // Preview builder method
78              upload: function(file, wrapper){
79                $field.WebEditionXHRUpload('upload', file, wrapper);
80              },
81
82              // Progress action callback
83              progress: function(e, wrapper, progressBar){
84                var percent = (e.loaded / e.total * 100 | 0);
85
86                if (percent < 100)
87                  $field.WebEditionXHRUpload('message', percent + '% uploaded', wrapper, 'progress');
88                else
89                  $field.WebEditionXHRUpload('message', 'Processing Upload', wrapper, 'progress');
90
91                // now just update the given progress bar
92                progressBar.val(percent * 0.75);
93              },
94
95              // Slowly creeps the progress bar, will never complete
96              // you can re-assign this to boolean false to remove creep
97              creep: function(wrapper) {
98                var config = this;
99                setTimeout(function(){
100                  var $progressBar = wrapper.find('progress'),
101                      current      = $progressBar.val(),
102                      remainingVal = (100 - current),
103                      creep  = current + (remainingVal * 0.10);
104                  if (remainingVal) {
105                    $progressBar.val(creep);
106                    config.creep(wrapper);
107                  }
108                }, 500);
109              },
110
111              // FileType filter, simply return true or false for each file object
112              fileFilter: function (file){ return true; },
113
114              // Do something after the upload is complete
115              success: function (data, wrapper) {
116                var config = $field.data('WebEditionXHRUpload'),
117                  $droppable = $field.closest(config.wrapper);
118
119                $droppable
120                  .removeClass(config.uploading)
121                  .addClass(config.uploadComplete);
122
123                wrapper.find('progress').remove();
124                wrapper.find('.upload-message').remove();
125              },
126              error: function (wrapper, errorMessage) {
127                console.log('errorTriggered');
128              }
129            };
130          
131
132        // === EXTEND OUR CONFIGURATION
133        options = (options === undefined) ? {}:options;
134        $.extend(config, options);
135
136
137        // === FILTER CALLBACK FOR IMAGES
138        if (config.images && options.fileFilter === undefined)
139          config.fileFilter = function(file) {
140            return file.type.match('image.*');
141          };
142
143
144        // === UPLOAD EVENT FOR IMAGE PREVIEWS
145        if (config.images && config.preview && options.upload === undefined) {
146          config.upload = function(file, wrapper, e){
147            var image = new Image();
148
149            // Create our image
150            image.src = e.target.result;
151            wrapper.append(image);
152
153            // Begin the upload process
154            $field.WebEditionXHRUpload('upload', file, wrapper);
155          };
156        }
157
158        if (config.multiple) $field.attr('multiple','true');
159
160
161        // add the pre-upload class, ideally this would hide the progress bar
162        $field.data('WebEditionXHRUpload', config);
163
164        if (window.FormData === undefined) console.warn('Your browser does not support form uploading in WebEdition!');
165
166        if (config.droppable) $field.WebEditionXHRUpload('droppable');
167
168
169        // this is what actually triggers the upload event
170        $field.on('change', function(){
171          $field.WebEditionXHRUpload('prepareUpload');
172        });
173
174      },
175
176      prepareUpload: function(){
177        var $field    = $(this),
178            config    = $field.data('WebEditionXHRUpload'),
179            $wrapper  = $field.closest(config.wrapper),
180            data      = new FormData(),
181            count     = 0;
182
183        // produce a new FormData object with the proper file types, and call any necessary processing
184        $.each($field.get(0).files, function(idx, file) {
185          var $progressWrapper = $(config.progressWrapper).clone(false), // in case they sent a jquery object
186            $messageWrapper = $(config.messageWrapper).clone(false);
187
188          // Create the upload area
189          $wrapper.append($progressWrapper);
190          $progressWrapper.append($messageWrapper);
191          if (config.images && config.preview) {
192            $progressWrapper.addClass(config.previewClass);
193          }
194
195          if (config.fileFilter(file)) {
196            if (count < 1 || config.multiple) {
197              // If using images, and previews, create the preview image
198              if (config.images && config.preview) {
199                // If we are using an image preview, the preview will take care of the rest
200                $field.WebEditionXHRUpload('imagePreview', file, $progressWrapper);
201              } else {
202                // if we are uploading a file, upload directly from here after outputting name
203                $fileWrapper = $(config.fileWrapper).clone(false);
204                $progressWrapper.append($fileWrapper.html(file.name));
205                config.upload(file, $progressWrapper);
206              }
207              count++;
208            } else {
209              $field.WebEditionXHRUpload('message','You may only upload one file at a time!', $progressWrapper, 'fail');
210              console.warn('This XHRUploader was configured to accept a single file, you attempted to upload multiple');
211            }
212          } else {
213            $field.WebEditionXHRUpload('message', 'Whoops! That ' + file.name + ' is the wrong filetype.', $progressWrapper, 'fail');
214            console.warn('File type ' + file.type + ' did not match requirements');
215          }
216        });
217
218        $field.val('');
219      },
220
221      upload: function(file, wrapper){
222        var $field    = $(this),
223            config    = $field.data('WebEditionXHRUpload'),
224            $droppable = $field.closest(config.wrapper),
225            xhr       = $field.WebEditionXHRUpload('XHRFactory', wrapper),
226            data      = new FormData();
227
228        data.append($field.attr('name'), file);
229        
230        $droppable
231          .addClass(config.uploading)
232          .addClass(config.dropOver);
233
234        if (typeof config.creep == 'function') {
235          // Begin an artificial, asymptotic progression of progress bar
236          setTimeout(function(){
237            config.creep(wrapper);
238          }, 500);
239        }
240
241
242        // Perform the actual upload
243        Webe.ajax({
244          url: config.url,
245          method: 'post',
246          cache: false,
247          contentType: false,
248          processData: false,
249          xhr: xhr,
250          data: data,
251          passthrough: false,
252          error: function(xhr, errorType, exeption){
253            $droppable.removeClass(config.dropOver);
254            if (errorType == 'parsererror') {
255              $field.WebEditionXHRUpload('message', "An unknown error occurred processing your upload", wrapper, 'fail');
256            } else {
257              $field.WebEditionXHRUpload('message', "An error occurred processing your upload: " + errorType, wrapper, 'fail');
258            }
259            
260            wrapper.find('progress').val(100);
261          },
262          success: function(results) {
263            var completeUpload = function() {
264                $droppable
265                  .removeClass(config.uploading)
266                  .addClass(config.uploadComplete);
267                config.success(result, wrapper);
268              };
269
270            results = (!(results instanceof Array) ? [results] : results);
271
272            for (var i in results) {
273              result = results[i];
274              wrapper.find('progress').val(100); // this also terminates the creep
275
276                try {
277                  if (result.status) {
278                    // If the upload was successful:
279                    wrapper.addClass(config.progressComplete);
280                    $field.WebEditionXHRUpload('message', result.message, wrapper, 'success');
281                    setTimeout(completeUpload, config.successDelay);
282
283                  // if the upload failed in some way
284                  } else {
285                    var message = (result.message === undefined) ? "An unknown error occurred while processing your upload." : result.message;
286                    $field.WebEditionXHRUpload('message', message, wrapper, 'fail');
287                    $droppable.addClass(config.uploadFailed);
288                    config.error(wrapper, message);
289                  }
290                } catch(error) {
291                  $field.WebEditionXHRUpload('message', "An unknown error occurred processing your upload", wrapper, 'fail');
292                }
293            }
294          }
295        });
296      },
297
298      reset: function(wrapper) {
299        var $field     = $(this),
300            config     = $field.data('WebEditionXHRUpload'),
301            $droppable = $field.closest(config.wrapper);
302
303        $field.val('');
304
305        $droppable
306          .removeClass(config.uploadComplete)
307          .removeClass(config.uploading)
308          .removeClass(config.dropOver);
309
310        wrapper.remove();
311      },
312
313      droppable: function(){
314        var $field     = $(this),
315            config     = $field.data('WebEditionXHRUpload'),
316            $droppable = $field.closest(config.wrapper),
317            $help = $droppable.next('.help');
318        
319        // Apply the droppable class
320        $droppable.addClass(config.dropActive);
321
322        // Move help text within the uploader
323        $droppable.append($help);
324
325        // Listen for dragenter, and apply the dropHover class
326        $droppable.on('dragenter', function(e){
327          e.stopPropagation();
328          e.preventDefault();
329          $droppable.addClass(config.dropHover);
330        });
331
332        // Dragover event end
333        $droppable.on('dragover', function(e){
334          e.stopPropagation();
335          e.preventDefault();
336        });
337
338        // Remove classes when dragging is over
339        $droppable.on('dragleave', function(e){
340          $droppable.removeClass(config.dropHover);
341        });
342
343        // Perform the upload when the object is dropped
344        $droppable.on('drop', function(e){
345          e.preventDefault();
346          var files = e.originalEvent.dataTransfer.files;
347
348          $field.get(0).files = files; // assign the files to our uploader (triggering change event)
349          $droppable.removeClass(config.dropHover);
350        });
351      },
352
353      imagePreview: function(file, wrapper){
354        var $field = $(this),
355            config = $field.data('WebEditionXHRUpload'),
356            reader = new FileReader();
357
358        // Assign our callback event, with a double closure to provide
359        // the file as well as the event object to our upload() callback
360        $(reader).on('load', (function(f){
361          return function(e){
362            config.upload(f, wrapper, e);
363          };
364        })(file));
365
366        // Initiate 
367        reader.readAsDataURL(file);
368      },
369
370      message: function(message, wrapper, type) {
371        var $field            = $(this),
372            config            = $field.data('WebEditionXHRUpload'),
373            $messageContainer = wrapper.find('.'+($(config.messageWrapper).attr('class'))),
374            firstClass        = $(config.messageWrapper).attr('class').split(" ")[0];
375          
376        type = (type === undefined) ? 'info' : type;
377        if (!firstClass) console.warn('Your messageWrapper must contain a class by default!');
378
379        $messageContainer.attr('class', firstClass);
380        $messageContainer.addClass(config.messageStatusPrefix + type);
381        $messageContainer.html("<span>" + message + "</span>");
382      },
383
384      XHRFactory: function(wrapper){
385        var $field            = $(this),
386            config            = $field.data('WebEditionXHRUpload'),
387            xhr               = jQuery.ajaxSettings.xhr(),
388            $progressInstance = config.progressBar.clone(false);
389        $(wrapper).append($progressInstance);
390
391        if (xhr instanceof window.XMLHttpRequest) {
392          xhr.upload.addEventListener('progress', (function(progressBar){
393            return function(e){
394              config.progress(e, wrapper, progressBar);
395            };
396          })($progressInstance));
397        } else {
398          console.warn('Unable to properly build the XHR Object!');
399        }
400
401        // return a closure with our special sauce xhr object
402        return function() {
403          return xhr;
404        };
405      }
406
407    };
408
409    if(actions[action]) return actions[action].apply(this, Array.prototype.slice.call(arguments, 1));
410    else if(typeof action === 'object' || !action) return actions.init.apply(this, arguments);
411    else $.error(action + ' is an undefined action of WebEditionXHRUpload');
412  
413  };
414
415})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.