AJAX simple file uploader
A simple javascript powered file uploader with progress and hooks support. Was created as a loose replacement for FineUploader. Currently only works with local uploads Below is the log history from the previous folder: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit 6ea59f91314be8b2b936920d4b0a3f04932c9e73 ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Thu Jun 3 10:31:54 2021 +0900 AJAX file uploader code clean up Add global abort and connected clean up of function calls and element show/hide blocks Add simple progress bar for upload (in connection with percent upload) Move running AFUS object into the config object Added new config object entries for this: - abort: flagged true if global abort is triggered - running: moved from AFUS_running into config, how many uploads are currently running - current: current file_pos running (that is queue position in array) - current_xhr: current XHR upload object, used for abort calls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit b061008ca0b496f6157b8f073d7ca14abb469ef5 ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Thu May 27 11:51:47 2021 +0900 Update AJAX file uploader to work sequential Rewrite flow in ajax uploader to use promsies to launch a new upload only if the previous upload was finished (in any way) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit a2ec369a8cae65e216fe402ac8b5d106e3db99af ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Thu May 20 11:48:38 2021 +0900 Updated ajax simple file uploader to allow multiple file uploads ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit 66878f89c82fe914031e113e780fd72e9ff09b78 ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Mon May 10 09:13:25 2021 +0900 Excel vendor sub module, ajax delay test, ajax file upload fix, others ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit e4efbbfdf843d8b2e53e4d3c873799b839875721 ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Fri Apr 9 13:44:28 2021 +0900 ajax file upload updates, byte format test fixes, ssh2 test fixes, array append test add, nested array recursive walk test add ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit 88734ebaf7420a704a538f0a923ce6996b0b5237 ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Mon Jan 25 17:15:14 2021 +0900 Add ajax uploader on error external function call Like post success uploaded, this function is called on any "non success" return falue. Passes on the full returned ajax data object ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit 2098fe53d510c03f291eaa5c4b2aefd60c24448e ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Wed Jan 13 06:29:20 2021 +0900 Add additional parameters method parameter Added on init of form, when submitted before additional external form parameters function is called ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit 0c2211e2312abf368c4151dbdf54d4fa96a121dc ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Tue Jan 12 10:09:42 2021 +0900 AJAX File uploader change for external function call. External functions are passed into the uploader as parameters. With this we can have unique functions for each init ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit c1eb15e30df319db1d5104bc5e4ab0cd8bb7cc8c ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Fri Jan 8 09:59:33 2021 +0900 AJAX file uploader target action router value dynamic setting update, other test php files updates and additions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ commit 429af6db892d6968ad87a3db662f3ff1a9d74270 ┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━ Author: Clemens Schwaighofer <clemens.schwaighofer@egplusww.com> Date: Thu Nov 5 11:33:30 2020 +0900 AJAX file uploader test code Simple single file AJAX file uploader with backend code sample. Work in progress with open - better, simpler frontend code insert part - multiple file upload - flag auto handling zip files (or tar, etc) - make it not rely on Jquery at all
This commit is contained in:
532
src/ajaxFileUploadSimple.OLD.js
Executable file
532
src/ajaxFileUploadSimple.OLD.js
Executable file
@@ -0,0 +1,532 @@
|
||||
/* AJAX File upload simple */
|
||||
|
||||
/* jshint esversion: 6 */
|
||||
|
||||
/* global errorCatch */
|
||||
|
||||
/**
|
||||
* CUSTOM SUB CALL FUNCTIONS as passsd on in init call
|
||||
* fileChange(target_file, target_router)
|
||||
* fileBeforeUpload(target_file, target_router)
|
||||
* fileUploaded(target_file, target_router, control_data)
|
||||
* fileUploadError(target_file, target_router, control_data)
|
||||
*/
|
||||
|
||||
var AFUS_strings = {};
|
||||
|
||||
/**
|
||||
* [5-A] show progress circle
|
||||
* Hides the submit button
|
||||
* If a "confirm" button is present hides this one too
|
||||
* !TODO! call external function for additional checks
|
||||
* and move eg confirm buttons check there
|
||||
* @param {String} target_file prefix for elements
|
||||
*/
|
||||
function showProgress(target_file)
|
||||
{
|
||||
// console.log('Show progress circle');
|
||||
// hide the upload button itself so we don't press twice
|
||||
$('#' + target_file + '-submit').hide();
|
||||
if ($('#mask-' + target_file).length > 0) {
|
||||
$('#mask-' + target_file).hide();
|
||||
} else {
|
||||
$('#' + target_file + '-file').hide();
|
||||
}
|
||||
// check if we have button "confirm" and disable it
|
||||
if ($('#confirm').length > 0) {
|
||||
$('#confirm').prop('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [7-C] hide progress circle
|
||||
* Show submit button again
|
||||
* If a "confirm" button is present show this one too
|
||||
* !TODO! call external function for additional checks
|
||||
* and move eg confirm buttons check there
|
||||
* @param {String} target_file prefix for elements
|
||||
*/
|
||||
function hideProgress(target_file)
|
||||
{
|
||||
// console.log('Hide progress circle');
|
||||
// show the upload button again after upload
|
||||
$('#' + target_file + '-submit').show();
|
||||
if ($('#' + target_file + '-submit-div').length > 0) {
|
||||
$('#' + target_file + '-submit-div').show();
|
||||
}
|
||||
if ($('#mask-' + target_file).length > 0) {
|
||||
$('#mask-' + target_file).show();
|
||||
// on mask hide button after upload
|
||||
$('#' + target_file + '-submit').hide();
|
||||
if ($('#' + target_file + '-submit-div').length > 0) {
|
||||
$('#' + target_file + '-submit-div').hide();
|
||||
}
|
||||
} else {
|
||||
$('#' + target_file + '-file').show();
|
||||
}
|
||||
// check if we have button "confirm" and disable it
|
||||
if ($('#confirm').length > 0) {
|
||||
$('#confirm').prop('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [7-B] upload error
|
||||
* prints upload error messages into the status field
|
||||
* @param {String} target_file prefix for elements
|
||||
* @param {Array} error_message error message, if not set standard error is shown
|
||||
* @param {Boolean} is_error if set true, then add error message class
|
||||
*/
|
||||
function uploadError(target_file, error_message, is_error)
|
||||
{
|
||||
// set if empty
|
||||
if (error_message.length == 0) {
|
||||
error_message.push('[JS Upload Lib] Upload Error');
|
||||
}
|
||||
// write error message
|
||||
document.getElementById(target_file + '-upload-status').innerHTML = error_message.join('<br>');
|
||||
// add error style to upload status
|
||||
if (is_error === true) {
|
||||
$('#' + target_file + '-upload-status').addClass('SubError');
|
||||
} else {
|
||||
$('#' + target_file + '-upload-status').removeClass('SubError');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [3] pass through event
|
||||
* Checks if a mask- element is present and then attaches
|
||||
* the passthrough event to the internal files button
|
||||
* checks if fileChange variable is a function and calls it
|
||||
* @param {String} target_file Prefix for elements
|
||||
* @param {String} target_router Router target name
|
||||
* @param {Boolean} auto_submit If set true will pass by submit button click
|
||||
* and automatically upload
|
||||
* @param {Function} fileChange A function with two string parameters
|
||||
* target_file, target_router
|
||||
* Is called on change of -file entry
|
||||
*/
|
||||
function passThroughEvent(target_file, target_router, auto_submit, fileChange)
|
||||
{
|
||||
console.log('[AJAX Uploader: %s] Element exists: %s',target_file, $('#mask-' + target_file + '-file').length);
|
||||
if ($('#mask-' + target_file + '-file').length > 0) {
|
||||
// hide the other elements
|
||||
// hide submit button until file is selected
|
||||
$('#' + target_file + '-file, #mask-' + target_file + '-file, #' + target_file + '-submit, #' + target_file + '-submit-div').hide();
|
||||
// init wipe upload status
|
||||
$('#' + target_file + '-upload-status').html('');
|
||||
// write file name to upload status
|
||||
// show submit button
|
||||
$('#' + target_file + '-file').change(function() {
|
||||
$('#mask-' + target_file + '-file').val($('#' + target_file + '-file').val());
|
||||
$('#' + target_file + '-upload-status').html(document.getElementById(target_file + '-file').files[0].name);
|
||||
$('#' + target_file + '-upload-status').show();
|
||||
if (auto_submit === false) {
|
||||
$('#' + target_file + '-submit').show();
|
||||
if ($('#' + target_file + '-submit-div').length > 0) {
|
||||
$('#' + target_file + '-submit-div').show();
|
||||
}
|
||||
}
|
||||
// file upload changed function
|
||||
if (typeof fileChange === 'function') {
|
||||
fileChange(target_file, target_router);
|
||||
}
|
||||
// if auto submit flaged
|
||||
console.log('AUTO SUBMIT: %s', auto_submit);
|
||||
if (auto_submit === true) {
|
||||
document.getElementById(target_file + '-submit').click();
|
||||
}
|
||||
});
|
||||
$('#mask-' + target_file + '-file').click(function() {
|
||||
var $elm = $('#' + target_file + '-file');
|
||||
if (document.createEvent) {
|
||||
var e = document.createEvent('MouseEvents');
|
||||
e.initEvent('click', true, true );
|
||||
$elm.get(0).dispatchEvent(e);
|
||||
} else {
|
||||
$elm.trigger('click');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [7-A] final step after upload
|
||||
* The last action to be called, fills all the hidden values
|
||||
* - uid
|
||||
* - file_name
|
||||
* - file_size
|
||||
* Inserts thumbnail if url exists
|
||||
* Adds uploaded file name and file size if flags show_name/show_size are set
|
||||
* The function checks for "fileUploaded" and if it exists
|
||||
* it will be called with the "other_data" object
|
||||
* @param {String} target_file Prefix for elements
|
||||
* @param {String} target_router Target router name
|
||||
* @param {Object} file_info Object with all the additional data returned from AJAX
|
||||
* @param {Object} data Full Object set (including file_info)
|
||||
* @param {Function} fileUploaded A function with two string and one object parameters
|
||||
* target_file, target_router, data
|
||||
* Is called after the upload has finished successfully
|
||||
*/
|
||||
function postUpload(target_file, target_router, file_info, data, fileUploaded)
|
||||
{
|
||||
console.log('[AJAX Uploader: %s] Post upload: File: %s, URL: %s, Name: %s, Size: %s', target_file, file_info.file_uid, file_info.file_url, file_info.file_name, file_info.file_size);
|
||||
// reset upload file, etc
|
||||
document.getElementById(target_file + '-file').value = '';
|
||||
// safari issues?
|
||||
document.getElementById(target_file + '-file').type = '';
|
||||
document.getElementById(target_file + '-file').type = 'file';
|
||||
// set internal uid
|
||||
document.getElementById(target_file + '-uid').value = file_info.file_uid;
|
||||
// name & size
|
||||
document.getElementById(target_file + '-file_name').value = file_info.file_name;
|
||||
document.getElementById(target_file + '-file_size').value = file_info.file_size_raw;
|
||||
// set thumb here, if we haveone
|
||||
// file_info also holds the output flags show_name, show_size if we want to show additional info
|
||||
// add remove file from here too (submits with uid to remove tmp uploaded file)
|
||||
// clear any previous content
|
||||
document.getElementById(target_file + '-uploaded').innerHTML = '';
|
||||
var element;
|
||||
// set base CSS prefix if set or use standard one
|
||||
var base_css = file_info.css ? file_info.css : 'image-upload';
|
||||
if (file_info.file_url) {
|
||||
element = document.createElement('img');
|
||||
element.src = file_info.file_url;
|
||||
element.id = target_file + '-input-thumbnail';
|
||||
element.className = base_css + '-img';
|
||||
document.getElementById(target_file + '-uploaded').appendChild(element);
|
||||
$('#' + target_file + '-uploaded').show();
|
||||
}
|
||||
// if we have name/size addition
|
||||
if (file_info.show_name || file_info.show_size) {
|
||||
element = document.createElement('div');
|
||||
element.className = base_css + '-text';
|
||||
if (file_info.show_name) {
|
||||
element.innerHTML = file_info.file_name;
|
||||
}
|
||||
if (file_info.show_size) {
|
||||
element.innerHTML += ' (' + file_info.file_size + ')';
|
||||
}
|
||||
document.getElementById(target_file + '-uploaded').appendChild(element);
|
||||
$('#' + target_file + '-uploaded').show();
|
||||
}
|
||||
if (typeof fileUploaded === 'function') {
|
||||
fileUploaded(target_file, target_router, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [2] Function that will allow us to know if Ajax uploads are supported
|
||||
* @return {Boolean} true on "ajax file uploaded supported", false on not possible
|
||||
*/
|
||||
function supportAjaxUploadWithProgress()
|
||||
{
|
||||
return supportFileAPI() && supportAjaxUploadProgressEvents() && supportFormData();
|
||||
// Is the File API supported?
|
||||
function supportFileAPI()
|
||||
{
|
||||
var fi = document.createElement('INPUT');
|
||||
fi.type = 'file';
|
||||
return 'files' in fi;
|
||||
}
|
||||
// Are progress events supported?
|
||||
function supportAjaxUploadProgressEvents()
|
||||
{
|
||||
var xhr = new XMLHttpRequest();
|
||||
return !! (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
|
||||
}
|
||||
// Is FormData supported?
|
||||
function supportFormData()
|
||||
{
|
||||
return !! window.FormData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [1] this has to be called to start the uploader
|
||||
* checks if ajax upload is supported and if yes
|
||||
* checks if we need to set the pass through click event
|
||||
* then calls the final init that loads the form.submit catcher
|
||||
* @param {String} target_file prefix for the element for the file upload
|
||||
* @param {String} target_form the master form in which this element sits
|
||||
* @param {String} [target_router=''] value of the action _POST variable, if not set or
|
||||
* if empty use "fileUpload"
|
||||
* NOTE: default = '' has been removed to work with IE11
|
||||
* @param {String} [target_action=''] override the target_form action field
|
||||
* NOTE: default = '' has been removed to work with IE11
|
||||
* @param {Object} [form_parameters={}] Key/Value list for additional parameters to add to the form submit.
|
||||
* Added BEFORE fileBeforeUpload parameters
|
||||
* @param {Boolean} [auto_submit=false] if we override the submit button
|
||||
* and directly upload
|
||||
* NOTE: default = false has been removed to work with IE11
|
||||
* @param {Function} [fileChange=''] Function run on change of -file element entry
|
||||
* Parameters are target_file, target_router
|
||||
* NOTE: default = false has been removed to work with IE11
|
||||
* @param {Function} [fileBeforeUpload=''] Function called before upload starts
|
||||
* Parameters are target_file, target_router
|
||||
* NOTE: default = false has been removed to work with IE11
|
||||
* @param {Function} [fileUploaded=''] Function called after upload has successfully finished
|
||||
* Parameters are target_file, target_router, data (object returned from upload function call)
|
||||
* NOTE: default = false has been removed to work with IE11
|
||||
* @param {Function} [fileUploadError=''] Function called after upload has failed
|
||||
* Parameters are target_file, target_router, data (object returned from upload function call)
|
||||
* NOTE: default = false has been removed to work with IE11
|
||||
*/
|
||||
function initAjaxUploader(target_file, target_form, target_router, target_action, form_parameters, auto_submit, fileChange, fileBeforeUpload, fileUploaded, fileUploadError)
|
||||
{
|
||||
// Actually confirm support
|
||||
if (supportAjaxUploadWithProgress()) {
|
||||
console.log('[AJAX Uploader: %s] init [%s]', target_file, target_router);
|
||||
if (document.getElementById(target_file + '-submit') !== null) {
|
||||
// add click event for the submit buttons to set which one submitted the file
|
||||
document.getElementById(target_file + '-submit').addEventListener('click', function() {
|
||||
this.form.submitted = this.id;
|
||||
});
|
||||
// set pass through events
|
||||
passThroughEvent(target_file, target_router, auto_submit, fileChange);
|
||||
// Ajax uploads are supported!
|
||||
// Init the Ajax form submission
|
||||
// pass on the target_file and the master form name
|
||||
initFullFormAjaxUpload(target_file, target_form, target_router, target_action, form_parameters, fileBeforeUpload, fileUploaded, fileUploadError);
|
||||
} else {
|
||||
console.log('[AJAX Uploader: %s] Element not found for init', target_file);
|
||||
}
|
||||
} else {
|
||||
console.log('[AJAX Uploader: %s] failed', target_file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [4] MAIN CALL for upload
|
||||
* Creates the main ajax send request if a submit on the main form is detected
|
||||
* all the parameters are passed on from the init function
|
||||
* The function will throw an error of not action (target) can be found
|
||||
* @param {String} target_file prefix for the element for the file upload
|
||||
* @param {String} target_form the master form in which this element sits
|
||||
* @param {String} target_router value of the action _POST variable
|
||||
* @param {String} target_action override the target_form action field (target file)
|
||||
* @param {Object} form_parameters additional parameters added to the form submit
|
||||
* @param {Function} fileBeforeUpload Function with two string parameters
|
||||
* target_file, target_router
|
||||
* Is called on submit before upload starts
|
||||
* @param {Function} fileUploaded Is passed through to sendXHRequest
|
||||
* @param {Function} fileUploadError Is passed through to sendXHRequest
|
||||
* @return {Boolean} false to not trigger normal form submit
|
||||
*/
|
||||
function initFullFormAjaxUpload(target_file, target_form, target_router, target_action, form_parameters, fileBeforeUpload, fileUploaded, fileUploadError)
|
||||
{
|
||||
// should check that form exists
|
||||
// + '-form'
|
||||
var form = document.getElementById(target_form);
|
||||
if (!form.getAttribute('action') && !target_action) {
|
||||
console.log('!!!!! MISSING FORM ACTION ENTRY');
|
||||
throw new Error('!!!!! MISSING FORM ACTION ENTRY');
|
||||
}
|
||||
form.onsubmit = function()
|
||||
{
|
||||
var path = window.location.pathname;
|
||||
// do we end in .php, we need to remove the name then, we just want the path
|
||||
if (path.indexOf('.php') != -1) {
|
||||
// remove trailing filename (all past last / )
|
||||
path = path.replace(/\w+\.php/, '');
|
||||
}
|
||||
if (path.substr(-1) != '/') {
|
||||
path += '/';
|
||||
}
|
||||
// get the form.submitted text (remove -submit) and compare to target_file,
|
||||
// if different overwrite the target file
|
||||
var _target_file = form.submitted.split('-')[0];
|
||||
console.log('[AJAX Uploader: %s] Wanted: %s, Submitted: %s', target_file, _target_file, form.submitted);
|
||||
if (target_file != _target_file) {
|
||||
target_file = _target_file;
|
||||
}
|
||||
// remove previous highlight if set
|
||||
$('#' + target_file + '-upload-status').removeClass('SubError');
|
||||
$('#' + target_file + '-upload-status').show();
|
||||
// progress highlight
|
||||
showProgress(target_file);
|
||||
// console.log('[AJAX Uploader: %s] Start upload', target_file);
|
||||
// create new form
|
||||
var formData = new FormData();
|
||||
// We send the data where the form wanted
|
||||
var action = form.getAttribute('action');
|
||||
// in case we have a target action set, we overwirde
|
||||
if (target_action) {
|
||||
action = target_action;
|
||||
}
|
||||
console.log('[AJAX Uploader: %s] ACTION: %s, PATH: %s', target_file, action, path);
|
||||
// add action
|
||||
if (!target_router) {
|
||||
target_router = 'fileUpload';
|
||||
}
|
||||
formData.append('action', target_router);
|
||||
formData.append('uploadName', target_file + '-file');
|
||||
// add file only (first file found) with target file name
|
||||
formData.append(target_file + '-file', document.getElementById(target_file + '-file').files[0]);
|
||||
// append file uid if exists
|
||||
formData.append(target_file + '-uid', $('#' + target_file + '-uid').val());
|
||||
// add additional ones
|
||||
for (const [key, value] of Object.entries(form_parameters)) {
|
||||
formData.append(key, value);
|
||||
}
|
||||
// external data gets added
|
||||
if (typeof fileBeforeUpload === 'function') {
|
||||
for (const [key, value] of Object.entries(fileBeforeUpload(target_file, target_router))) {
|
||||
formData.append(key, value);
|
||||
}
|
||||
}
|
||||
console.log('[AJAX Uploader: %s] Send data to: %s, with path: %s', target_file, action, path);
|
||||
// run translation check, must have at least two basic strings set
|
||||
// if they are not set, set default values here
|
||||
/*if (!Object.prototype.hasOwnProperty.call(AFUS_strings, 'upload_start')) {
|
||||
AFUS_strings.upload_start = 'Upload start';
|
||||
}
|
||||
if (!Object.prototype.hasOwnProperty.call(AFUS_strings, 'upload_finished')) {
|
||||
AFUS_strings.upload_finished = 'Upload finished';
|
||||
}*/
|
||||
// debugger;
|
||||
// Code common to both variants
|
||||
sendXHRequest(target_file, target_router, formData, path + action, fileUploaded, fileUploadError);
|
||||
console.log('[AJAX Uploader: %s] Data sent to: %s', target_file, action);
|
||||
// Avoid normal form submission
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* [5-B]
|
||||
* Once the FormData instance is ready and we know
|
||||
* where to send the data, the data gets submitted
|
||||
* it adds event listeners for start/progress/load and general ready state change
|
||||
* then it sends the data
|
||||
* each event listener is called during the stages
|
||||
* - start: onloadstartHandler
|
||||
* - progress: onprogressHandler
|
||||
* - end: onloadHandler
|
||||
* - finish: onreadystatechangeHandler
|
||||
* Note: on xhr.onerror function is called if an error happens
|
||||
* and just calls the xhr.send again
|
||||
* there are some issues on firefox that can trigger this
|
||||
* @param {String} target_file Element name prefix
|
||||
* @param {String} target_router Target router name
|
||||
* @param {Object} formData The form data created in the init full function
|
||||
* @param {String} uri The target uri to where the data should be sent
|
||||
* @param {Function} fileUploaded Is passed through to onreadystatechangeHandler
|
||||
* @param {Function} fileUploadError Is passed through to onreadystatechangeHandler
|
||||
*/
|
||||
function sendXHRequest(target_file, target_router, formData, uri, fileUploaded, fileUploadError)
|
||||
{
|
||||
// Get an XMLHttpRequest instance
|
||||
var xhr = new XMLHttpRequest();
|
||||
// Set up events
|
||||
xhr.upload.addEventListener('loadstart', onloadstartHandler.bind(null, target_file), false);
|
||||
xhr.upload.addEventListener('progress', onprogressHandler.bind(null, target_file), false);
|
||||
xhr.upload.addEventListener('load', onloadHandler.bind(null, target_file), false);
|
||||
xhr.addEventListener('readystatechange', onreadystatechangeHandler.bind(null, target_file, target_router, fileUploaded, fileUploadError), false);
|
||||
// alternative pass on via target file
|
||||
// xhr.targetFile = target_file;
|
||||
// Set up request
|
||||
xhr.open('POST', uri, true);
|
||||
// Fire!
|
||||
xhr.send(formData);
|
||||
// on error log & try again
|
||||
xhr.onerror = function() {
|
||||
console.log('[AJAX Uploader: %s] upload ERROR', target_file);
|
||||
// try again
|
||||
xhr.open('POST', uri, true);
|
||||
xhr.send(formData);
|
||||
};
|
||||
console.log('[AJAX Uploader: %s] SEND DATA: %o', target_file, formData);
|
||||
}
|
||||
|
||||
/**
|
||||
* [6-A] Handle the start of the transmission
|
||||
* @param {String} target_file element name prefix
|
||||
*/
|
||||
function onloadstartHandler(target_file)
|
||||
{
|
||||
// console.log('[AJAX Uploader: %s] start uploading', target_file);
|
||||
// must set dynamic
|
||||
var div = document.getElementById(target_file + '-upload-status');
|
||||
div.innerHTML = AFUS_strings.upload_start || 'Upload start';
|
||||
}
|
||||
|
||||
/**
|
||||
* [6-B] Handle the end of the transmission
|
||||
* @param {String} target_file element name prefix
|
||||
*/
|
||||
function onloadHandler(target_file)
|
||||
{
|
||||
// console.log('[AJAX Uploader: %s] finished uploading', target_file);
|
||||
// must set dynamic
|
||||
var div = document.getElementById(target_file + '-upload-status');
|
||||
div.innerHTML = AFUS_strings.upload_finished || 'Upload finished';
|
||||
}
|
||||
|
||||
/**
|
||||
* [6-C] Handle the progress
|
||||
* calculates percent and show that in the upload status element
|
||||
* @param {String} target_file element name prefix
|
||||
* @param {Event} evt event data for upload progress
|
||||
* holds file size and bytes transmitted
|
||||
*/
|
||||
function onprogressHandler(target_file, evt)
|
||||
{
|
||||
// must set dynamic
|
||||
var div = document.getElementById(target_file + '-upload-status');
|
||||
var percent = evt.loaded / evt.total * 100;
|
||||
// console.log('[AJAX Uploader: %s] Uploading: %s', target_file, Math.round(percent));
|
||||
div.innerHTML = Math.round(percent) + '%';
|
||||
}
|
||||
|
||||
/**
|
||||
* [6-D] Handle the response from the server
|
||||
* If ready state is 4 it will call the final post upload function on status success
|
||||
* if status is other it will call the upload error function
|
||||
* on all other statii it currently only prints a debug log message
|
||||
* @param {String} target_file Element name prefix
|
||||
* @param {String} target_router Target router name
|
||||
* @param {Function} fileUploaded Is passed through to postUpload
|
||||
* @param {Function} fileUploadError Is called on error
|
||||
* @param {Event} evt event data for return data and ready state info
|
||||
*/
|
||||
function onreadystatechangeHandler(target_file, target_router, fileUploaded, fileUploadError, evt)
|
||||
{
|
||||
var status, readyState, responseText, responseData;
|
||||
try {
|
||||
readyState = evt.target.readyState;
|
||||
responseText = evt.target.responseText;
|
||||
status = evt.target.status;
|
||||
} catch(e) {
|
||||
errorCatch(e);
|
||||
return;
|
||||
}
|
||||
if (readyState == 4 && status == '200' && responseText) {
|
||||
responseData = JSON.parse(responseText);
|
||||
// must set dynamic
|
||||
console.log('[AJAX Uploader: %s] Uploader response: %s -> %o', target_file, responseData.status, responseData);
|
||||
uploadError(target_file, responseData.content.msg, false);
|
||||
// run post uploader
|
||||
if (responseData.status == 'success') {
|
||||
postUpload(target_file, target_router, {
|
||||
file_uid: responseData.content.file_uid,
|
||||
file_url: responseData.content.file_url,
|
||||
file_size: responseData.content.file_size,
|
||||
file_size_raw: responseData.content.file_size_raw,
|
||||
file_name: responseData.content.file_name,
|
||||
show_name: responseData.content.show_name,
|
||||
show_size: responseData.content.show_size,
|
||||
css: responseData.content.css
|
||||
}, responseData.content, fileUploaded);
|
||||
} else {
|
||||
// uploadError(target_file, responseData.content.msg, true);
|
||||
if (typeof fileUploadError === 'function') {
|
||||
fileUploadError(target_file, target_router, responseData.content);
|
||||
}
|
||||
}
|
||||
hideProgress(target_file);
|
||||
} else {
|
||||
console.log('[AJAX Uploader: %s] ReadyState: %s, status: %s, Text: %o', target_file, readyState, status, responseText);
|
||||
}
|
||||
}
|
||||
1222
src/ajaxFileUploadSimple.js
Executable file
1222
src/ajaxFileUploadSimple.js
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user