I implemented FineUploader and I would like to hook up my client script to an event after all files are uploaded. Is that possible?
My implementation follows. Just want to know if that's right direction.
function init() {
var uploader = new qq.FineUploader({
element: document.getElementById('button-selectfiles'),
request: {
endpoint: '/Up/UploadFile'
},
callbacks: {
onStatusChange: onFileUploadStatusChange
}
});
};
var uploads = 0;
function onFileUploadStatusChange(id, oldStatus, newStatus) {
console.log(newStatus);
if (newStatus === 'submitting') {
uploads++;
}
if (newStatus === 'upload successful' || newStatus === 'upload failed') {
uploads--;
}
if (uploads === 0) {
console.log('done');
}
}
onComplete - used for single upload file, if you are using a multiple files upload just use onAllComplete:
callbacks: {
onAllComplete: function() {
alert('done')
}
}
Your onFileUploadStatusChange function fails to check for cancelled files.
The way to verify if all files have been uploaded is via the API methods: getInProgress and getUploads. If we have 0 uploads in progress, and 0 failed uploads, then we can safely assume that all files have been uploaded. You may want to remove the check for failed uploads if you would still like to proceed if any upload has failed. We check for these conditions to be met during the onStatusChange and onComplete callbacks. The onStatusChange event should only check if the file has been cancelled because that might mean that all of the other files have completed, and thus the custom action can be completed.
Note: I've adapted my answer of 16989719 to work for non-jQuery Fine Uploader.
function init() {
var uploader;
function check_done() {
// Alert the user when all uploads are completed.
// You probably want to execute a different action though.
if (allUploadsCompleted() === true) {
window.alert('All files uploaded');
}
}
function allUploadsCompleted() {
// If and only if all of Fine Uploader's uploads are in a state of
// completion will this function fire the provided callback.
// If there are 0 uploads in progress...
if (uploader.getInProgress() === 0) {
var failedUploads = uploader.getUploads({ status: qq.status.UPLOAD_FAILED });
// ... and none have failed
if (failedUploads.length === 0) {
// They all have completed.
return true;
}
}
return false;
}
uploader = new qq.FineUploader({
element: document.getElementById('button-selectfiles'),
request: {
endpoint: '/Up/UploadFile'
},
callbacks: {
onStatusChange: function (id, oldStatus, newStatus) {
// This will check to see if a file that has been cancelled
// would equate to all uploads being 'completed'.
if (newStatus === qq.status.CANCELLED) {
check_done();
}
},
onComplete: check_done
}
});
};
Related
Is there a way to check if the service worker found an update before loading custom functions?
i have this function which is working, but it runs the custom functions twice, and seems very untidy..
I'm looking for a way to only run the custom functions once, and not when an update was found and installed. When an update is found, the user || the page will reload automatically and then the custom functions can run normally..
I added the reg.events in this function to determine where to place my custom functions. I hope this question is understandable..
function installApp(path, scope) {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(path, {
scope: scope
}).then((reg) => {
// event listener to catch the prompt if any and store in
// an instance for later use with add to homescreen() function.
getPrompt();
// this is a custom alert type notification
makeProgress('System','is ok');
/* THIS IS THE UPDATE FOUND FUNCTION */
reg.onupdatefound = function() {
var installingWorker = reg.installing;
installingWorker.onstatechange = function() {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// the _clear() function removes items from the locaforage db to
// force the app to not auto login, but let the user
// login again to refresh any data when the page reloads
_clear('uuid');
_clear('user');
_clear('token');
makeProgress('new version','reload app');
} else {
// removes any custom notifications
clearProgress();
//just go into the app because everything is loaded.
//We dont need to reinstall the
//homescreen or listen for the homescreen because this
//is an update and the homescreen should already be installed?
enterApp();
}
break;
case 'redundant':
// removes any custom notifications cause
//the install is complete
clearProgress();
enterApp();
console.log('The installing service worker became redundant.');
break;
}
};
return;
};
/** Here is the events that fire during the install
// process and where i am currently stuck **/
if (reg.installing) {
makeProgress('updating','files');
/* THE SERVICE WORKER IS DOWNLOADING THE CACHE FROM THE SERVER */
} else if (reg.waiting) {
/* what message here ?*/
/* as far as i can tell, THE SERVICE WORKER IS WAITING FOR
*//*PREVIOUS SERVICE WORKER TO BEREFRESHED SO A RELOAD */
/*UI SHOULD COME HERE??*/
} else if (reg.active) {
/* what message here ?*/
/* IS THIS THE BEST PLACE TO RUN THE BELOW CUSTOM
*//*FUNCTIONS?? WILL //THEY ALWAYS FIRE */
}
/** AT WHICH OF THE EVENTS ABOVE WILL I ADD THE FUNCTIONS FROM HERE **/
requestWakeLock();
const browserFeatures = detectFeatures(reg);
setCompatibilityArray(browserFeatures);
localforage.ready().then(function() {
localforage.getItem('homescreen').then(function (value) {
if(value != 1){
if (platform == 'iPhone' || platform == 'iPad') {
installHome();
} else {
makeProgress('waiting', 'prompt');
waitPrompt();
}
return;
} else {
enterApp();
return;
}
}).catch(function (err) {
alertIt('something went wrong. Please refresh the page to try again. If the problem persists, try another browser.</br>', 'warning', 0);
return;
});
}).catch(function (err) {
alertIt('Something went wrong.<br>Please refresh the page to restart the installation process.<br>'+err, 'danger', 0);
return;
});
/** TO HERE, WITHOUT RUNNING THESE FUNCTION DURING*/
/*THE ONUPDATEFOUND EVENT AS THEN THEY WILL RUN TWICE**/
}, (err) => {
alertIt('Something went wrong.<br>Please refresh the page to restart the installation process.<br>', 'danger', 0);
})
} else {
alertIt('This browser is not compatible with this app.<br>Please try to use a different browser to install this application.<br>', 'danger', 0);
return;
}
}
I initialize this script like so:
window.addEventListener("load", () => {
makeProgress('Checking','system');
installApp(appsPath, appScope);
})
basically they must not be invoked if a new update is found..
I discovered that the onupdate function runs when old service worker is active..
If the onupdate function fires it changes a variable to a true value
I then used a time out function in the active event to see if a variable had changed... if it did change then i return false, and let the onupdate functions continue their course.. otherwise i continue to load my custom functions...Its working, but it doesn't seem like the best way.
Do you have a better method?
so like this:
function installApp(path, scope) {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(path, {
scope: scope
}).then((reg) => {
getPrompt();
makeProgress('refreshing','files');
var entApp = true;
reg.onupdatefound = function() {
entApp = false;
var installingWorker = reg.installing;
installingWorker.onstatechange = function() {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
_clear('uuid');
_clear('user');
_clear('token');
makeProgress('new version','reloading app');
setTimeout(function(){
location.reload();
}, 2500);
return;
} else {
/*NOT SURE WHAT IS SUPPOSED TO GO HERE, SO I JUST RELOADED THE PAGE*/
makeProgress('new version','reloading app');
setTimeout(function(){
location.reload();
}, 2500);
return;
}
break;
case 'redundant':
/*NOT SURE WHAT IS SUPPOSED TO GO HERE, SO I JUST RELOADED THE PAGE*/
makeProgress('new version','reloading app');
setTimeout(function(){
location.reload();
}, 2500);
return;
break;
}
};
return;
};
if (reg.active) {
/** RIGHT HERE IS WHERE THE ONUPDATE FIRES. I GAVE IT A
2.5 SECONDS TO DO ITS THING, THEN CHECKED TO SEE IF THERE WAS
AN UPDATE, IF NO UPDATE THEN I RUN MY CUSTOM FUNCTIONS, OTHERWISE
THE ONUPDATE FUNCTION RELOADS THE PAGE AND THE UPDATED SW.JS FILE
WILL THEN RUN THESE FUNCTIONS WHEN ITS ACTIVE.. IS THERE A BETTER
IN-BUILT METHOD TO DO THIS?**/
setTimeout(function(){
if(entApp === true){
requestWakeLock();
const browserFeatures = detectFeatures(reg);
setCompatibilityArray(browserFeatures);
localforage.ready().then(function() {
localforage.getItem('homescreen').then(function (value) {
if(value != 1){
if (platform == 'iPhone' || platform == 'iPad') {
installHome();
} else {
makeProgress('waiting', 'prompt');
waitPrompt();
}
return;
} else {
enterApp();
return;
}
}).catch(function (err) {
alertIt('something went wrong. Please refresh the page to try again. If the problem persists, try another browser.</br>', 'warning', 0);
return;
});
}).catch(function (err) {
alertIt('Something went wrong.<br>Please refresh the page to restart the installation process.<br>'+err, 'danger', 0);
return;
});
}
}, 2500);
}
I am using Jquery Form Plugin to upload files using onchange event listener on the file upload input element to upload the file as soon as it is selected.
I want to allow only one file at a time to be uploaded and adding the rest in a queue to be uploaded once the existing upload is complete.
I tried making this happen by using a variable and setting it false in beforeSubmit and then switching it back to true once the upload is complete. However, it keeps turning true automatically.
Here is my Javascript code:
var allowUpload = true;
console.log('initial');
var options = {
beforeSubmit: beforeSubmit,
uploadProgress: OnProgress,
success: afterSuccess,
resetForm: true
};
$('#upload').change(function() {
console.log(allowUpload);
if(allowUpload)
{
console.log('onchange:' + allowUpload);
$('#uploadForm').ajaxSubmit(options);
}
return false;
});
function afterSuccess(data)
{
allowUpload = true;
console.log('aftersuccess' + allowUpload);
}
function beforeSubmit(data)
{
allowUpload = false;
console.log(allowUpload);
}
I am using jquery file upload as below.
dialogElem.find('#upload-image-file-input').fileupload({
url: url,
dataType: 'json',
autoUpload: true,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
maxFileSize: 5000000, // 5 MB
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
previewMaxWidth: 100,
previewMaxHeight: 100,
previewCrop: true
}).on('fileuploadadd', function (e, data) {
var fileCount = data.originalFiles.length;
if (fileCount > 5) {
alert("The max number of files is : "+5);
return false;
}
}).on('fileuploadprocessalways', function (e, data) {
//some logic
}).on('fileuploadprogress', function (e, data) {
//some logic
}).on('fileuploaddone', function (e, data) {
//some logic
}).on('fileuploadfail', function (e, data) {
//some logic
})
Inside fileuploadadd I added some validation logic. If the validation is failed, how can I stop all other events like fileuploadprogress,fileuploadfail and fileuploadprocessalways ?
If u have some task like i had few weeks ago - try this:
You can cancel an in-progress upload by aborting the XHR (ajax request) call.
You can bind to the fileuploadadd event of the file input field, submit the request while keeping the jqXHR object and use it for aborting:
jqXHR.abort();
For example:
$(".cloudinary-fileupload").bind('fileuploadadd', function(e, data) {
jqXHR = data.submit(); // Catching the upload process of every file
});
$('#cancel_button').click(function (e) {
if (jqXHR) {
jqXHR.abort();
jqXHR = null;
console.log("Canceled");
}
return false;
});
The following page includes some more code samples
https://github.com/blueimp/jQuery-File-Upload/issues/290
just call
if (fileCount > 5) {
jqXHR.abort();
jqXHR = null; }
jqXHR.abort() doesnt work for me. But throw aborts "add" handling:
.bind('fileuploadadd', function (e, data) {
if (total_uploads >= maxImagesPerPost){
throw new Error('Upload maximum reached');
}
I am using the Latest version of Plupload (2.1) - UI widget
when i click upload files, it uploads all files correctly.
but when i try to upload files with my Form submit button. it doesn't work. it just showing a little bit uploading of files and then eventually submit the forms without completing the file upload.
here is my code :
jj = jQuery.noConflict();
jj(function() {
jj("#flash_uploader_other").plupload({
runtimes: "html5,flash,silverlight,html4",
url: "/external/uploader-new/upload.php",
max_file_size: "10mb",
chunk_size: "1mb",
unique_names: true,
filters: [
{
title: "jpg,xls,csv,doc,pdf,docx,xlsx",
extensions: "jpg,xls,csv,doc,pdf,docx,xlsx"
}
],
flash_swf_url: "/external/uploader-new/js/Moxie.swf",
silverlight_xap_url: "/external/uploader-new/js/Moxie.xap"
});
// Handle the case when form was submitted before uploading has finished
jj("form").submit(function(e) {
// Files in queue upload them first
if (jj("#flash_uploader_other").plupload("getFiles").length > 0) {
// When all files are uploaded submit form
jj("#flash_uploader_other").on("complete", function() {
jj("form").submit();
});
jj("#flash_uploader_other").plupload("start");
}
});
});
Please help!!
Thanks
its working now
I replaced the following code
jj("form").submit(function(e) {
// Files in queue upload them first
if (jj("#flash_uploader_other").plupload("getFiles").length > 0) {
// When all files are uploaded submit form
jj("#flash_uploader_other").on("complete", function() {
jj("form").submit();
});
jj("#flash_uploader_other").plupload("start");
}
});
With this code :
jj("form").submit(function(e) {
var uploader = jj("#flash_uploader_other").plupload("getUploader");
// Validate number of uploaded files
if (uploader.total.uploaded == 0) {
// Files in queue upload them first
if (uploader.files.length > 0) {
// When all files are uploaded submit form
uploader.bind("UploadProgress", function() {
jj("#flash_uploader_other").on("complete", function() {
jj("form").submit();
});
});
jj("#flash_uploader_other").plupload("start");
} else {
jj("form").submit();
}
//alert('You must at least upload one file.');
e.preventDefault();
}
});
My javascript skills are limited and I'm having a problem with the structure of a series of functions which I think need callbacks. I've been reading a number of posts and tutorials but it's not sticking...yet..
On my page I have a pop up modal which contains an image. If the user clicks the edit button it's to be edited in aviary. Once that's completed the image properties get saved into a database and then the images within the modal box - and the underlying form - should get updated with the edited image.
My series of events starts with the modal opening:
$('#editImageLink2').click(function(event) {
aviaryOnClick('image2', $(this).data('mode'), function(image) {
#do final bits here
});
});
Modal pops up then if the user clicks the edit button this next function starts the editor:
function aviaryOnClick(source, mode) {
editedImage = doAviary(source);
if (editedImage) {
return true;
} else {
return false;
}
}
So - aviary pops up as expected. Then when the user saves the edited image I'm starting to have trouble:
The doAviary function looks like this:
function doAviary(source) {
console.log("hit doAviary", source);
var featherEditor = new Aviary.Feather({
apiKey: 'XXXXXXXX',
apiVersion: 3,
theme: 'dark',
tools: 'all',
displayImageSize: true,
maxSize: 1200,
onSave: function(imageID, newURL) {
//replace image in modal preview
var img = document.getElementById(imageID);
img.src = newURL;
if (newURL != undefined) {
storeImage(newURL, updateFormImage(imageData));
featherEditor.close();
return true;
}
},
onError: function(errorObj) {
alert(errorObj.message);
return false;
}
});
return featherEditor.launch({
image: source,
url: $('#' + source).attr('src')
});
}
So I'm trying to run storeImage in the onSave event, which should then run a callback to the update images with the image data.
My storeImage function:
function storeImage(newURL, imageData) {
var options = new Object();
options.aviaryURL = newURL;
options.mode = mode;
options.dbID = ($('#dbID').val()) ? $('#dbID').val() : null;
//console.log("store image options object:", options);
jQuery.ajax({
url: '/filemanager/aviary',
type: 'POST',
dataType: 'json',
data: options,
complete: function(xhr, textStatus) {
//called when complete
},
success: function(data, textStatus, xhr) {
//called when successful
console.log("finished store image", data);
$.cookie('asset_filename', data.image.filename);
$.cookie('asset_id', data.image.id);
imageData(data);
},
error: function(xhr, textStatus, errorThrown) {
//called when there is an error
imageData(false);
}
});
so IF the image is saved the data should be passed back to the callback. If it fails it's false
Then in the update image function
function updateFormImage(data) {
if (data.result == 'success') {
image = data.image;
#simple updates of elements in page
}
}
My current problem is that on save I'm getting an error imageData is not defined - I'm not sure why this is - if it's waiting for ajax to complete before passing back the data to the callback it should exist.
Why does this error happen?
What better ways are there to refactor this code and use callbacks correctly.
I originally had a callback on the first function but got an error callback function not defined
Confused.
Thanks
imageData is not defined into doAviary.
Also, updateFormImage should return something (imageData).