cancel
Showing results for 
Search instead for 
Did you mean: 

alfresco share upload file

khawlich
Champ in-the-making
Champ in-the-making
Bonjour,
Je travail sur un projet développé avec alfresco share et je veux ajouter un bouton upload file pour ajouter des documents dans ma page. Il y a tellement de fichiers que je sais pas quoi modifier et par quoi commencer.
Est ce que quelqu'un peut m'aider.
Merciiii Smiley Wink
11 REPLIES 11

khawlich
Champ in-the-making
Champ in-the-making
bonjour,
Oui j'ai les sources Voilà flash-upload.js
 /*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception.  You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/

/**
* FlashUpload component.
*
* Popups a YUI panel and displays a filelist and buttons to browse for files
* and upload them. Files can be removed and uploads can be cancelled.
* For single file uploads version input can be submitted.
*
* A multi file upload scenario could look like:
*
* var flashUpload = Alfresco.component.getFlashUploadInstance();
* var multiUploadConfig =
* {
*    siteId: siteId,
*    containerId: doclibContainerId,
*    path: docLibUploadPath,
*    filter: [],
*    mode: flashUpload.MODE_MULTI_UPLOAD,
* }
* this.flashUpload.show(multiUploadConfig);
*
* @namespace Alfresco.module
* @class Alfresco.FlashUpload
* @extends Alfresco.component.Base
*/
(function()
{
   /**
    * YUI Library aliases
    */
   var Dom = YAHOO.util.Dom,
      Element = YAHOO.util.Element,
      KeyListener = YAHOO.util.KeyListener;

   /**
    * FlashUpload constructor.
    *
    * FlashUpload is considered a singleton so constructor should be treated as private,
    * please use Alfresco.component.getFlashUploadInstance() instead.
    *
    * @param htmlId {String} The HTML id of the parent element
    * @return {Alfresco.component.FlashUpload} The new FlashUpload instance
    * @constructor
    * @private
    */
   Alfresco.FlashUpload = function(htmlId)
   {
      Alfresco.FlashUpload.superclass.constructor.call(this, "Alfresco.FlashUpload", htmlId, ["button", "container", "datatable", "datasource", "cookie", "uploader"]);

      this.swf = Alfresco.constants.URL_CONTEXT + "yui/uploader/assets/uploader.swf?dt=" + (new Date()).getTime();
      this.hasRequiredFlashPlayer = Alfresco.util.hasRequiredFlashPlayer(9, 0, 45);
    
      this.fileStore = {};
      this.addedFiles = {};
      this.defaultShowConfig =
      {
         siteId: null,
         containerId: null,
         uploadDirectory: null,
         updateNodeRef: null,
         updateFilename: null,
         mode: this.MODE_SINGLE_UPLOAD,
         filter: [],
         onFileUploadComplete: null,
         overwrite: false,
         thumbnails: null,
         uploadURL: null,
         username: null
      };
      this.suppliedConfig = {};
      this.showConfig = {};
      this.fileItemTemplates = {};
    
      return this;
   };

   YAHOO.extend(Alfresco.FlashUpload, Alfresco.component.Base,
   {
      /**
       * The flash move will dispatch the contentReady event twice,
       * make sure we only react on it twice.
       *
       * @property contentReady
       * @type boolean
       */
      contentReady: false,
    
      /**
       * The user is browsing and adding files to the file list
       *
       * @property STATE_BROWSING
       * @type int
       */
      STATE_BROWSING: 1,

      /**
       * File(s) is being uploaded to the server
       *
       * @property STATE_UPLOADING
       * @type int
       */
      STATE_UPLOADING: 2,

      /**
       * All files are processed and have either failed or been successfully
       * uploaded to the server.
       *
       * @property STATE_FINISHED
       * @type int
       */
      STATE_FINISHED: 3,
    
      /**
       * File failed to upload.
       *
       * @property STATE_FAILURE
       * @type int
       */
      STATE_FAILURE: 4,

      /**
       * File was successfully STATE_SUCCESS.
       *
       * @property STATE_SUCCESS
       * @type int
       */
      STATE_SUCCESS: 5,

       /**
       * The state of which the uploader currently is, where the flow is.
       * STATE_BROWSING > STATE_UPLOADING > STATE_FINISHED
       *
       * @property state
       * @type int
       */
      state: 1,

      /**
       * Stores references and state for each file that is in the file list.
       * The fileId parameter from the YAHOO.widget.Uploader is used as the key
       * and the value is an object that stores the state and references.
       *
       * @property fileStore
       * @type object Used as a hash table with fileId as key and an object
       *       literal as the value.
       *       The object literal is of the form:
       *       {
       *          contentType: {HTMLElement},        // select that holds the chosen contentType for the file.
       *          fileButton: {YAHOO.widget.Button}, // Will be disabled on success or STATE_FAILURE
       *          state: {int},                      // Keeps track if the individual file has been successfully uploaded or failed
       *                                             // (state flow: STATE_BROWSING > STATE_UPLOADING > STATE_SUCCESS or STATE_FAILURE)
       *          progress: {HTMLElement},           // span that is the "progress bar" which is moved during progress
       *          progressInfo: {HTMLElement},       // span that displays the filename and the state
       *          progressPercentage: {HTMLElement}, // span that displays the upload percentage for the individual file
       *          fileName: {string},                // filename
       *          nodeRef: {string}                  // nodeRef if the file has been uploaded successfully
       *       }
       */
      fileStore: null,

      /**
       * The number of successful uploads since upload was clicked.
       *
       * @property noOfSuccessfulUploads
       * @type int
       */
      noOfSuccessfulUploads: 0,

      /**
       * The number of failed uploads since upload was clicked.
       *
       * @property noOfFailedUploads
       * @type int
       */
      noOfFailedUploads: 0,

      /**
       * Remembers what files that how been added to the file list since
       * the show method was called.
       *
       * @property addedFiles
       * @type object
       */
      addedFiles: null,

      /**
       * Shows uploader in single upload mode.
       *
       * @property MODE_SINGLE_UPLOAD
       * @static
       * @type int
       */
      MODE_SINGLE_UPLOAD: 1,

      /**
       * Shows uploader in single update mode.
       *
       * @property MODE_SINGLE_UPDATE
       * @static
       * @type int
       */
      MODE_SINGLE_UPDATE: 2,

      /**
       * Shows uploader in multi upload mode.
       *
       * @property MODE_MULTI_UPLOAD
       * @static
       * @type int
       */
      MODE_MULTI_UPLOAD: 3,
    
      /**
       * The default config for the gui state for the uploader.
       * The user can override these properties in the show() method to use the
       * uploader for both single & multi uploads and single updates.
       *
       * @property defaultShowConfig
       * @type object
       */
      defaultShowConfig: null,

      /**
       * The config passed in to the show method.
       *
       * @property suppliedConfig
       * @type object
       */
      suppliedConfig: null,

      /**
       * The merged result of the defaultShowConfig and the config passed in
       * to the show method.
       *
       * @property showConfig
       * @type object
       */
      showConfig: null,

      /**
       * Contains the upload gui
       *
       * @property panel
       * @type YAHOO.widget.Panel
       */
      panel: null,

      /**
       * YUI class that controls the .swf to open the browser dialog window
       * and transfers the files.
       *
       * @property uploader
       * @type YAHOO.widget.Uploader
       */
      uploader: null,

      /**
       * A property that is set to true after the loaded swf movie has dispatched its swfReady/contentReady event
       *
       * @property uploader Ready
       * @type boolean
       */
      uploaderReady: false,

      /**
       * Used to display the user selceted files and keep track of what files
       * that are selected and should be STATE_FINISHED.
       *
       * @property uploader
       * @type YAHOO.widget.DataTable
       */
      dataTable: null,

      /**
       * HTMLElement of type span that displays the dialog title.
       *
       * @property titleText
       * @type HTMLElement
       */
      titleText: null,

      /**
       * HTMLElement of type span that displays help text for multi uploads.
       *
       * @property multiUploadTip
       * @type HTMLElement
       */
      multiUploadTip: null,

      /**
       * HTMLElement of type span that displays help text for single updates.
       *
       * @property singleUpdateTip
       * @type HTMLElement
       */
      singleUpdateTip: null,

      /**
       * HTMLElement of type span that displays the total upload status
       *
       * @property statusText
       * @type HTMLElement
       */
      statusText: null,

      /**
       * HTMLElement of type radio button for major or minor version
       *
       * @property description
       * @type HTMLElement
       */
      minorVersion: null,

      /**
       * HTMLElement of type textarea for version comment
       *
       * @property description
       * @type HTMLElement
       */
      description: null,

      /**
       * HTMLElement of type div that displays the version input form.
       *
       * @property versionSection
       * @type HTMLElement
       */
      versionSection: null,

      /**
       * HTMLElements of type div that is used to to display a column in a
       * row in the file table list. It is loaded dynamically from the server
       * and then cloned for each row and column in the file list.
       * The fileItemTemplates has the following form:
       * {
       *    left:   HTMLElement to display the left column
       *    center: HTMLElement to display the center column
       *    right:  HTMLElement to display the right column
       * }
       *
       * @property fileItemTemplates
       * @type HTMLElement
       */
      fileItemTemplates: null,

      /**
       * Fired by YUI when parent element is available for scripting.
       * Initial History Manager event registration
       *
       * @method onReady
       */
      onReady: function FlashUpload_onReady()
      {
         // Tell the YUI class where the swf is
         YAHOO.widget.Uploader.SWFURL = this.swf;

         Dom.removeClass(this.id + "-dialog", "hidden");

         // Create the panel
         this.panel = Alfresco.util.createYUIPanel(this.id + "-dialog");

         /**
          * Mac Gecko bugfix for javascript losing connection to the flash uploader movie.
          * To avoid a mac gecko bug where scrollbars are displayed even if the "scrolled"
          * content isn't visible, YUI toggled the "overflow" style property between "hidden"
          * and "visible", this unfortnately also caused the flash movie (which is a child
          * of the toggled element) to get re-instantiated.
          *
          * (https://bugzilla.mozilla.org/show_bug.cgi?id=187435)
          */
         if (this.panel.platform == "mac" && YAHOO.env.ua.gecko)
         {
            /**
             * Remove the already added event listeners that toggles
             * the "overflow" style property for the dialog wrapper.
             */
            var Config = YAHOO.util.Config,
                  p = this.panel;

            if (Config.alreadySubscribed(p.showEvent, p.showMacGeckoScrollbars, p))
            {
               p.showEvent.unsubscribe(p.showMacGeckoScrollbars, p);
            }
            if (Config.alreadySubscribed(p.showEvent, p.hideMacGeckoScrollbars, p))
            {
               p.showEvent.unsubscribe(p.hideMacGeckoScrollbars, p);
            }

            // Remove the toggling of the "overview" style property for the dialog itself.
            p.showMacGeckoScrollbars = function(){};
            p.hideMacGeckoScrollbars = function(){};

            // Add a class for special bug fix css classes
            Dom.addClass(p.element, "reinstantiated-fix");
         }

         // Save a reference to the file row template that is hidden inside the markup
         this.fileItemTemplates.left = Dom.get(this.id + "-left-div");
         this.fileItemTemplates.center = Dom.get(this.id + "-center-div");
         this.fileItemTemplates.right = Dom.get(this.id + "-right-div");

         // Create the YIU datatable object
         this._createEmptyDataTable();

         // Save a reference to the HTMLElement displaying texts so we can alter the texts later
         this.titleText = Dom.get(this.id + "-title-span");
         this.multiUploadTip = Dom.get(this.id + "-multiUploadTip-span");
         this.singleUpdateTip = Dom.get(this.id + "-singleUpdateTip-span");
         this.statusText = Dom.get(this.id + "-status-span");
         this.description = Dom.get(this.id + "-description-textarea");

         // Save reference to version radio so we can reset and get its value later
         this.minorVersion = Dom.get(this.id + "-minorVersion-radioButton");

         // Save a reference to the HTMLElement displaying version input so we can hide or show it
         this.versionSection = Dom.get(this.id + "-versionSection-div");

         // Create and save a reference to the uploadButton so we can alter it later
         this.widgets.uploadButton = Alfresco.util.createYUIButton(this, "upload-button", this.onUploadButtonClick);

         // Create and save a reference to the cancelOkButton so we can alter it later
         this.widgets.cancelOkButton = Alfresco.util.createYUIButton(this, "cancelOk-button", this.onCancelOkButtonClick);

         // Create and save a reference to the uploader so we can call it later
         this.uploader = new YAHOO.widget.Uploader(this.id + "-flashuploader-div", Alfresco.constants.URL_CONTEXT + "themes/" + Alfresco.constants.THEME + "/images/upload-button-sprite.png", true);
         this.uploader.subscribe("fileSelect", this.onFileSelect, this, true);
         this.uploader.subscribe("uploadComplete",this.onUploadComplete, this, true);
         this.uploader.subscribe("uploadProgress",this.onUploadProgress, this, true);
         this.uploader.subscribe("uploadStart",this.onUploadStart, this, true);
         this.uploader.subscribe("uploadCancel",this.onUploadCancel, this, true);
         this.uploader.subscribe("uploadCompleteData",this.onUploadCompleteData, this, true);
         this.uploader.subscribe("uploadError",this.onUploadError, this, true);
         this.uploader.subscribe("contentReady", this.onContentReady, this, true);

         // Register the ESC key to close the dialog
         this.widgets.escapeListener = new KeyListener(document,
         {
            keys: KeyListener.KEY.ESCAPE
         },
         {
            fn: this.onCancelOkButtonClick,
            scope: this,
            correctScope: true
         });
      },

      /**
       * Called when the "wrapping" SWFPlayer-flash movie is loaded
       *
       * @method onContentReady
       */
      onContentReady: function FlashUpload_onContentReady(event)
      {
         this.uploader.enable();
         this.uploader.setAllowMultipleFiles(this.showConfig.mode === this.MODE_MULTI_UPLOAD);
         this.uploader.setFileFilters(this.showConfig.filter);
      },

      /**
       * Show can be called multiple times and will display the uploader dialog
       * in different ways depending on the config parameter.    
       *
       * @method show
       * @param config {object} describes how the upload dialog should be displayed
       * The config object is in the form of:
       * {
       *    siteId: {string},        // site to upload file(s) to
       *    containerId: {string},   // container to upload file(s) to (i.e. a doclib id)
       *    uploadPath: {string},    // directory path inside the component to where the uploaded file(s) should be save
       *    updateNodeRef: {string}, // nodeRef to the document that should be updated
       *    updateFilename: {string},// The name of the file that should be updated, used to display the tip
       *    mode: {int},             // MODE_SINGLE_UPLOAD, MODE_MULTI_UPLOAD or MODE_SINGLE_UPDATE
       *    filter: {array},         // limits what kind of files the user can select in the OS file selector
       *    onFileUploadComplete: null, // Callback after upload
       *    overwrite: false         // If true and in mode MODE_XXX_UPLOAD it tells
       *                             // the backend to overwrite a versionable file with the existing name
       *                             // If false and in mode MODE_XXX_UPLOAD it tells
       *                             // the backend to append a number to the versionable filename to avoid
       *                             // an overwrite and a new version
       * }
       */
      show: function FlashUpload_show(config)
      {
         if (!this.hasRequiredFlashPlayer)
         {
            Alfresco.util.PopupManager.displayPrompt(
            {
               text: this.msg("label.noFlash")
            });
         }

         // Merge the supplied config with default config and check mandatory properties
         this.suppliedConfig = config;
         this.showConfig = YAHOO.lang.merge(this.defaultShowConfig, config);
         if (this.showConfig.uploadDirectory === undefined && this.showConfig.updateNodeRef === undefined)
         {
             throw new Error("An updateNodeRef OR uploadDirectory must be provided");
         }
         if (this.showConfig.uploadDirectory !== null && this.showConfig.uploadDirectory.length === 0)
         {
            this.showConfig.uploadDirectory = "/";
         }

         // Apply the config before it is shown
         this._resetGUI();

         // Apply the config before it is shown
         this._applyConfig();

         // Enable the Esc key listener
         this.widgets.escapeListener.enable();

         // Show the upload panel
         this.panel.show();

         // Need to resize FF in Ubuntu so the button appears
         var swfWrapper = this.id + "-flashuploader-div";
         if (navigator.userAgent && navigator.userAgent.indexOf("Ubuntu") != -1 &&
            YAHOO.env.ua.gecko > 1 && !Dom.hasClass(swfWrapper, "button-fix"))
         {
            Dom.addClass(swfWrapper, "button-fix");
         }

         var swf = Dom.getChildrenBy(Dom.get(this.id + "-flashuploader-div"), function(node)
         {
            return node.tagName.toLowerCase() == "embed" || node.tagName.toLowerCase() == "object";
         })[0];
         swf.focus();
      },

      /**
       * Reset GUI to start state
       *
       * @method _resetGUI
       * @private     
       */
      _resetGUI: function FlashUpload__resetGUI()
      {
         // Reset references and the gui before showing it
         this.state = this.STATE_BROWSING;
         this.noOfFailedUploads = 0;
         this.noOfSuccessfulUploads = 0;
         this.statusText.innerHTML = " ";
         this.description.value = "";
         this.minorVersion.checked = true;
         this.widgets.uploadButton.set("label", this.msg("button.upload"));
         this.widgets.uploadButton.set("disabled", true);
         this.widgets.cancelOkButton.set("label", this.msg("button.cancel"));
         this.widgets.cancelOkButton.set("disabled", false);
      },

      /**
       * Fired by YUI:s DataTable when the added row has been rendered to the data table list.
       *
       * @method onPostRenderEvent     
       */
      onPostRenderEvent: function FlashUpload_onPostRenderEvent()
      {
         // Display the upload button since all files are rendered
         if (this.dataTable.getRecordSet().getLength() > 0)
         {
            this.widgets.uploadButton.set("disabled", false);
         }
         if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            if (this.dataTable.getRecordSet().getLength() === 0)
            {
               this.uploader.enable();
            }
            else
            {
               this.uploader.disable();
            }
         }
      },


      /**
       * Fired by YUI:s DataTable when a row has been added to the data table list.
       * Keeps track of added files.
       *
       * @method onRowDeleteEvent
       * @param event {object} a DataTable "rowDelete" event
       */
      onRowDeleteEvent: function FlashUpload_onRowDeleteEvent(event)
      {
      },

      /**
       * Fired by YIUs Uploader when the user has selected one or more files
       * from the OS:s file dialog window.
       * Adds file that hasn't been selected before to the gui and adjusts the gui.
       *
       * @method onFileSelect
       * @param event {object} an Uploader "fileSelect" event
       */
      onFileSelect: function FlashUpload_onFileSelect(event)
      {
         // Disable upload button until all files have been rendered and added
         this.widgets.uploadButton.set("disabled", true);

         // For each time the user select new files, all the previous selected
         // files also are included in the event.fileList. Make sure we only
         // add files to the table that haven's been added before.
         var newFiles = [],
            data,
            uniqueFileToken;
         for (var i in event.fileList)
         {
            if (this.dataTable.get("renderLoopSize") === 0)
            {
               this.dataTable.set("renderLoopSize", 1);
            }
            data = YAHOO.widget.DataTable._cloneObject(event.fileList[i]);
            uniqueFileToken = this._getUniqueFileToken(data);
            if (!this.addedFiles[uniqueFileToken])
            {
               if (data.size === 0 && !this.addedFiles[uniqueFileToken])
               {
                  Alfresco.util.PopupManager.displayMessage(
                  {
                     text: this.msg("message.zeroByteFileSelected", data.name)
                  });
               }
               else
               {
                  // Add file to file table
                  newFiles.push(data);
               }
               // Since the flash movie allows the user to select one file several
               // times we need to keep track of the selected files by our selves
               this.addedFiles[uniqueFileToken] = uniqueFileToken;
            }
         }
         // Add all files to table
         this.dataTable.addRows(newFiles, 0);
      },

      /**
       * Fired by YIU:s Uploader when transfer has been start for one of the files.
       * Adjusts the gui.
       *
       * @method onUploadStart
       * @param event {object} an Uploader "uploadStart" event
       */
      onUploadStart: function FlashUpload_onUploadStart(event)
      {
         // Get the reference to the files gui components
         var fileInfo = this.fileStore[event.id];

         // Hide the contentType drop down if it wasn't hidden already
         Dom.addClass(fileInfo.contentType, "hidden");

         // Show the progress percentage if it wasn't visible already
         fileInfo.progressPercentage.innerHTML = "0%";
         Dom.removeClass(fileInfo.progressPercentage, "hidden");

         // Make sure we know we are in upload state
         fileInfo.state = this.STATE_UPLOADING;
      },

      /**
       * Fired by YIU:s Uploader during the transfer for one of the files.
       * Adjusts the gui and its progress bars.
       *
       * @method onUploadComplete
       * @param event {object} an Uploader "uploadProgress" event
       */
      onUploadProgress: function FlashUpload_onUploadProgress(event)
      {
         var flashId = event.id;
         var fileInfo = this.fileStore[flashId];

         // Set percentage
         var percentage = event.bytesLoaded / event.bytesTotal;
         fileInfo.progressPercentage.innerHTML = Math.round(percentage * 100) + "%";

         // Set progress position
         var left = (-400 + (percentage * 400));
         Dom.setStyle(fileInfo.progress, "left", left + "px");
      },

      /**
       * Fired by YIU:s Uploader when transfer is complete for one of the files.
       *
       * @method onUploadComplete
       * @param event {object} an Uploader "uploadComplete" event
       */
      onUploadComplete: function FlashUpload_onUploadComplete(event)
      {
         /**
          * Actions taken on a completed upload is handled by the
          * onUploadCompleteData() method instead.
          */
      },

      /**
       * Fired by YIU:s Uploader when transfer is completed for a file.
       * A difference compared to the onUploadComplete() method is that
       * the response body is available in the event.
       * Adjusts the gui and calls for another file to upload if the upload
       * was succesful.
       *
       * @method onUploadCompleteData
       * @param event {object} an Uploader "uploadCompleteData" event
       */
      onUploadCompleteData: function FlashUpload_onUploadCompleteData(event)
      {
         // The individual file has been transfered completely
         // Now adjust the gui for the individual file row
         var fileInfo = this.fileStore[event.id];
         fileInfo.state = this.STATE_SUCCESS;
         fileInfo.fileButton.set("disabled", true);

         // Extract the nodeRef and (possibly changed) fileName from the JSON response
         var oldFileName = fileInfo.fileName;
         var json = Alfresco.util.parseJSON(event.data);
         if (json)
         {
            fileInfo.nodeRef = json.nodeRef;
            fileInfo.fileName = json.fileName;
         }

         // Add the label "Successful" after the filename, updating the fileName from the response
         fileInfo.progressInfo.innerHTML = fileInfo.progressInfo.innerHTML.replace(oldFileName, fileInfo.fileName) + " " + this.msg("label.success");

         // Change the style of the progress bar
         Dom.removeClass(fileInfo.progress, "fileupload-progressSuccess-span");
         Dom.addClass(fileInfo.progress, "fileupload-progressFinished-span");

         // Move the progress bar to "full" progress
         Dom.setStyle(fileInfo.progress, "left", 0 + "px");
         fileInfo.progressPercentage.innerHTML = "100%";
         this.noOfSuccessfulUploads++;

         // Adjust the rest of the gui
         this._updateStatus();
         this._uploadFromQueue(1);
         this._adjustGuiIfFinished();
      },

      /**
       * Fired by YIU:s Uploader when transfer has been cancelled for one of the files.
       * Doesn't do anything.
       *
       * @method onUploadCancel
       * @param event {object} an Uploader "uploadCancel" event
       */
      onUploadCancel: function FlashUpload_onUploadCancel(event)
      {
         // The gui has already been adjusted in the function that caused the cancel
      },

      /**
       * Fired by YIU:s Uploader when transfer failed for one of the files.
       * Adjusts the gui and calls for another file to upload.
       *
       * @method onUploadError
       * @param event {object} an Uploader "uploadError" event
       */
      onUploadError: function FlashUpload_onUploadError(event)
      {
         var fileInfo = this.fileStore[event.id];

         // This sometimes gets called twice, make sure we only adjust the gui once
         if (fileInfo.state !== this.STATE_FAILURE)
         {
            fileInfo.state = this.STATE_FAILURE;

            // Add the failure label to the filename & and as a title attribute
            var key = "label.failure." + event.status,
               msg = Alfresco.util.message(key, this.name);
            if(msg == key)
            {
               msg = Alfresco.util.message("label.failure", this.name);
            }
            fileInfo.progressInfo["innerHTML"] = fileInfo.progressInfo["innerHTML"] + " " + msg;
            fileInfo.progressInfoCell.setAttribute("title", msg);

            // Change the style of the progress bar
            Dom.removeClass(fileInfo.progress, "fileupload-progressSuccess-span");
            Dom.addClass(fileInfo.progress, "fileupload-progressFailure-span");

            // Set the progress bar to "full" progress
            Dom.setStyle(fileInfo.progress, "left", 0 + "px");

            // Disable the remove button
            fileInfo.fileButton.set("disabled", true);

            // Adjust the rest of the gui
            this.noOfFailedUploads++;
            this._updateStatus();
            this._uploadFromQueue(1);
            this._adjustGuiIfFinished();
         }
      },

      /**
       * Called by an anonymous function which that redirects the call to here
       * when the user clicks the file remove button.
       * Removes the file and cancels it if it was being uploaded
       *
       * @method _onFileButtonClickHandler
       * @param flashId {string} an id matching the flash movies fileId
       * @param recordId {int} an id matching a record in the data tables data source
       */
      _onFileButtonClickHandler: function FlashUpload__onFileButtonClickHandler(flashId, recordId)
      {
         /**
          * The file button has been clicked to remove a file.
          * Remove the file from the datatable and all references to it.
          */
         var r = this.dataTable.getRecordSet().getRecord(recordId);
         this.addedFiles[this._getUniqueFileToken(r.getData())] = null;
         this.fileStore[flashId] = null;
         this.dataTable.deleteRow(r);
         if (this.state === this.STATE_BROWSING)
         {
            // Remove the file from the flash movies memory
            this.uploader.removeFile(flashId);
            if (this.dataTable.getRecordSet().getLength() === 0)
            {
               // If it was the last file, disable the gui since no files exist.
               this.widgets.uploadButton.set("disabled", true);
               this.uploader.enable();
            }
         }
         else if (this.state === this.STATE_UPLOADING)
         {
            // Cancel the ongoing upload for the file in the flash movie
            this.uploader.cancel(flashId);

            // Continue to upload documents from the queue
            this._uploadFromQueue(1);

            // Update the rest of the gui
            this._updateStatus();
            this._adjustGuiIfFinished();
         }
      },

      /**
       * Fired when the user clicks the cancel/ok button.
       * The action taken depends on what state the uploader is in.
       * In STATE_BROWSING  - Closes the panel.
       * In STATE_UPLOADING - Cancels current uploads,
       *                      informs the user about how many that were uploaded,
       *                      tells the documentlist to update itself
       *                      and closes the panel.
       * In STATE_FINISHED  - Tells the documentlist to update itself
       *                      and closes the panel.
       *
       * @method onBrowseButtonClick
       * @param event {object} a Button "click" event
       */
      onCancelOkButtonClick: function FlashUpload_onCancelOkButtonClick()
      {
         var message, i;
         if (this.state === this.STATE_BROWSING)
         {   
            // Do nothing (but close the panel, which happens below)
         }
         else if (this.state === this.STATE_UPLOADING)
         {
            this._cancelAllUploads();

            // Inform the user if any files were uploaded before the rest was cancelled
            var noOfUploadedFiles = 0;
            for (i in this.fileStore)
            {
               if (this.fileStore[i] && this.fileStore[i].state === this.STATE_SUCCESS)
               {
                  noOfUploadedFiles++;
               }
            }
            if (noOfUploadedFiles > 0)
            {
               message = YAHOO.lang.substitute(this.msg("message.cancelStatus"),
               {
                  "0": noOfUploadedFiles
               });
            }

            // Tell the document list to refresh itself if present
            YAHOO.Bubbling.fire("metadataRefresh",
            {
               currentPath: this.showConfig.path
            });
         }
         else if (this.state === this.STATE_FINISHED)
         {
            // Tell the document list to refresh itself if present and to
            // highlight the uploaded file (if multi upload was used display the first file)
            var fileName = null, f;
            for (i in this.fileStore)
            {
               f = this.fileStore[i];
               if (f && f.state === this.STATE_SUCCESS)
               {
                  fileName = f.fileName;
                  break;
               }
            }
            if (fileName)
            {
               YAHOO.Bubbling.fire("metadataRefresh",
               {
                  currentPath: this.showConfig.path,
                  highlightFile: fileName
               });
            }
            else
            {
               YAHOO.Bubbling.fire("metadataRefresh",
               {
                  currentPath: this.showConfig.path
               });
            }
         }

         // Hide the panel
         this.panel.hide();
                
         // Disable the Esc key listener
         this.widgets.escapeListener.disable();

         // Remove all files and references for this upload "session"
         this._clear();

         // Inform the user if any files were uploaded before the rest was cancelled
         if (message)
         {
            Alfresco.util.PopupManager.displayPrompt(
            {
               text: message
            });
         }
      },

      /**
       * Fired when the user clicks the upload button.
       * Starts the uploading and adjusts the gui.
       *
       * @method onBrowseButtonClick
       * @param event {object} a Button "click" event
       */
      onUploadButtonClick: function FlashUpload_onUploadButtonClick()
      {
         if (this.state === this.STATE_BROWSING)
         {
            // Change the stat to uploading state and adjust the gui
            var length = this.dataTable.getRecordSet().getLength();
            if (length > 0)
            {
               this.state = this.STATE_UPLOADING;
               this.widgets.uploadButton.set("disabled", true);
               this.uploader.disable();
               this._updateStatus();
            }
            // And start uploading from the queue
            this._uploadFromQueue(2);
         }
      },

      /**
       * Adjust the gui according to the config passed into the show method.
       *
       * @method _applyConfig
       * @private
       */
      _applyConfig: function FlashUpload__applyConfig()
      {
         // Set the panel title
         var title;
         if (this.showConfig.mode === this.MODE_SINGLE_UPLOAD)
         {
            title = this.msg("header.singleUpload");
         }
         else if (this.showConfig.mode === this.MODE_MULTI_UPLOAD)
         {
            title = this.msg("header.multiUpload");
         }
         else if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            title = this.msg("header.singleUpdate");
         }
         this.titleText.innerHTML = title;

         if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            this.singleUpdateTip.innerHTML = YAHOO.lang.substitute(this.msg("label.singleUpdateTip"),
            {
               "0": this.showConfig.updateFilename
            });

            // Display the version input form
            Dom.removeClass(this.versionSection, "hidden");
         }
         else
         {
            // Hide the version input form
            Dom.addClass(this.versionSection, "hidden");
         }

         if (this.showConfig.mode === this.MODE_MULTI_UPLOAD)
         {
            // Show the upload status label, only interesting for multiple files
            Dom.removeClass(this.statusText, "hidden");

            // Show the help label for how to select multiple files
            Dom.removeClass(this.multiUploadTip, "hidden");

            // Hide the help label for other modes
            Dom.addClass(this.singleUpdateTip, "hidden");

            // Make the file list long
            this.dataTable.set("height", "204px", true);
         }
         else
         {
            // Hide the upload status label, only interesting for multiple files
            Dom.addClass(this.statusText, "hidden");

            // Hide the help label for how to select multiple files
            Dom.addClass(this.multiUploadTip, "hidden");

            // Show the help label for single updates
            if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
            {
               // Show the help label for single updates
               Dom.removeClass(this.singleUpdateTip, "hidden");
            }
            else
            {
               // Hide the help label for single updates
               Dom.addClass(this.singleUpdateTip, "hidden");
            }

            // Make the file list short
            this.dataTable.set("height", "40px");
         }

         // Check if flash player existed or if the no flash message is displayed
         var uploaderDiv = Dom.get(this.id + "-flashuploader-div");
         var p = Dom.getFirstChild(uploaderDiv);
         if (p && p.tagName.toLowerCase() == "p")
         {
            // Flash isn't installed, make sure the no flash error message is displayed
            Dom.setStyle(uploaderDiv, "height", "30px");
            Dom.setStyle(uploaderDiv, "height", "200px");
         }
         else
         {
            this._applyUploaderConfig(
            {
               multiSelect: this.showConfig.mode === this.MODE_MULTI_UPLOAD,
               filter: this.showConfig.filter
            }, 0);

         }
      },

      /**
       * Function to try to apply configuration to Flash movie.
       *
       * @method _applyUploaderConfig
       * @param obj {Object} Object literal containing configuration
       * @param attempt {int} Counter for retry attempts
       * @private
       */
      _applyUploaderConfig: function (obj, attempt)
      {
         try
         {
            this.uploader.enable();
            this.uploader.setAllowMultipleFiles(obj.multiSelect);
            this.uploader.setFileFilters(obj.filter);
         }
         catch(e)
         {
            if (attempt == 7)
            {
               Alfresco.util.PopupManager.displayPrompt(
               {
                  title: this.msg("message.flashError.title"),
                  text: this.msg("message.flashError.message"),
                  buttons: [
                  {
                     text: Alfresco.util.message("button.ok"),
                     handler:
                     {
                        fn: function _applyUploaderConfig_onOk(e, p_obj)
                        {
                           this.destroy();
                           p_obj.panel.destroy();
                           var fileUpload = p_obj._disableFlashUploader();
                           if (fileUpload)
                           {
                              fileUpload.show(p_obj.suppliedConfig);
                           }
                        },
                        obj: this
                     },
                     isDefault: true
                  },
                  {
                     text: Alfresco.util.message("button.refreshPage"),
                     handler: function _applyUploaderConfig_onRefreshPage()
                     {
                        window.location.reload(true);
                     }
                  }]
               });
            }
            else
            {
               YAHOO.lang.later(100, this, this._applyUploaderConfig, [obj, ++attempt]);
            }
         }
      },
    
      /**
       * Disables Flash uploader if an error is detected.
       * Possibly a temporary workaround for bugs in SWFObject v1.5
       *
       * @method _disableFlashUploader
       */
      _disableFlashUploader: function FlashUpload__disableFlashUploader()
      {
         var fileUpload = Alfresco.util.ComponentManager.findFirst("Alfresco.FileUpload");
         if (fileUpload)
         {
            fileUpload.hasRequiredFlashPlayer = false;
            fileUpload.onComponentsLoaded();
         }
         return fileUpload;
      },

      /**
       * Helper function to create the data table and its cell formatter.
       *
       * @method _createEmptyDataTable
       * @private
       */
      _createEmptyDataTable: function FlashUpload__createEmptyDataTable()
      {
         /**
          * Save a reference of 'this' so that the formatter below can use it
          * later (since the formatter method gets called with another scope
          * than 'this').
          */
         var myThis = this;

         /**
          * Responsible for rendering the left row in the data table
          *
          * @param el HTMLElement the td element
          * @param oRecord Holds the file data object
          */
         var formatLeftCell = function(el, oRecord, oColumn, oData)
         {
            myThis._formatCellElements(el, oRecord, myThis.fileItemTemplates.left);
         };

         /**
          * Responsible for rendering the center row in the data table
          *
          * @param el HTMLElement the td element
          * @param oRecord Holds the file data object
          */
         var formatCenterCell = function(el, oRecord, oColumn, oData)
         {
            myThis._formatCellElements(el, oRecord, myThis.fileItemTemplates.center);
         };

         /**
          * Responsible for rendering the right row in the data table
          *
          * @param el HTMLElement the td element
          * @param oRecord Holds the file data object
          */
         var formatRightCell = function(el, oRecord, oColumn, oData)
         {
            myThis._formatCellElements(el, oRecord, myThis.fileItemTemplates.right);
         };

         /**
          * Takes a left, center or right column template and looks for expected
          * html components and vcreates yui objects or saves references to
          * them so they can be updated during the upload progress.
          *
          * @param el HTMLElement the td element
          * @param oRecord Holds the file data object
          * @param template the template to display in the column
          */
         this._formatCellElements = function(el, oRecord, template)
         {
            var record = oRecord.getData(),
               flashId = record.id;
            // Set the state for this file(/row) if it hasn't been set
            if (!this.fileStore[flashId])
            {
               this.fileStore[flashId] =
               {
                  state: this.STATE_BROWSING,
                  fileName: record.name,
                  nodeRef: null
               };
            }

            // create an instance from the template and give it a uniqueue id.
            var cell = new Element(el);
            var templateInstance = template.cloneNode(true);
            templateInstance.setAttribute("id", templateInstance.getAttribute("id") + flashId);

            // Save references to elements that will be updated during upload.
            var progress = Dom.getElementsByClassName("fileupload-progressSuccess-span", "span", templateInstance);
            if (progress.length == 1)
            {
               this.fileStore[flashId].progress = progress[0];
            }
            var progressInfo = Dom.getElementsByClassName("fileupload-progressInfo-span", "span", templateInstance);
            if (progressInfo.length == 1)
            {
               // Display the file size in human readable format after the filename.
               var fileInfoStr = record.name + " (" + Alfresco.util.formatFileSize(record.size) + ")";

               // Display the file name and size.
               progressInfo = progressInfo[0];
               this.fileStore[flashId].progressInfo = progressInfo;
               this.fileStore[flashId].progressInfo.innerHTML = fileInfoStr;

               // Save the cell element
               this.fileStore[flashId].progressInfoCell = el;
            }

            // Save a reference to the contentType dropdown so we can find each file's contentType before upload.          
            var contentType = Dom.getElementsByClassName("fileupload-contentType-select", "select", templateInstance);
            if (contentType.length == 1)
            {
               this.fileStore[flashId].contentType = contentType[0];
            }

            // Save references to elements that will be updated during upload.
            var progressPercentage = Dom.getElementsByClassName("fileupload-percentage-span", "span", templateInstance);
            if (progressPercentage.length == 1)
            {
               this.fileStore[flashId].progressPercentage = progressPercentage[0];
            }

            // Create a yui button for the fileButton.
            var fButton = Dom.getElementsByClassName("fileupload-file-button", "button", templateInstance);
            if (fButton.length == 1)
            {
               var fileButton = new YAHOO.widget.Button(fButton[0],
               {
                  type: "button"
               });
               fileButton.subscribe("click", function()
               {
                  this._onFileButtonClickHandler(flashId, oRecord.getId());
               }, this, true);
               this.fileStore[flashId].fileButton = fileButton;
               fileButton.focus();
            }

            // Insert the templateInstance to the column.
            cell.appendChild (templateInstance);
         };

         // Definition of the data table column
         var myColumnDefs = [
            { key: "id", className:"col-left", resizable: false, formatter: formatLeftCell },
            { key: "name", className:"col-center", resizable: false, formatter: formatCenterCell },
            { key: "created", className:"col-right", resizable: false, formatter: formatRightCell }
         ];

         // The data tables underlying data source.
         var myDataSource = new YAHOO.util.DataSource([]);
         myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
         myDataSource.responseSchema =
         {
            fields: ["id", "name", "created", "modified", "type", "size", "progress"]
         };

         /**
          * Create the data table.
          * Set the properties even if they will get changed in applyConfig
          * afterwards, if not set here they will not be changed later.
          */
         YAHOO.widget.DataTable._bStylesheetFallback = !!YAHOO.env.ua.ie;
         var dataTableDiv = Dom.get(this.id + "-filelist-table");
         this.dataTable = new YAHOO.widget.DataTable(dataTableDiv, myColumnDefs, myDataSource,
         {
            scrollable: true,          
            height: "100px", // must be set to something so it can be changed afterwards, when the showconfig options decides if its a sinlge or multi upload
            width: "620px",
            renderLoopSize: 0, // value > 0 results in an error in IE & Safari from YIU2.6.0
            MSG_EMPTY: this.msg("label.noFiles")
         });
         this.dataTable.subscribe("postRenderEvent", this.onPostRenderEvent, this, true);
         this.dataTable.subscribe("rowDeleteEvent", this.onRowDeleteEvent, this, true);
      },

      /**
       * Helper function to create a unique file token from the file data object
       *
       * @method _getUniqueFileToken
       * @param data {object} a file data object describing a file
       * @private
       */
      _getUniqueFileToken: function FlashUpload__getUniqueFileToken(data)
      {
         return data.name + ":" + data.size + ":" + data.cDate + ":" + data.mDate;
      },

      /**
       * Update the status label with the latest information about the upload progress
       *
       * @method _updateStatus
       * @private
       */
      _updateStatus: function FlashUpload__updateStatus()
      {
         // Update the status label with the latest information about the upload progress
         this.statusText.innerHTML = YAHOO.lang.substitute(this.msg("label.uploadStatus"),
         {
            "0" : this.noOfSuccessfulUploads,
            "1" : this.dataTable.getRecordSet().getLength(),
            "2" : this.noOfFailedUploads
         });
      },

      /**
       * Checks if all files are finished (successfully uploaded or failed)
       * and if so adjusts the gui.
       *
       * @method _adjustGuiIfFinished
       * @private
       */
      _adjustGuiIfFinished: function FlashUpload__adjustGuiIfFinished()
      {
         var objComplete =
         {
            successful: [],
            failed: []
         };
         var file = null;
       
         // Go into finished state if all files are finished: successful or failures
         for (var i in this.fileStore)
         {
            file = this.fileStore[i];
            if (file)
            {
               if (file.state == this.STATE_SUCCESS)
               {
                  // Push successful file
                  objComplete.successful.push(
                  {
                     fileName: file.fileName,
                     nodeRef: file.nodeRef
                  });
               }
               else if (file.state == this.STATE_FAILURE)
               {
                  // Push failed file
                  objComplete.failed.push(
                  {
                     fileName: file.fileName
                  });
               }
               else
               {
                  return;
               }
            }
         }
         this.state = this.STATE_FINISHED;
         this.widgets.cancelOkButton.set("label", this.msg("button.ok"));
         this.widgets.uploadButton.set("disabled", true);
       
         var callback = this.showConfig.onFileUploadComplete;
         if (callback && typeof callback.fn == "function")
         {
            // Call the onFileUploadComplete callback in the correct scope
            callback.fn.call((typeof callback.scope == "object" ? callback.scope : this), objComplete, callback.obj);
         }
      },

      /**
       * Starts to upload as many files as specified by noOfUploadsToStart
       * as long as there are files left to upload.
       *
       * @method _uploadFromQueue
       * @param noOfUploadsToStart
       * @private
       */
      _uploadFromQueue: function FlashUpload__uploadFromQueue(noOfUploadsToStart)
      {
         // generate upload POST url
         var url;
         if (this.showConfig.uploadURL === null)
         {
            url = Alfresco.constants.PROXY_URI + "api/upload";
         }
         else
         {
            url = Alfresco.constants.PROXY_URI + this.showConfig.uploadURL;
         }
       
         // Flash does not correctly bind to the session cookies during POST
         // so we manually patch the jsessionid directly onto the URL instead
         url += ";jsessionid=" + YAHOO.util.Cookie.get("JSESSIONID");
       
         // Find files to upload
         var startedUploads = 0,
            length = this.dataTable.getRecordSet().getLength(),
            record, flashId, fileInfo, attributes;
       
         for (var i = 0; i < length && startedUploads < noOfUploadsToStart; i++)
         {
            record = this.dataTable.getRecordSet().getRecord(i);
            flashId = record.getData("id");
            fileInfo = this.fileStore[flashId];
            if (fileInfo.state === this.STATE_BROWSING)
            {
               // Upload has NOT been started for this file, start it now
               fileInfo.state = this.STATE_UPLOADING;
             
               attributes =
               {
                  siteId: this.showConfig.siteId,
                  containerId: this.showConfig.containerId,
                  username: this.showConfig.username
               };
               if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
               {       
                  attributes.updateNodeRef = this.showConfig.updateNodeRef;
                  attributes.majorVersion = !this.minorVersion.checked;
                  attributes.description = this.description.value;
               }
               else
               {
                  attributes.uploadDirectory = this.showConfig.uploadDirectory;
                  attributes.contentType = fileInfo.contentType.options[fileInfo.contentType.selectedIndex].value;
                  attributes.overwrite = this.showConfig.overwrite;
                  if (this.showConfig.thumbnails)
                  {
                     attributes.thumbnails = this.showConfig.thumbnails;
                  }
               }
               this.uploader.upload(flashId, url, "POST", attributes, "filedata");
               startedUploads++;
            }
         }
      },

      /**
       * Cancels all uploads inside the flash movie.
       *
       * @method _cancelAllUploads
       * @private
       */
      _cancelAllUploads: function FlashUpload__cancelAllUploads()
      {
         // Cancel all uploads inside the flash movie
         var length = this.dataTable.getRecordSet().getLength();
         for (var i = 0; i < length; i++)
         {
            var record = this.dataTable.getRecordSet().getRecord(i);
            var flashId = record.getData("id");
            this.uploader.cancel(flashId);
         }
      },

      /**
       * Remove all references to files inside the data table, flash movie
       * and the this class references.
        *
       * @method _clear
       * @private
       */
      _clear: function FlashUpload__clear()
      {
         /**
          * Remove all references to files inside the data table, flash movie
          * and this class's references.
          */
         var length = this.dataTable.getRecordSet().getLength();
         this.addedFiles = {};
         this.fileStore = {};
         this.dataTable.deleteRows(0, length);
         this.uploader.clearFileList();
      }
   });
})();


