Send dropzone thumbnail to server - javascript

is there a possibility to send the generated Dropzone.js thumbnail to the server?
I have already tried the "sending" event, but there I have no access to the thumbnail:
myDropzone.on('sending', function(file, xhr, formData) {
});
Threre is also a "thumbnail" event but there I have no access to the formData:
myDropzone.on('thumbnail', function(file, dataUrl) {
});
EDIT
#mirata
I changed a few things in the dropzone.js file:
Dropzone.prototype._finished = function(files, responseText, e) {
var file, _i, _len;
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
file.status = Dropzone.SUCCESS;
file.fid = responseText;
this.emit("success", file, responseText, e);
this.emit("complete", file);
}
[...]
};
I have added "file.fid = responseText;" to store the server response (in my case, the fileid) (should be on line 1356, Dropzone.js v4).
And on line 309, "file.thumbnail = dataUrl;"
[...]
thumbnail: function(file, dataUrl) {
var thumbnailElement, _i, _len, _ref;
if (file.previewElement) {
file.thumbnail = dataUrl;
file.previewElement.classList.remove("dz-file-preview");
[...]
}
},
[...]
finally I save my thumbnails with the "success" event:
myDropzone.on('success', function(file) {
$.ajax({
url: 'url',
method: 'post',
data: {
fileId: file.fid,
thumbnail: file.thumbnail
}
});
});
Hope this helps!

It is not correct way to make changes directly in plugin (in that case you can not update your plugins or include them using f.e. npm or bower). You must override plugin or try to solve problem using plugin functionality (Dropzone provides a lot of events).
One version:
Disable autoProcessQueue on plugin init:
autoProcessQueue: false
And process images queue after thumbnail creating:
myDropzone.on('thumbnail', function(file, thumb) {
file.thumbnail = thumb;
myDropzone.processQueue();
});
And before sending image include thumbnail too:
myDropzone.on('sending', function(file, xhr, formData) {
formData.append('thumbnail', file.thumbnail);
});
So instead of making additional request for sending thumbnail, you send it with original image.

I'm having a similar problem. 'Sending' seems to happen first, followed by 'thumbnail' which is done on a separate thread. This means that the thumbnail could be generated in the background at any point before or after the upload is completed. Not ideal for us.
What we really need is a way to trigger the thumbnailing process and have it finish before sending to the server, or figure out how to send the thumbnail as a secondary operation, and know what record the thumbnail needs to be stored against.
If I figure something out, I'll add it here.

Related

Upload image to cloudinary and to my own server using jquery file upload

