All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.org.richfaces.fileupload.js Maven / Gradle / Ivy

There is a newer version: 5.0.0.Alpha3
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
(function($, rf) {

    rf.ui = rf.ui || {};

    rf.ui.FileUpload = function(id, options) {
        this.id = id;
        this.items = [];
        this.submitedItems = [];

        $.extend(this, options);
        if (this.acceptedTypes) {
            this.acceptedTypes = $.trim(this.acceptedTypes).toUpperCase().split(/\s*,\s*\.?/);
        }
        if (this.maxFilesQuantity) {
            this.maxFilesQuantity = parseInt($.trim(this.maxFilesQuantity));
        }
        this.element = $(this.attachToDom());
        this.form = this.element.parents("form:first");
        var header = this.element.children(".rf-fu-hdr:first");
        var leftButtons = header.children(".rf-fu-btns-lft:first");
        this.addButton = leftButtons.children(".rf-fu-btn-add:first");
        this.uploadButton = this.addButton.next();
        this.clearButton = leftButtons.next().children(".rf-fu-btn-clr:first");
        this.inputContainer = this.addButton.find(".rf-fu-inp-cntr:first");
        this.input = this.inputContainer.children("input");
        this.list = header.next();
        this.element.bind('dragenter', function(e) {e.stopPropagation(); e.preventDefault();});
        this.element.bind('dragover', function(e) {e.stopPropagation(); e.preventDefault();});
        this.element.bind('drop', $.proxy(this.__addItemsFromDrop, this));

        this.hiddenContainer = this.list.next();
        this.cleanInput = this.input.clone();
        this.addProxy = $.proxy(this.__addItems, this);
        this.input.change(this.addProxy);
        this.addButton.mousedown(pressButton).mouseup(unpressButton).mouseout(unpressButton);
        this.uploadButton.click($.proxy(this.__startUpload, this)).mousedown(pressButton)
            .mouseup(unpressButton).mouseout(unpressButton);
        this.clearButton.click($.proxy(this.__removeAllItems, this)).mousedown(pressButton)
            .mouseup(unpressButton).mouseout(unpressButton);
        if (this.onfilesubmit) {
            rf.Event.bind(this.element, "onfilesubmit", new Function("event", this.onfilesubmit));
        }
        if (this.ontyperejected) {
            rf.Event.bind(this.element, "ontyperejected", new Function("event", this.ontyperejected));
        }
        if (this.onsizerejected) {
            rf.Event.bind(this.element, "onsizerejected", new Function("event", this.onsizerejected));
        }
        if (this.onuploadcomplete) {
            rf.Event.bind(this.element, "onuploadcomplete", new Function("event", this.onuploadcomplete));
        }
        if (this.onclear) {
            rf.Event.bind(this.element, "onclear", new Function("event", this.onclear));
        }
        if (this.onfileselect) {
            rf.Event.bind(this.element, "onfileselect", new Function("event", this.onfileselect));
        }
    };

    var UID = "rf_fu_uid";
    var UID_ALT = "rf_fu_uid_alt";
    var FAKE_PATH = "C:\\fakepath\\";
    var ITEM_HTML = '
' + '' + '
'; var ITEM_STATE = { NEW: "new", UPLOADING: "uploading", DONE: "done", SIZE_EXCEEDED: "sizeExceeded", STOPPED: "stopped", SERVER_ERROR_PROCESS: "serverErrorProc", SERVER_ERROR_UPLOAD: "serverErrorUp" }; var pressButton = function(event) { $(this).children(":first").css("background-position", "3px 3px").css("padding", "4px 4px 2px 22px"); }; var unpressButton = function(event) { $(this).children(":first").css("background-position", "2px 2px").css("padding", "3px 5px 3px 21px"); }; rf.BaseComponent.extend(rf.ui.FileUpload); function TypeRejectedException(fileName) { this.name = "TypeRejectedException"; this.message = "The type of file " + fileName + " is not accepted"; this.fileName = fileName; } $.extend(rf.ui.FileUpload.prototype, (function () { return { name: "FileUpload", doneLabel: "Done", sizeExceededLabel: "File size is exceeded", stoppedLabel: "", serverErrorProcLabel: "Server error: error in processing", serverErrorUpLabel: "Server error: upload failed", clearLabel: "Clear", deleteLabel: "Delete", __addFiles : function(files) { var context = { acceptedFileNames: [], rejectedFileNames: [] }; if (files) { for (var i = 0 ; i < files.length; i++) { this.__tryAddItem(context, files[i]); if (this.maxFilesQuantity && this.__getTotalItemCount() >= this.maxFilesQuantity) { this.addButton.hide(); break; } } } else { var fileName = this.input.val(); this.__tryAddItem(context, fileName); } if (context.rejectedFileNames.length > 0) { rf.Event.fire(this.element, "ontyperejected", context.rejectedFileNames.join(',')); } if (this.immediateUpload) { this.__startUpload(); } }, __addItems : function() { this.__addFiles(this.input.prop("files")); // replace input with a copy, IE 10 doesn't allow clearing just the value (this.input.val("")) this.input.replaceWith(this.input.clone(true)); this.input = this.inputContainer.children("input"); }, __addItemsFromDrop: function(dropEvent) { dropEvent.stopPropagation(); dropEvent.preventDefault(); if (this.maxFilesQuantity && this.__getTotalItemCount() >= this.maxFilesQuantity) { return; } this.__addFiles(dropEvent.originalEvent.dataTransfer.files); }, __tryAddItem: function(context, file) { if (this.maxFileSize && file.size > this.maxFileSize) { rf.Event.fire(this.element, "onsizerejected", file); return; } try { if (this.__addItem(file)) { context.acceptedFileNames.push(file.name); } } catch (e) { if (e instanceof TypeRejectedException) { context.rejectedFileNames.push(file.name); } else { throw e; } } }, __addItem: function(file) { var fileName = file.name; if (!navigator.platform.indexOf("Win")) { fileName = fileName.match(/[^\\]*$/)[0]; } else { if (!fileName.indexOf(FAKE_PATH)) { fileName = fileName.substr(FAKE_PATH.length); } else { fileName = fileName.match(/[^\/]*$/)[0]; } } if (this.__accept(fileName) && (!this.noDuplicate || !this.__isFileAlreadyAdded(fileName))) { var item = new Item(this, file); this.list.append(item.getJQuery()); this.items.push(item); this.__updateButtons(); rf.Event.fire(this.element, "onfileselect", fileName); return true; } return false; }, __removeItem: function(item) { var inItems = $.inArray(item, this.items), inSItems = $.inArray(item, this.submitedItems); if (inItems != -1) { this.items.splice(inItems, 1); } if (inSItems != -1) { this.submitedItems.splice(inSItems, 1); } this.__updateButtons(); rf.Event.fire(this.element, "onclear", [item.model]); }, __removeAllItems: function(item) { var itemsRemoved = []; for (var i = 0; i < this.submitedItems.length; i++) { itemsRemoved.push(this.submitedItems[i].model); } for (var i = 0; i < this.items.length; i++) { itemsRemoved.push(this.items[i].model); } this.list.empty(); this.items.splice(0, this.items.length); this.submitedItems.splice(0, this.submitedItems.length); this.__updateButtons(); rf.Event.fire(this.element, "onclear", itemsRemoved); }, __updateButtons: function() { if (!this.loadableItem && this.list.children(".rf-fu-itm").size()) { if (this.items.length) { this.uploadButton.css("display", "inline-block"); } else { this.uploadButton.hide(); } this.clearButton.css("display", "inline-block"); } else { this.uploadButton.hide(); this.clearButton.hide(); } if (this.maxFilesQuantity && this.__getTotalItemCount() >= this.maxFilesQuantity) { this.addButton.hide(); } else { this.addButton.css("display", "inline-block"); } }, __startUpload: function() { if (!this.items.length) { this.__finishUpload(); return; } rf.setGlobalStatusNameVariable(this.status); this.loadableItem = this.items.shift(); this.__updateButtons(); this.loadableItem.startUploading(); }, __accept: function(fileName) { fileName = fileName.toUpperCase(); var result = !this.acceptedTypes; for (var i = 0; !result && i < this.acceptedTypes.length; i++) { var extension = this.acceptedTypes[i]; if (extension === "" && fileName.indexOf(".") < 0) { // no extension result = true; } else { result = fileName.indexOf(extension, fileName.length - extension.length) !== -1; } } if (!result) { throw new TypeRejectedException(fileName); } return result; }, __isFileAlreadyAdded: function(fileName) { var result = false; for (var i = 0; !result && i < this.items.length; i++) { result = this.items[i].model.name == fileName; } result = result || (this.loadableItem && this.loadableItem.model.name == fileName); for (var i = 0; !result && i < this.submitedItems.length; i++) { result = this.submitedItems[i].model.name == fileName; } return result; }, __getTotalItemCount : function() { return this.__getItemCountByState(this.items, ITEM_STATE.NEW) + this.__getItemCountByState(this.submitedItems, ITEM_STATE.DONE); }, __getItemCountByState : function(items) { var statuses = {}; var s = 0; for ( var i = 1; i < arguments.length; i++) { statuses[arguments[i]] = true; } for ( var i = 0; i < items.length; i++) { if (statuses[items[i].model.state]) { s++; } } return s; }, __finishUpload : function() { this.loadableItem = null; this.__updateButtons(); var items = []; for (var i = 0; i < this.submitedItems.length; i++) { items.push(this.submitedItems[i].model); } for (var i = 0; i < this.items.length; i++) { items.push(this.items[i].model); } rf.Event.fire(this.element, "onuploadcomplete", items); } }; })()); var Item = function(fileUpload, file) { this.fileUpload = fileUpload; this.model = {name: file.name, state: ITEM_STATE.NEW, file: file}; }; $.extend(Item.prototype, { __createProgressBar: function(item, facet) { var $pb = facet.find(".rf-pb"); if ($pb.length) { // custom progressBar return { pb: RichFaces.component($pb), prepare: function() { item.find(".rf-fu-itm-lft").append($pb.detach()); }, setValue: function(progress) { var max = parseFloat(this.pb.maxValue), min = parseFloat(this.pb.minValue), relativeProgress = progress*(max - min)/100 + min; this.pb.setValue(relativeProgress); }, cleanUp: function() { facet.append($pb.detach()); }, show: function() { $pb.show(); }, hide: function() { $pb.hide(); } } } var progressElement = '
' + '
' + '
'; return { prepare: function() { item.find(".rf-fu-itm-lft").append($(progressElement)); this.element = item.find(".progress-bar"); this.label = this.element.find("span"); }, setValue: function(progress) { this.label.html( progress + " %" ); this.element.attr("aria-valuenow", progress); this.element.css("width", progress + "%"); }, cleanUp: function() { }, show: function() { this.element.parent().show(); }, hide: function() { this.element.parent().hide(); } } }, getJQuery: function() { this.element = $(ITEM_HTML); var leftArea = this.element.children(".rf-fu-itm-lft:first"); this.label = leftArea.children(".rf-fu-itm-lbl:first"); this.state = this.label.nextAll(".rf-fu-itm-st:first"); this.link = leftArea.next().children("a"); this.label.html(this.model.name); this.link.html(this.fileUpload["deleteLabel"]); this.link.click($.proxy(this.removeOrStop, this)); return this.element; }, removeOrStop: function() { this.element.remove(); this.fileUpload.__removeItem(this); }, startUploading: function() { this.progressBarFacet = this.__createProgressBar(this.element, this.fileUpload.hiddenContainer); this.progressBarFacet.prepare(); this.progressBarFacet.hide(); this.state.css("display", "block"); this.progressBarFacet.setValue(0); this.progressBarFacet.show(); this.link.html(""); this.model.state = ITEM_STATE.UPLOADING; this.uid = Math.random(); var formData = new FormData(), fileName = this.model.file.name, viewState = this.fileUpload.form.find("input[name='javax.faces.ViewState']").val(); formData.append(this.fileUpload.form[0].id, this.fileUpload.form[0].id); formData.append("javax.faces.ViewState", viewState); formData.append(this.fileUpload.id, this.model.file); var originalAction = this.fileUpload.form.attr("action"), delimiter = originalAction.indexOf("?") == -1 ? "?" : "&", encodedId = encodeURIComponent(this.fileUpload.id), newAction = originalAction + delimiter + UID + "=" + this.uid + "&javax.faces.partial.ajax=true" + "&javax.faces.source=" + encodedId + "&javax.faces.partial.execute=" + encodedId + "&org.richfaces.ajax.component=" + encodedId + "&javax.faces.ViewState=" + encodeURIComponent(viewState); if (jsf.getClientWindow && jsf.getClientWindow()) { newAction += "&javax.faces.ClientWindow=" + encodeURIComponent(jsf.getClientWindow()); }; var eventHandler = function(handlerCode) { if (handlerCode) { var safeHandlerCode = "try {" + handlerCode + "} catch (e) {" + "window.RichFaces.log.error('Error in method execution: ' + e.message)" + "}"; return new Function("event", safeHandlerCode); } } this.onerror = eventHandler(this.fileUpload.onerror); this.xhr = new XMLHttpRequest(); this.xhr.open('POST', newAction, true); this.xhr.setRequestHeader('Faces-Request', 'partial/ajax'); this.xhr.upload.onprogress = $.proxy(function(e) { if (e.lengthComputable) { var progress = Math.floor((e.loaded / e.total) * 100); this.progressBarFacet.setValue(progress); } }, this); this.xhr.upload.onerror = $.proxy(function (e) { this.fileUpload.loadableItem = null; this.finishUploading(ITEM_STATE.SERVER_ERROR_UPLOAD); }, this); this.xhr.onload = $.proxy(function (e) { switch (e.target.status) { case 413: responseStatus = ITEM_STATE.SIZE_EXCEEDED; break; case 200: responseStatus = ITEM_STATE.DONE; break; default: // 500 - error in processing parts responseStatus = ITEM_STATE.SERVER_ERROR_PROCESS; } var handlerFunction = function(handlerName) { return function (event) { var xml = $("partial-response extension#org\\.richfaces\\.extension", event.responseXML) var handlerCode = xml.children(handlerName).text(); var handler = eventHandler(handlerCode); if (handler) { handler.call(this,event); } $("form").trigger('ajaxcomplete'); } } var eventsAdapter = rf.createJSFEventsAdapter({ complete: handlerFunction('complete'), error: handlerFunction('error') }); var responseContext = { source: this.fileUpload.element[0], // MyFaces sourceid: this.fileUpload.element[0], // Mojarra element: this.fileUpload.element[0], /* hack for MyFaces */ _mfInternal: { _mfSourceControlId: this.fileUpload.element.attr('id') }, onevent: eventsAdapter, onerror: eventsAdapter }; var onbeforedomupdate = eventHandler(this.fileUpload.onbeforedomupdate); if (onbeforedomupdate) { var data = {}; data.type = "event"; data.status = 'complete'; data.source = this.fileUpload.element[0]; data.responseCode = this.xhr.status; data.responseXML = this.xhr.responseXML; data.responseText = this.xhr.responseText onbeforedomupdate.call(this.fileUpload, data); } this.fileUpload.form.trigger('ajaxbeforedomupdate'); jsf.ajax.response(this.xhr, responseContext); this.finishUploading(responseStatus); this.fileUpload.__startUpload(); }, this); var onbegin = eventHandler(this.fileUpload.onbegin); if (onbegin) { onbegin.call(this.fileUpload, { source: this.fileUpload.element[0], type: 'event', status: 'begin' }) } this.fileUpload.form.trigger('ajaxbegin'); this.xhr.send(formData); rf.Event.fire(this.fileUpload.element, "onfilesubmit", this.model); }, finishUploading: function(state) { if (state != ITEM_STATE.DONE && this.onerror) { this.onerror.call(this.fileUpload, {state: state, error: this.fileUpload[state + "Label"]}); } this.state.html(this.fileUpload[state + "Label"]); this.progressBarFacet.hide(); this.progressBarFacet.cleanUp(); this.link.html(this.fileUpload["clearLabel"]); this.model.state = state; this.fileUpload.submitedItems.push(this); } }); }(RichFaces.jQuery, window.RichFaces));




© 2015 - 2024 Weber Informatics LLC | Privacy Policy