et html-upload.js
/**
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception.  You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/

/**
* HtmlUpload component.
*
* Popups a YUI panel and displays a filelist and buttons to browse for files
* and upload them. Files can be removed and uploads can be cancelled.
* For single file uploads version input can be submitted.
*
* A multi file upload scenario could look like:
*
* var htmlUpload = Alfresco.getHtmlUploadInstance();
* var multiUploadConfig =
* {
*    siteId: siteId, *    containerId: doclibContainerId,
*    path: docLibUploadPath,
*    filter: [],
*    mode: htmlUpload.MODE_MULTI_UPLOAD,
* }
* this.htmlUpload.show(multiUploadConfig);
*
* @namespace Alfresco
* @class Alfresco.HtmlUpload
* @extends Alfresco.component.Base
*/
(function()
{
   /**
    * YUI Library aliases
    */
   var Dom = YAHOO.util.Dom,
      KeyListener = YAHOO.util.KeyListener;

   /**
    * HtmlUpload constructor.
    *
    * HtmlUpload is considered a singleton so constructor should be treated as private,
    * please use Alfresco.getHtmlUploadInstance() instead.
    *
    * @param htmlId {String} The HTML id of the parent element
    * @return {Alfresco.HtmlUpload} The new HtmlUpload instance
    * @constructor
    * @private
    */
   Alfresco.HtmlUpload = function(htmlId)
   {
      Alfresco.HtmlUpload.superclass.constructor.call(this, "Alfresco.HtmlUpload", htmlId, ["button", "container"]);

      this.defaultShowConfig =
      {
         siteId: null,
         containerId: null,
         uploadDirectory: null,
         updateNodeRef: null,
         updateFilename: null,
         mode: this.MODE_SINGLE_UPLOAD,
         onFileUploadComplete: null,
         overwrite: false,
         thumbnails: null,
         uploadURL: null,
         username: null
      };
      this.showConfig = {};

      return this;
   };

   YAHOO.extend(Alfresco.HtmlUpload, Alfresco.component.Base,
   {
      /**
       * Shows uploader in single upload mode.
       *
       * @property MODE_SINGLE_UPLOAD
       * @static
       * @type int
       */
      MODE_SINGLE_UPLOAD: 1,

      /**
       * Shows uploader in single update mode.
       *
       * @property MODE_SINGLE_UPDATE
       * @static
       * @type int
       */
      MODE_SINGLE_UPDATE: 2,

      /**
       * The default config for the gui state for the uploader.
       * The user can override these properties in the show() method to use the
       * uploader for both single & multi uploads and single updates.
       *
       * @property defaultShowConfig
       * @type object
       */
      defaultShowConfig: null,

      /**
       * The merged result of the defaultShowConfig and the config passed in
       * to the show method.
       *
       * @property defaultShowConfig
       * @type object
       */
      showConfig: null,

      /**
       * HTMLElement of type div that displays the version input form.
       *
       * @property versionSection
       * @type HTMLElement
       */
      versionSection: null,

      /**
       * Fired by YUI when parent element is available for scripting.
       * Initial History Manager event registration
       *
       * @method onReady
       */
      onReady: function HtmlUpload_onReady()
      {
         Dom.removeClass(this.id + "-dialog", "hidden");

         // Create the panel
         this.widgets.panel = Alfresco.util.createYUIPanel(this.id + "-dialog");

         // Save a reference to the HTMLElement displaying texts so we can alter the texts later
         this.widgets.titleText = Dom.get(this.id + "-title-span");
         this.widgets.singleUploadTip = Dom.get(this.id + "-singleUploadTip-span");
         this.widgets.singleUpdateTip = Dom.get(this.id + "-singleUpdateTip-span");

         // Save references to hidden fields so we can set them later
         this.widgets.filedata = Dom.get(this.id + "-filedata-file");
         this.widgets.filedata.contentEditable = false;
         this.widgets.siteId = Dom.get(this.id + "-siteId-hidden");
         this.widgets.containerId = Dom.get(this.id + "-containerId-hidden");
         this.widgets.username = Dom.get(this.id + "-username-hidden");
         this.widgets.updateNodeRef = Dom.get(this.id + "-updateNodeRef-hidden");
         this.widgets.uploadDirectory = Dom.get(this.id + "-uploadDirectory-hidden");
         this.widgets.overwrite = Dom.get(this.id + "-overwrite-hidden");
         this.widgets.thumbnails = Dom.get(this.id + "-thumbnails-hidden");
         this.widgets.successCallback = Dom.get(this.id + "-successCallback-hidden");
         this.widgets.successScope = Dom.get(this.id + "-successScope-hidden");
         this.widgets.failureCallback = Dom.get(this.id + "-failureCallback-hidden");
         this.widgets.failureScope = Dom.get(this.id + "-failureScope-hidden");

         // Save reference to version section elements so we can set its values later
         this.widgets.description = Dom.get(this.id + "-description-textarea");
         this.widgets.minorVersion = Dom.get(this.id + "-minorVersion-radioButton");
         this.widgets.versionSection = Dom.get(this.id + "-versionSection-div");

         // Create and save a reference to the buttons so we can alter them later
         this.widgets.uploadButton = Alfresco.util.createYUIButton(this, "upload-button", null,
         {
            type: "submit"
         });
         this.widgets.cancelButton = Alfresco.util.createYUIButton(this, "cancel-button", this.onCancelButtonClick);
        
         // Configure the forms runtime
         var form = new Alfresco.forms.Form(this.id + "-htmlupload-form");
         this.widgets.form = form;

         // Title is mandatory
         form.addValidation(this.id + "-filedata-file", Alfresco.forms.validation.mandatory, null, "change");

         // The ok button is the submit button, and it should be enabled when the form is ready
         form.setShowSubmitStateDynamically(true, false);
         form.setSubmitElements(this.widgets.uploadButton);
         form.doBeforeFormSubmit =
         {
            fn: function()
            {
               this.widgets.uploadButton.set("disabled", true);
               this.widgets.cancelButton.set("disabled", true);
               this.widgets.panel.hide();
               this.widgets.feedbackMessage = Alfresco.util.PopupManager.displayMessage(
               {
                  text: Alfresco.util.message("message.uploading", this.name),
                  spanClass: "wait",
                  displayTime: 0
               });
            },
            obj: null,
            scope: this
         };

         // Submit as an ajax submit (not leave the page), in json format
         form.setAJAXSubmit(true, {});

         // We're in a popup, so need the tabbing fix
         form.applyTabFix();
         form.init();

         // Register the ESC key to close the dialog
         this.widgets.escapeListener = new KeyListener(document,
         {
            keys: KeyListener.KEY.ESCAPE
         },
         {
            fn: this.onCancelButtonClick,
            scope: this,
            correctScope: true
         });
      },

      /**
       * Show can be called multiple times and will display the uploader dialog
       * in different ways depending on the config parameter.
       *
       * @method show
       * @param config {object} describes how the upload dialog should be displayed
       * The config object is in the form of:
       * {
       *    siteId: {string},        // site to upload file(s) to
       *    containerId: {string},   // container to upload file(s) to (i.e. a doclib id)
       *    uploadPath: {string},    // directory path inside the component to where the uploaded file(s) should be save
       *    updateNodeRef: {string}, // nodeRef to the document that should be updated
       *    updateFilename: {string},// The name of the file that should be updated, used to display the tip
       *    mode: {int},             // MODE_SINGLE_UPLOAD or MODE_SINGLE_UPDATE
       *    filter: {array},         // limits what kind of files the user can select in the OS file selector
       *    onFileUploadComplete: null, // Callback after upload
       *    overwrite: false         // If true and in mode MODE_XXX_UPLOAD it tells
       *                             // the backend to overwrite a versionable file with the existing name
       *                             // If false and in mode MODE_XXX_UPLOAD it tells
       *                             // the backend to append a number to the versionable filename to avoid
       *                             // an overwrite and a new version
       * }
       */
      show: function HtmlUpload_show(config)
      {
         // Merge the supplied config with default config and check mandatory properties
         this.showConfig = YAHOO.lang.merge(this.defaultShowConfig, config);
         if (this.showConfig.uploadDirectory === undefined && this.showConfig.updateNodeRef === undefined)
         {
             throw new Error("An updateNodeRef OR uploadDirectory must be provided");
         }
         if (this.showConfig.uploadDirectory !== null && this.showConfig.uploadDirectory.length === 0)
         {
            this.showConfig.uploadDirectory = "/";
         }

         // Enable the Esc key listener
         this.widgets.escapeListener.enable();

         this._showPanel();
      },

      /**
       * Called when a file has been successfully uploaded
       * Informs the user and reloads the doclib.
       *
       * @method onUploadSuccess
       */
      onUploadSuccess: function HtmlUpload_onUploadSuccess(response)
      {
         // Hide the current message display
         this.widgets.feedbackMessage.destroy();

         // Tell the document list to refresh itself if present
         var fileName = response.fileName ? response.fileName : this.widgets.filedata.value;
         YAHOO.Bubbling.fire("metadataRefresh",
         {
            currentPath: this.showConfig.path,
            highlightFile: fileName
         });
             
         // Todo see if the nodeRef can be added to the list
         var objComplete =
         {
            successful: [{nodeRef: response.nodeRef, fileName: fileName}]
         };

         var callback = this.showConfig.onFileUploadComplete;
         if (callback && typeof callback.fn == "function")
         {
            // Call the onFileUploadComplete callback in the correct scope
            callback.fn.call((typeof callback.scope == "object" ? callback.scope : this), objComplete, callback.obj);
         }
      },

      /**
       * Called when a file failed to be uploaded
       * Informs the user.
       *
       * @method onUploadFailure
       */
      onUploadFailure: function HtmlUpload_onUploadFailure(e)
      {
         // Hide the current message display
         this.widgets.feedbackMessage.destroy();

         // Inform user that the upload failed
         var key = "message.failure." + event.status.code,
            text = Alfresco.util.message(key, this.name);
         if(text == key)
         {
            text = event.status.code ? event.status.code : Alfresco.util.message("message.failure", this.name);
         }
         Alfresco.util.PopupManager.displayPrompt(
         {
            title: Alfresco.util.message("message.failure", this.name),
            text: text
         });
      },

      /**
       * Fired when the user clicks the cancel button.
       * Closes the panel.
       *
       * @method onCancelButtonClick
       * @param event {object} a Button "click" event
       */
      onCancelButtonClick: function HtmlUpload_onCancelButtonClick()
      {
         // Disable the Esc key listener
         this.widgets.escapeListener.disable();

         // Hide the panel
         this.widgets.panel.hide();
      },

      /**
       * Adjust the gui according to the config passed into the show method.
       *
       * @method _applyConfig
       * @private
       */
      _applyConfig: function HtmlUpload__applyConfig()
      {
         // Set the panel title
         var title;
         if (this.showConfig.mode === this.MODE_SINGLE_UPLOAD)
         {
            title = Alfresco.util.message("header.singleUpload", this.name);
         }
         else if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            title = Alfresco.util.message("header.singleUpdate", this.name);
         }
         this.widgets.titleText.innerHTML = title;

         if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            var tip = Alfresco.util.message("label.singleUpdateTip", this.name,
            {
               "0": this.showConfig.updateFilename
            });
            this.widgets.singleUpdateTip.innerHTML = tip;

            // Display the version input form
            Dom.removeClass(this.widgets.versionSection, "hidden");
         }
         else
         {
            // Hide the version input form
            Dom.addClass(this.widgets.versionSection, "hidden");
         }

         // Show the help label for single updates
         if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            // Show the help label for single updates
            Dom.removeClass(this.widgets.singleUpdateTip, "hidden");
            Dom.addClass(this.widgets.singleUploadTip, "hidden");
         }
         else
         {
            // Show the help label for single uploads
            Dom.removeClass(this.widgets.singleUploadTip, "hidden");
            Dom.addClass(this.widgets.singleUpdateTip, "hidden");
         }

         this.widgets.cancelButton.set("disabled", false);
         this.widgets.filedata.value = null;
         this.widgets.uploadButton.set("disabled", true);

         // Set the forms action url
         var formEl = Dom.get(this.id + "-htmlupload-form");
         if (this.showConfig.uploadURL === null)
         {
            // The .html suffix is required - it is not possible to do a multipart post using an ajax call.
            // So it has to be a FORM submit, to make it feel like an ajax call a a hidden iframe is used.
            // Since the component still needs to be called when the upload is finished, the script returns
            // an html template with SCRIPT tags inside that which calls the component that triggered it.
            formEl.action = Alfresco.constants.PROXY_URI + "api/upload.html";
         }
         else
         {
            formEl.action = Alfresco.constants.PROXY_URI + this.showConfig.uploadURL;
         }

         // Set the hidden parameters
         this.widgets.siteId.value = this.showConfig.siteId;
         this.widgets.containerId.value = this.showConfig.containerId;
         this.widgets.username.value = this.showConfig.username;
         if (this.showConfig.mode === this.MODE_SINGLE_UPDATE)
         {
            this.widgets.updateNodeRef.value = this.showConfig.updateNodeRef;
            this.widgets.uploadDirectory.value = "";
            this.widgets.overwrite.value = "";
            this.widgets.thumbnails.value = "";
         }
         else
         {
            this.widgets.updateNodeRef.value = "";
            this.widgets.uploadDirectory.value = this.showConfig.uploadDirectory;
            this.widgets.overwrite.value = this.showConfig.overwrite;
            this.widgets.thumbnails.value = this.showConfig.thumbnails;
         }
         var success = "window.parent.Alfresco.util.ComponentManager.get('" + this.id + "')";
         this.widgets.successCallback.value = success + ".onUploadSuccess";
         this.widgets.successScope.value = success;

         var failure = "window.parent.Alfresco.util.ComponentManager.get('" + this.id + "')";
         this.widgets.failureCallback.value = failure + ".onUploadFailure";
         this.widgets.failureScope.value = failure;
      },

      /**
       * Prepares the gui and shows the panel.
       *
       * @method _showPanel
       * @private
       */
      _showPanel: function HtmlUpload__showPanel()
      {
         // Reset references and the gui before showing it
         this.widgets.description.value = "";
         this.widgets.minorVersion.checked = true;

         // Apply the config before it is showed
         this._applyConfig();

         // Show the upload panel
         this.widgets.panel.show();
      }
   });
})();
et file-upload.js
/**
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception.  You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/

/**
* FileUpload component.
*
* Checks if Flash is installed or not and uses either the FlashUpload or
* HtmlUpload component.
*
* A multi file upload scenario could look like:
*
* var fileUpload = Alfresco.getFileUploadInstance();
* var multiUploadConfig =
* {
*    siteId: siteId,
*    containerId: doclibContainerId,
*    path: docLibUploadPath,
*    filter: [],
*    mode: fileUpload.MODE_MULTI_UPLOAD,
* }
* this.fileUpload.show(multiUploadConfig);
*
* If flash is installed it would use the FlashUpload component in multi upload mode
* If flash isn't installed it would use the HtmlUpload in single upload mode instead.
*
* @namespace Alfresco.component
* @class Alfresco.FileUpload
* @extends Alfresco.component.Base
*/
(function()
{
   /**
    * FileUpload constructor.
    *
    * FileUpload is considered a singleton so constructor should be treated as private,
    * please use Alfresco.getFileUploadInstance() instead.
    *
    * @param {string} htmlId The HTML id of the parent element
    * @return {Alfresco.FileUpload} The new FileUpload instance
    * @constructor
    * @private
    */
   Alfresco.FileUpload = function(instanceId)
   {
      var instance = Alfresco.util.ComponentManager.get(instanceId);
      if (instance !== null)
      {
         throw new Error("An instance of Alfresco.FileUpload already exists.");
      }

      // Determine minimum required Flash capability
      this.hasRequiredFlashPlayer = !Alfresco.util.getVar("noflash") && Alfresco.util.hasRequiredFlashPlayer(9, 0, 45);

      Alfresco.FileUpload.superclass.constructor.call(this, "Alfresco.FileUpload", instanceId);

      return this;
   };

   YAHOO.extend(Alfresco.FileUpload, Alfresco.component.Base,
   {
      /**
       * The uploader instance
       *
       * @property uploader
       * @type Alfresco.FlashUpload or Alfresco.HtmlUpload
       */
      uploader: null,

      /**
       * Shows uploader in single upload mode.
       *
       * @property MODE_SINGLE_UPLOAD
       * @static
       * @type int
       */
      MODE_SINGLE_UPLOAD: 1,

      /**
       * Shows uploader in single update mode.
       *
       * @property MODE_SINGLE_UPDATE
       * @static
       * @type int
       */
      MODE_SINGLE_UPDATE: 2,

      /**
       * Shows uploader in multi upload mode.
       *
       * @property MODE_MULTI_UPLOAD
       * @static
       * @type int
       */
      MODE_MULTI_UPLOAD: 3,

      /**
       * The default config for the gui state for the uploader.
       * The user can override these properties in the show() method to use the
       * uploader for both single & multi uploads and single updates.
       *
       * @property defaultShowConfig
       * @type object
       */
      defaultShowConfig:
      {
         siteId: null,
         containerId: null,
         uploadDirectory: null,
         updateNodeRef: null,
         updateFilename: null,
         mode: this.MODE_SINGLE_UPLOAD,
         filter: [],
         onFileUploadComplete: null,
         overwrite: false,
         thumbnails: null,
         htmlUploadURL: null,
         flashUploadURL: null,
         username: null
      },

      /**
       * The merged result of the defaultShowConfig and the config passed in
       * to the show method.
       *
       * @property defaultShowConfig
       * @type object
       */
      showConfig: {},

      /**
       * Fired by YUILoaderHelper when required component script files have
       * been loaded into the browser.
       *
       * @method onComponentsLoaded
       */
      onComponentsLoaded: function FU_onComponentsLoaded()
      {
         // Create the appropriate uploader component
         var uploadType = this.hasRequiredFlashPlayer ? "Alfresco.FlashUpload" : "Alfresco.HtmlUpload",
            uploadInstance = Alfresco.util.ComponentManager.findFirst(uploadType);
        
         if (uploadInstance)
         {
            this.uploader = uploadInstance;
         }
         else
         {
            throw new Error("No instance of uploader type '" + uploadType + "' exists.");           
         }
      },

      /**
       * Show can be called multiple times and will display the uploader dialog
       * in different ways depending on the config parameter.
       *
       * @method show
       * @param config {object} describes how the upload dialog should be displayed
       * The config object is in the form of:
       * {
       *    siteId: {string},        // site to upload file(s) to
       *    containerId: {string},   // container to upload file(s) to (i.e. a doclib id)
       *    uploadPath: {string},    // directory path inside the component to where the uploaded file(s) should be save
       *    updateNodeRef: {string}, // nodeRef to the document that should be updated
       *    updateFilename: {string},// The name of the file that should be updated, used to display the tip
       *    mode: {int},             // MODE_SINGLE_UPLOAD, MODE_MULTI_UPLOAD or MODE_SINGLE_UPDATE
       *    filter: {array},         // limits what kind of files the user can select in the OS file selector
       *    onFileUploadComplete: null, // Callback after upload
       *    overwrite: false         // If true and in mode MODE_XXX_UPLOAD it tells
       *                             // the backend to overwrite a versionable file with the existing name
       *                             // If false and in mode MODE_XXX_UPLOAD it tells
       *                             // the backend to append a number to the versionable filename to avoid
       *                             // an overwrite and a new version
       *    htmlUploadURL: null,     // Overrides default url to post the file to if the html version is used
       *    flashUploadURL: null,    // Overrides default url to post the files to if the flash version is used
       *    username: null           // If a file should be associated with a user
       * }
       */
      show: function FU_show(config)
      {
         // Merge the supplied config with default config and check mandatory properties
         this.showConfig = YAHOO.lang.merge(this.defaultShowConfig, config);

         // If flash isn't installed multi upload mode isn't supported
         if (!this.hasRequiredFlashPlayer && this.showConfig.mode == this.MODE_MULTI_UPLOAD)
         {
            this.showConfig.mode = this.MODE_SINGLE_UPLOAD;
         }

         if (this.hasRequiredFlashPlayer)
         {
            this.showConfig.uploadURL = this.showConfig.flashUploadURL;
         }
         else
         {
            this.showConfig.uploadURL = this.showConfig.htmlUploadURL;
         }

         // Let the uploader instance show itself
         this.uploader.show(this.showConfig);
      }
   });
})();

Alfresco.getFileUploadInstance = function()
{
   var instanceId = "alfresco-fileupload-instance";
   return Alfresco.util.ComponentManager.get(instanceId) || new Alfresco.FileUpload(instanceId);
};

s'il y a d'autres fichiers que je dois fournir dites  moi

rguinot
Confirmed Champ
Confirmed Champ
Resumons la situation :

- vous louez un appartement
- vous payez un prestataire pour peindre une pièce de l'appartement
- vous vous plaignez ensuite au propriétaire que la peinture est mal faite

j'ai bon ?

Ne serait il pas plus simple de vous rapprocher du prestataire pour qu'il corrige son code spécifique ?
D'autre part, l'utilité de ce code spécifique n'apparait pas claire étant donné que l'upload multiple existe déja en standard.