I use jQuery File Upload to upload images to my server. Now I want to test out Cloudinary, but during testing I still want to upload all images to my own server as well.
The code I use for uploading images to my server is:
$(function () {
$('#fileupload').fileupload({
url: '/Upload/Upload.ashx',
maxFileSize: 15000000,
acceptFileTypes: /(\.|\/)(jpe?g)$/i,
dataType: "json",
autoUpload: true,
start: function (e) {
$('#progress').removeClass('hidden');
},
progress: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css('width', progress + '%');
},
always: function (e) {
$('#progress').addClass('hidden').fadeOut("slow");
},
done: function (e, data) {
$('#progress').addClass('hidden');
parent.location.reload();
},
})
.bind('fileuploadadd', function (e, data) {
$('#error').addClass('hidden');
})
.bind('fileuploadprocessfail', function (e, data) {
var currentFile = data.files[data.index];
if (data.files.error && currentFile.error) {
$('#error').html('error: ' + data.files[data.index].error);
$('#error').removeClass('hidden');
}
})
});
The code for uploading using Cloudinary is:
$('#fileupload').unsigned_cloudinary_upload('test12345',
{ cloud_name: 'test' }
).bind('cloudinarystart', function (e, data) {
$('#progress').show();
}
).bind('cloudinaryprogress', function (e, data) {
$('.progress-bar').css('width',
Math.round((data.loaded * 100.0) / data.total) + '%');
}
).bind('cloudinarydone', function (e, data) {
$('#progress').hide();
parent.location.reload();
});
Now I'm searching for a way to do both the same time or after each other.
What I tried?
I tried to putting the code from Cloudinary in the "done" part of the Jquery File Upload code but that is not working. I also tried to destroyed Fileupload first and then start the Cloudinary code, also not working. I tried to play with Jquery when/then, but still no succes. I searched Google and Stackoverflow but can not find anything that I need.
The first part of uploading (FileUpload) is working. But the Cloudinary part it not. No errors in the console window.
I need a way to combine the scripts.. can anybody help me out?
Update
I fixed it with only running the first script and in the Upload.ashx uploading to Cloudinay with asp.net. That is working.
public static UploadResult UploadImage(string tags, string fileName, Stream stream)
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(fileName, stream),
PublicId = fileName,
Tags = tags,
UploadPreset = "test12345",
};
var result = new Cloudinary(GetAccount()).Upload(uploadParams);
return new UploadResult
{
uri = result.SecureUri,
error = result.Error != null ? result.Error.Message : string.Empty
};
}
When you say "not working", you mean that the cloudinarydone event isn't fired at all after a successful upload? Because it should, and you should be able to get the details of it and to pass it to your server. Here's an example:
https://jsfiddle.net/taragano/70dd9vd4/
Alternatively, and it may be probably the more recommended approach, you can upload the image to your server first, and then do a server-side upload, i.e., have your server upload the image directly to your Cloudinary account.

DropZone.js - Throwing an error on screen immediately after a file is selected

I'm using dropzone.js, and trying to figure out how can I throw an error BEFORE the file is shown in the dropzone UI.
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#fileUpload", { url: "/myUrl/file", maxFiles: 1, maxFilesize: 2,
accept: function(file, done) {
var splitFileName = file.name.split(".");
if (splitFileName[splitFileName.length - 1] != "bbb") {
done("Error! Files of this type are not accepted");
}
else { done(); }
}
});
myDropzone.options.acceptedFiles = '.bbb';
Suppose the user drags a file that is not with .bbb extension, then the file is still shown in the dropzone (with an 'X' sign).
Is it possible not to show that file in the dropzone, and even show a relevant error ?
I figured out you can use the helpful removeFile method with addedfile event to easily achieve this kind of functionality.
myDropzone.on("addedfile", function(file) {
});
Inside this handler, you can remove files with .bbb extensions and set any kind of behavior you wish.

How to allow resubmission of file uploads after failure with Dropzone.js?

I have a file upload form that uses Dropzone.js to upload files to my server. A user can upload up to 5 fivles at once, but I have a unique condition I'm dealing with: if any single file errors out on the server end (over the maximum size, wrong mime-type, wrong file type, etc), I need none of the files to be added to my database. This is not a problem.
What I am having a problem with is the client side handling of it. Why is it when I get a response from the server, I can no longer upload files again by clicking "submit" (the element of which is bound to an event handler, as seen below)?
Dropzone.options.uploadedFilesDropzone = {
autoProcessQueue: false,
maxFilesize: 1024, //MB
addRemoveLinks: true,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 5,
init: function() {
var uploadedFilesDropzone = this;
$('#submit').on('click', function() {
uploadedFilesDropzone.processQueue();
uploadedFilesDropzone.on("successmultiple", function(files, response) {
// Handle the responseText here. For example, add the text to the preview element:
console.log(files);
console.log(response.errors[0]);
$.each(files, function(index, file) {
// no errors
if (response.errors[index].length == 0) {
} else {
file.previewElement.classList.add('dz-error');
}
})
});
});
}
}
Files are removed from the Dropzone queue once processQueue() is called. You can no longer upload the files by clicking submit because there are no files in the queue.
You need to add each file back into the queue after the response has been received.
If there is an error with the files server side it is best to set the status code of the response to something other than 200 so that you can override the Dropzone error listener.
this.on("error", function(file, errorMessage) {
$.each(dropZone.files, function(i, file) {
file.status = Dropzone.QUEUED
});
$.each(message, function(i, item) {
$("#dropzoneErrors .errors ul").append("<li>" + message[i] + "</li>")
});
});

Check overall progress of file upload of jquery file upload

I need to check overall progress of the Jquery file upload
I'm allowing my users to upload multiple files, Now I want to know what all the files are completed then I need to trigger a function to do some other work.
I tried all the callbacks but couldn't figure it out.
I even tried this
var activeUploads = $('.new_photographer').fileupload('active');
But its variable is returning some garbage data.
Here's my jquery:
$('.new_photographer').fileupload({
dataType :'json',
fileInput: $(this).find('input:file'),
acceptFileTypes: /(\.|\/)(gif|jpeg|png|jpg)$/i,
dropZone: $(this).find('#dropzone'),
complete : function (e, data) {
var activeUploads = $('.new_photographer').fileupload('active');
var overallProgress = $('.new_photographer').fileupload('progress');
alert(JSON.stringify(activeUploads));
//alert('overallProgress :: '+JSON.stringify(overallProgress));
if ( activeUploads < 0){
window.location.replace("http://stackoverflow.com");
}
}
}).bind('fileuploadsubmit', function (e, data) {
var inputs = data.context.find(':input');
data.formData = inputs.serializeArray();
});

Dropzone.js uploads only two files when autoProcessQueue set to false

I use Dropzone.js and I want it to upload the dropped not automatically but when the user clicks a button. So I set the autoProcessQueue option to false. When the button is clicked the processQueue() method is called. I would suppose that now the full queue is processed. But thats not the case. Only the number of files which is specified in the parallelUploads option will be uploaded. The standard value of parallelUploads seems to be 2. Which every click 2 files are processed and uploaded.
Do I have to set parallelUploads to an very high number, for now to solve this?
Here's my full JS code:
var myDropzone = new Dropzone("div#myId", {
url: "http://www.torrentplease.com/dropzone.php",
addRemoveLinks: true,
thumbnailWidth: "80",
thumbnailHeight: "80",
dictCancelUpload: "Cancel",
autoProcessQueue: false
});
myDropzone.on("drop", function(event) {
$('.edit_tooltip .option_bar').animate({
opacity: 1,
top: "-5"
});
});
$('.edit_tooltip .option_bar .button').click(function() {
myDropzone.processQueue();
});
Add parallelUploads: 10(This is your max no)
There's a simple way to solve this which can be found here:
https://github.com/enyo/dropzone/issues/253#issuecomment-22184190
"If you want autoProcessQueue to be true after the first upload, then just listen to the processing event, and set this.options.autoProcessQueue = true; inside."
So just add
this.on("processing", function() {
this.options.autoProcessQueue = true;
});
My solution is:
// init dropzone with auto process queue false
var adPhotosDropzone = new Dropzone("#dropzone", {
autoProcessQueue: false,
parallelUploads: 3
});
$(document).on('click', '#btnUpload', function () {
// enable auto process queue after uploading started
adPhotosDropzone.options.autoProcessQueue = true;
// queue processing
adPhotosDropzone.processQueue();
});
// disable queue auto processing on upload complete
adPhotosDropzone.on("queuecomplete", function() {
adPhotosDropzone.options.autoProcessQueue = false;
});
Very late but maybe it will help someone.
I noticed when I placed maxFilesSize above parallerUploads it didn't worked.
So sequence for options should be
.
.
.
parallelUploads: 20,
maxFilesize: 2,
maxFiles: 20,
.
.
Add overdrive two event like
processing -> Allow upload all file
queuecomplete -> Return to normal
init: function () {
this.on("queuecomplete", function () {
this.options.autoProcessQueue = false;
});
this.on("processing", function () {
this.options.autoProcessQueue = true;
});
};
i used this dropzone with option (autoProcessQueue:false) and it does only upload 2 files instead of my whole files. And i found this workaround in the oligoil's answer at the git's issue
The Idea is very simple (bcs we want to upload the files one by one, remember the option! :D ).
It upload multiple but limited to 1, after one file is uploaded it trigger the next Queue!
Hope it help someone!
here's my code using that idea ( since i have 2 forms to upload, after all the images is uploaded it will submitting the other forms )
Dropzone.options.dropzoneForm = {
paramName: "file", // The name that will be used to transfer the file
autoProcessQueue: false,
addRemoveLinks:true,
parallelUploads : 1,
maxFiles : 50,
autoProcessQueue : false,
autoQueue : true,
dictDefaultMessage: "<strong>Drop files here or click to upload. </strong>",
init: function () {
....
this.on("complete", function (file) {
if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
console.log("END ", this.getQueuedFiles().length);
}
else {
Dropzone.forElement("#dropzoneForm").processQueue();
}
});
}
};
If you dont want to set maxFiles (default no limit) and use parallelUploads with the value you want. Read this!
I have solved the problem behaviour by setting
autoQueue: false,
autoProcessQueue: true,
Then when I want to upload the files I just add them to the queue with:
myDrop.enqueueFile(file)
But, this method just accept one file, for multiple files I'am using:
myDrop.on("addedfiles", function(files){
//wait confirmation, or do some processing with the files, then:
files.forEach(function(file){
myDrop.enqueueFile(file)
})
}
Note that "addedfiles" event it's not in the documentation yet. I captures all files dragged into the dropzone or added by the click event.
This is good because if you are using "sending" event to add POST data, or "parallelUploads" the sample code works fine and don't mess with the next files. I am using Sweet Alert 2 to ask for some tags before uploading the images.
I think that you can allow uploadMultiple and change dropzone.js file.
First, allow uploadMultiple
Next, change this line code into dropzone.js:
return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
for
return this.processFiles(queuedFiles.slice(0, queuedFiles.length));
A bit late, but I wasn't happy with the other answers, so here's mine.
Changing autoProcessingQueue (even temporarily) after clicking send mean that if you add another file to the dropzone while other are still queued, it will get uploaded without you having to press send again, which I didn't want. And I didn't want to use a setTimeout or a busyloop either. So here's how to do it without either :
Modify the dropzone.js file. First, in the Dropzone function, you need to add a second file array to store the queue when send is pressed :
function Dropzone(element, options) {
...
this.files = [];
this.files2 = [];
Then, save the files to it when send is clicked by modifying processQueue
Dropzone.prototype.processQueue = function() {
this.files2 = this.getQueuedFiles();
...
Finally, edit the _finished function so that when a file is done uploading, another file get sent if there was still remaining ones in the queue when send was pressed:
Dropzone.prototype._finished = function(files, responseText, e) {
var file, _i, _len;
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
file.status = Dropzone.SUCCESS;
this.emit("success", file, responseText, e);
this.emit("complete", file);
this.files2 = this.files2.filter(function(e) { return e.status == "queued" }); // Remove the files that are finished or already being uploaded
}
if (this.options.uploadMultiple) {
this.emit("successmultiple", files, responseText, e);
this.emit("completemultiple", files);
}
if (this.options.autoProcessQueue) {
return this.processQueue();
}
else {
if (typeof this.files2 != "undefined" && this.files2.length > 0) {
this.processFiles(this.files2.slice(0,1)); // process the next file if there's one
}
}
};
This solved it for me, without changing any dropzone.js code or voiding the parallelUploads setting.
$('#submit').click(function(e){
e.preventDefault();
function tryQueue(){
var numQueued=dz.getQueuedFiles().length;
var numFiles=numQueued+dz.getUploadingFiles().length;
if(numQueued>0){
dz.processQueue();
}
if(numFiles>0){
setTimeout(tryQueue,1000);
}
else window.location='/'; //redirect when finished
}
tryQueue();
});
This assumes that dz is the dropzone instance. It works by invoking processQueue until all have been uploaded. The logic in processQueue takes care of returning if nothing needs to be done so no harm in the polling.

Categories

Resources