Advertisement
Guest User

XPages HTML5 Multiple File Upload JS

a guest
Nov 9th, 2012
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Class UploadController
  3.  * Contains massively restructured code based upon example from Julian Buss:
  4.  * http://julianbuss.net/web/youatnotes/blog-jb.nsf/dx/html5-multi-file-upload-with-xpages-my-solution-in-a-nutshell.htm
  5.  *
  6.  * @author: gernot.hummer
  7.  *
  8.  * @version 1.0
  9.  */
  10. function UploadController(){
  11.  
  12.     var _self = this;
  13.     _self.TAG = "[UPLOADCONTROLLER]";
  14.     _self.DEFAULT_LIMIT = 1048576;
  15.     _self.MB_THRESHOLD = 1048576;
  16.     _self.DEFAULT_ERROR = "Die Datei überschreitet das Größenlimit.";
  17.  
  18.     _self.source = null;
  19.     _self.response = null;
  20.     _self.containerID = "";
  21.     _self.url = "";
  22.     _self.uploadID = "";
  23.     _self.form = null;
  24.     _self.inputHTML = "<input id=\"multiUploadInput\" type=\"file\" multiple=\"true\" label=\"Select Some Files\"" +
  25.     " uploadOnSelect=\"false\" name=\"uploadedfile\" class=\"hide\" />";
  26.    
  27.     /**
  28.      * function init()
  29.      *
  30.      * @param url - String. The URL to post ajax upload calls to.
  31.      * @param uploadID - String. The id of the original single file upload element
  32.      * @param multiUploadID - String. The id of the container to place the multi upload element in.
  33.      * @param responseID - String. The id of the container to render the file queue into
  34.      * @param buttonSelectId - String. The id of the button that selects files
  35.      * @param buttonResetId - String. The id of the button that resets the file queue
  36.      * @param buttonUploadId - String. The id of the button that posts files to the server via ajax calls.
  37.      */
  38.     _self.init = function(url, uploadID, multiUploadID, responseID, buttonSelectId, buttonResetId, buttonUploadId){
  39.  
  40.         _self.url = url;
  41.         _self.uploadID = uploadID;
  42.         _self.response = dojo.byId(responseID);
  43.         _self.connectUpload(multiUploadID);
  44.         dojo.connect(dojo.byId(buttonSelectId), "onclick", _self.showDialog);
  45.         dojo.connect(dojo.byId(buttonResetId), "onclick", dojo.partial(_self.reset, multiUploadID));
  46.         dojo.connect(dojo.byId(buttonUploadId), "onclick", dojo.partial(_self.doUpload, url, uploadID))
  47.  
  48.         if(_self.source == null || _self.response == null){
  49.             console.log(_self.TAG + ": Necessary document nodes were not found.");
  50.         }
  51.  
  52.     }
  53.    
  54.     /**
  55.      * function connectUpload()
  56.      * Generates a multi upload input element and connects it via dojo event handling
  57.      *
  58.      * @param multiUploadID - String. The id of the container to place the multi upload element in
  59.      */
  60.     _self.connectUpload = function(multiUploadID){
  61.         _self.containerID = multiUploadID;
  62.         document.getElementById(multiUploadID).innerHTML = _self.inputHTML;
  63.         _self.response.innerHTML = "";
  64.         _self.source = dojo.byId("multiUploadInput");
  65.         _self.form = XSP.findForm("multiUploadInput");
  66.        
  67.         //connect onchange event of upload element with function showQueue()
  68.         dojo.connect(_self.source, "onchange", _self.showQueue);
  69.  
  70.     }
  71.    
  72.     /**
  73.      * function showDialog()
  74.      * Provokes the file picker of the browser to select multiple files.
  75.      */
  76.     _self.showDialog = function(){
  77.         _self.source.click();
  78.     }
  79.  
  80.     /**
  81.      * function showQueue()
  82.      * Renders the current file queue into the target result container. This method is
  83.      * connected to the onchange event of the multi upload input element.
  84.      */
  85.     _self.showQueue = function(){
  86.         try {
  87.             var files = document.getElementById(dojo.attr(_self.source, "id")).files;
  88.             var responseHTML = '';
  89.             if (files && files.length > 0) {           
  90.                 responseHTML = '<table id="fileUpload" class="xspDataTableFileDownload" style="width:100%;margin-bottom:1em">';
  91.                 responseHTML += '<thead style="color:#545454;"><tr><th style="font-weight:bold;width:46px">Size</th><th style="font-weight:bold">Files to Upload</th></tr></thead><tbody  style="color:#a0a0a0">';
  92.                 for (var i = 0; i < files.length; i++) {
  93.                     _self.file = files[i];
  94.                     var size = 0;
  95.                     if (_self.file.size > _self.MB_THRESHOLD)
  96.                         size = (Math.round(_self.file.size / (_self.MB_THRESHOLD))).toString() + ' MB';
  97.                     else
  98.                         size = (Math.round(_self.file.size / 1024)).toString() + ' KB';
  99.                     responseHTML += '<tr><td>'+size+'</td><td>'+_self.file.name+'</td></tr>'
  100.                 }
  101.                 responseHTML += '</tbody></table>'
  102.             }
  103.             _self.response.innerHTML = responseHTML;
  104.         } catch (e) {
  105.             console.log(_self.TAG + ": " + e);
  106.         }
  107.     }
  108.    
  109.     /**
  110.      * function reset()
  111.      * Convenience method to re-initialize the upload element
  112.      */
  113.     _self.reset = function(){
  114.         _self.connectUpload(_self.containerID);
  115.     }
  116.    
  117.     /**
  118.      * function doUpload()
  119.      * Handles the whole upload process of files
  120.      *
  121.      * @param url- String. The URL to direct POST calls to
  122.      * @param uploadID - String. The id of the single file upload element.
  123.      */
  124.     _self.doUpload = function(url, uploadID){
  125.         try{
  126.             var files = document.getElementById(dojo.attr(_self.source, "id")).files;
  127.             var total = files.length;
  128.  
  129.             var callback = new UploadCallback(_self, files, total);
  130.             if(callback.hasMore()){ callback.call(); }
  131.  
  132.         }catch(e){
  133.             console.log(_self.TAG + ": " + e);
  134.         }
  135.     }
  136.    
  137.     /**
  138.      * function doSingleUpload()
  139.      * Uploads a single file to the server
  140.      *
  141.      * @param url - String. The URL to direct POST calls to
  142.      * @param uploadID - String. The id of the single file upload element
  143.      * @param callback - UploadCallback. The callback interaction object for consecutive files.
  144.      */
  145.     _self.doSingleUpload = function(url, uploadID, callback){
  146.         try{
  147.             if(_self._checkFileSize()){
  148.                 _self._prepareForm(uploadID, callback);
  149.                 _self._doAjax(url, callback);
  150.                 return true;
  151.             }
  152.  
  153.         }catch(e){
  154.             console.log(_self.TAG + ": " + e);
  155.         }
  156.  
  157.         return false;
  158.  
  159.     }
  160.    
  161.     /**
  162.      * function setMaxSize()
  163.      * Set the maximum size that is allowed for uploads
  164.      *
  165.      * @param maxSize - number. The amount of MBs allowed.
  166.      */
  167.     _self.setMaxSize = function(maxSize){
  168.         _self.maxSize = maxSize;
  169.     }
  170.    
  171.     /**
  172.      * function _checkFileSize()
  173.      *
  174.      * @return true if the file size is not too big.
  175.      */
  176.     _self._checkFileSize = function(){
  177.         if(!_self.maxSize) _self.maxSize = _self.DEFAULT_LIMIT;
  178.  
  179.         if((_self.file.size / _self.DEFAULT_LIMIT) > _self.maxSize) {
  180.             alert(_self.DEFAULT_ERROR);
  181.             return false;
  182.         }
  183.  
  184.         return true;
  185.     }
  186.    
  187.     /**
  188.      * function _prepareForm()
  189.      * Prepares <code>FormData</code> to be dispatched to the server.
  190.      *
  191.      * @param uploadID- String. The id of the single file upload input element.
  192.      * @param callback - UploadCallback. The callback object this controller interacts with
  193.      */
  194.     _self._prepareForm = function(uploadID, callback){
  195.         var formData = new FormData();
  196.         formData.append(uploadID, callback.getCurrentFile());
  197.         formData.append("$$viewid", dojo.query("input[name='$$viewid']")[0].value);
  198.         formData.append("$$xspsubmitid", dojo.query("input[name='$$xspsubmitid']")[0].value);
  199.         formData.append("$$xspsubmitvalue", dojo.query("input[name='$$xspsubmitvalue']")[0].value);
  200.         formData.append("$$xspsubmitscroll", dojo.query("input[name='$$xspsubmitscroll']")[0].value);
  201.         formData.append(_self.form.id, _self.form.id);
  202.         _self.formData = formData;
  203.     }
  204.  
  205.     /**
  206.      * function _doAjax()
  207.      * The actual ajax call logic to post a file to the server.
  208.      *
  209.      * @param url - String. The url to direct the POST request to.
  210.      * @param callback - UploadCallback. The callback object this controller interacts with.
  211.      */
  212.     _self._doAjax = function(url, callback){
  213.  
  214.         var xhr = new XMLHttpRequest();
  215.  
  216.         xhr.addEventListener("load", function(){
  217.             callback.iterate();
  218.             if(callback.hasMore()){
  219.                 callback.call();
  220.             } else {
  221.                 callback.finish();
  222.             }
  223.         }, false)
  224.  
  225.         xhr.open("POST", url);
  226.         xhr.send(_self.formData);
  227.  
  228.  
  229.     }
  230.  
  231.     return _self;
  232. }
  233.  
  234. /**
  235.  * Class UploadCallback
  236.  * @param controller - The <code>UploadController</code> instance this callback interacts with
  237.  * @param files - The list of <code>File</code>s this callback should handle
  238.  *
  239.  * @author: gernot.hummer
  240.  * @version 1.0
  241.  */
  242. function UploadCallback(controller, files){
  243.  
  244.     var _self = this;
  245.     _self.controller = controller;
  246.     _self.files = files;
  247.     _self.total = files.length;
  248.     _self.current = 0;
  249.    
  250.     /**
  251.      * function hasMore()
  252.      *
  253.      * @returns true the end of the file list hasn't been reached yet.
  254.      */
  255.     _self.hasMore = function(){
  256.         return _self.current<_self.total;
  257.     }
  258.    
  259.     /**
  260.      * function call();
  261.      * This is the main call function of this callback.
  262.      */
  263.     _self.call = function(){
  264.         _self.file = files[_self.current];
  265.         _self.controller.doSingleUpload(_self.controller.url, _self.controller.uploadID, _self);
  266.     }
  267.  
  268.     /**
  269.      * function getCurrentFile()
  270.      * Return the file at the current file number
  271.      *
  272.      * @return File
  273.      */
  274.     _self.getCurrentFile  = function(){
  275.         return _self.file;
  276.     }
  277.    
  278.     /**
  279.      * function finish()
  280.      * Call this after the last ajax call has been effected.
  281.      */
  282.     _self.finish = function(){
  283.         _self.controller.reset();
  284.     }
  285.  
  286.     /**
  287.      * function iterate()
  288.      * Move on to next file number
  289.      */
  290.     _self.iterate= function(){
  291.         _self.current++;
  292.     }
  293.  
  294.     return _self;
  295.  
  296. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement