I'm using the jQuery File Upload plugin.
I would like to be able to trigger an event when all selected files have finished uploading. So far I have an event for doing an action when a file(s) is selected for uploading and when each particular file finishes uploading - is there a way to detect that all selected files have finished uploading?
The actual app is here http://repinzle-demo.herokuapp.com/upload
My input field looks like this:
<div id="fine-uploader-basic" class="btn btn-success" style="position: relative; overflow: hidden; direction: ltr;">
My script code looks like this:
<script>
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
add: function (e, data) { // when files are selected this lists the files to be uploaded
$.each(data.files, function (index, file) {
$('<p/>').text("Uploading ... "+file.name).appendTo("#fileList");
});
data.submit();
},
done: function (e, data) { // when a file gets uploaded this lists the name
$.each(data.files, function (index, file) {
$('<p/>').text("Upload complete ..."+file.name).appendTo("#fileList");
});
}
});
});
</script>
I am handling the request with a Play Framework (Java) controller that looks like this:
publi
c static void doUpload(File[] files) throws IOException{
List<ImageToUpload> imagesdata = new ArrayList<ImageToUpload>();
//ImageToUpload has information about images that are going to be uploaded, name size etc.
for(int i=0;i<files.length;i++){
Upload upload = new Upload(files[i]);
upload.doit(); //uploads pictures to Amazon S3
Picture pic = new Picture(files[i].getName());
pic.save(); // saves metadata to a MongoDB instance
imagesdata.add(new ImageToUpload(files[i].getName()));
}
renderJSON(imagesdata);
}
I think you are looking for 'stop' event:
$('#fileupload').bind('fileuploadstop', function (e) {/* ... */})
as said in the plugin documentation:
Callback for uploads stop, equivalent to the global ajaxStop event
(but for file upload requests only).
You can also specify the function on plugin creation passing it as parameter
$('#fileupload').fileupload({
stop: function (e) {}, // .bind('fileuploadstop', func);
});
Here's the solution you want:
$('#fileupload').on('fileuploaddone', function(e, data) {
var activeUploads = $('#fileupload').fileupload('active');
if (activeUploads == 1) {
console.info("All uploads done");
}
});
I was with this problem also, fixed 3 years ago.
Related
I am toying with the following code trying to take images from a set directory, and preload them. I do not want to load the images into a div, but rather preload them in the memory using the normal:
new Image().src = "/wp-content/themes/NCHERM_Theme/images/home4-events.jpg";
I am rather new to jquery so looking for some help to finalize this:
window.onload = function($) {
var folder = "images/preload";
$.ajax({
url : folder,
success: function (data) {
//go through each item in folder
$.each(data, function(i,filename) {
//take each item and run into the normal preload method
setTimeout(function() {
// preload images
new Image().src = filename;
}, 1000);
});
}
});
};
running this in wordpress I get `403 forbbiden' on the url for the folder before i can even test if this is working
Make sure you have added reference of JQuery inside your <script> tag. JQuery Library is missing.
<script src="../../jquery.min.js" type="text/javascript"></script>
For your reference: $.ajax is not a function
Try this code if it work for you.
window.onload = function($) {
var folder = "images/preload";
$.ajax({
url : folder,
success: function (data) {
//go through each item in folder
$.each(data, function(i,filename) {
//take each item and run into the normal preload method
setTimeout(function() {
// preload images
var $img=$("<img />",{"src":filename});
$('#target_id').append($img);
}, 1000);
});
}
});
};
You can solve 403 error by adding:
Options +Indexes
On .htaccess file.
I am attempting to use the jQuery File Upload Plugin here
The behavior I want is similar to the home page that loads - i.e - the ability to select multiple files - when selected I don't need the button to upload files individually (just remove with the cancel button individually) and remove all with the cancel button along the top bar
I am developing my site in c# mvc and the file gets uploaded to a ECM solution via CMIS Browser Bindings so I dont actually hit an MVC controller method. As I am using Browser Bindings I need to upload each file individually to the CMIS Endpoint. The code works fine doing an auto data submit for each file
So the working code I have is:
$('#uploadFile').fileupload({
replaceFileInput: false,
singleFileUploads: true,
add: function (e, data) {
$.each(data.files, function (index, file) {
data.url = 'mycmis_url';
data.type = 'POST';
data.submit();
});
},
done: function (e, data) {
alert("Done");
}
});
If I do have 3 files selected to upload I will get 3 'Done' alerts but the 3 files all upload successfully. However as mentioned the behavior I want is one Uppload All button that would trigger the upload for each of my selected files. I have the code below:
$('#uploadFile').fileupload({
replaceFileInput: false,
singleFileUploads: true,
autoUpload: false,
add: function (e, data) {
$.each(data.files, function (index, file) {
data.url = 'mycmis_url';
data.type = 'POST';
});
$("#uploadAllFilesBtn").unbind('click').on('click', function () { data.submit(); });
},
done: function (e, data) {
alert("Done");
}
});
So I have set the autoUpload property to false but if I select two files and then click my Upload All Files button as my uploadAllFiles button is outside my each loop if my first selected file is called foo.txt and my 2nd selected file is bar.txt it will only upload bar.txt.
Has anyone got any idea how I could have a button called upload all that would trigger a data.submit for each individual file?
Incorporating code from your later question:
$('#uploadFile').fileupload({
replaceFileInput: false,
singleFileUploads: true,
add: function(event, data) {
data.url = 'myUrl';
data.type = 'POST';
data.context = $('<tr>'
+ '<td><strong>Selected File : </strong>' + data.files[0].name + '</td>'
+ '<td> </td>'
+ '<td><button type="button" class="removeBtn btn btn-default">'
+ '<span class="glyphicon glyphicon-remove-circle"></span>'
+ 'Remove File</button></td>'
+ '</tr>')
.appendTo('#files')
.data('data', data);
}
});
$('#files').on('click', '.removeBtn', function() {
$(this).closest('tr').remove();
});
$('#uploadAllFiles').click(function() {
var jqXHRs = [];
$('#files').find('tr').each(function() {
jqXHRs.push($(this).data('data').submit());
});
$.when.apply($, jqXHRs).done(function() {
alert('done');
});
});
Note:
Since you have singleFileUploads set to true, the data.files array will always contain exactly one file.
The data is attached to the <tr> element using jQuery's .data() function.
For the "Remove" buttons, the code is using event delegation, which was suggested by #Ekansh's answer to your other question.
I am using Dropzonejs to add image upload functionality in a Form, as I have various other fields in form so I have set autoProcessQueue to false and Processing it on click on Submit button of Form as shown below.
Dropzone.options.portfolioForm = {
url: "/user/portfolio/save",
previewsContainer: ".dropzone-previews",
uploadMultiple: true,
parallelUploads: 8,
autoProcessQueue: false,
autoDiscover: false,
addRemoveLinks: true,
maxFiles: 8,
init: function() {
var myDropzone = this;
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
}
}
This works fine and allows me to process all images sent when form is submitted. However, I also want to be able to see images already uploaded by user when he edits the form again. So I went through following post from Dropzone Wiki.
https://github.com/enyo/dropzone/wiki/FAQ#how-to-show-files-already-stored-on-server
Which populates dropzone-preview area with existing images but it does not send existing images with form submit this time. I guess this is because theses images are not added in queue but If it's so then how can update on server side, In case an existing image is removed by user?
Also, what would be the better approach, add already added images in queue again or just send information of removed file?
I spent a bit of time trying to add images again, but after battling with it for a while I ended up just sending information about the deleted images back to the server.
When populating dropzone with existing images I attach the image's url to the mockFile object. In the removedfile event I add a hidden input to the form if the file that is being removed is a prepopulated image (determined by testing whether the file that is passed into the event has a url property). I have included the relevant code below:
Dropzone.options.imageDropzone = {
paramName: 'NewImages',
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
init: function () {
var myDropzone = this;
//Populate any existing thumbnails
if (thumbnailUrls) {
for (var i = 0; i < thumbnailUrls.length; i++) {
var mockFile = {
name: "myimage.jpg",
size: 12345,
type: 'image/jpeg',
status: Dropzone.ADDED,
url: thumbnailUrls[i]
};
// Call the default addedfile event handler
myDropzone.emit("addedfile", mockFile);
// And optionally show the thumbnail of the file:
myDropzone.emit("thumbnail", mockFile, thumbnailUrls[i]);
myDropzone.files.push(mockFile);
}
}
this.on("removedfile", function (file) {
// Only files that have been programmatically added should
// have a url property.
if (file.url && file.url.trim().length > 0) {
$("<input type='hidden'>").attr({
id: 'DeletedImageUrls',
name: 'DeletedImageUrls'
}).val(file.url).appendTo('#image-form');
}
});
}
});
Server code (asp mvc controller):
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ViewModel viewModel)
{
if (ModelState.IsValid)
{
foreach (var url in viewModel.DeletedImageUrls)
{
// Code to remove the image
}
foreach (var image in viewModel.NewImages)
{
// Code to add the image
}
}
}
I hope that helps.
To extend on Teppic's answer, I found you needed to emit the complete event to remove the progress bar on the preview.
var file = {
name: value.name,
size: value.size,
status: Dropzone.ADDED,
accepted: true
};
myDropzone.emit("addedfile", file);
myDropzone.emit("thumbnail", file, value.path);
myDropzone.emit("complete", file);
myDropzone.files.push(file);
just use myDropzone.addFile(file)
from dropzone source code https://github.com/enyo/dropzone/blob/4e20bd4c508179997b4b172eb66e927f9c0c8564/dist/dropzone.js#L978
There's an official FAQ for that here
I solved this using the dropzone's built in "displayExistingFile" method.
in your init: function.
Create the mockfile
let mockFile = { name: file.title, size: file.size, dataURL:};
Call the displayExistingFile function
this.displayExistingFile(mockFile, , null, 'anonymous')
Instead of 'null' you can place a callback to respond to the thumbnail load event.
The 'anonymous' is for the cross origin property.
Originally I was doing this to programmatically upload a pre-existing file:
myDropzone.emit("addedfile", imageFile);
myDropzone.emit("thumbnail", imageFile, imageUrl);
myDropzone.files.push(file);
However, referencing this Dropzone Github Issue I found an easier way to directly upload:
myDropzone.uploadFiles([imageFile])
Unfortunately there are no references to this uploadFiles method in the Dropzone Documentation, so I figured I'd share some knowledge with all you Dropzone users.
Hope this helps someone
If you have the URL of the file, you can add the file with addFile.
fetch("url")
.then(res => res.blob())
.then((currentBlob) => {
const generateFile = new File([currentBlob], "filename.jpg", {
type: currentBlob.type,
});
myDropzone.addFile(generateFile);
});
On click of upload files just clear the files from dropzone.
All Files can be cleared using removeAllFiles() or specific file also you can delete by using removeFile(fileName).
i'm using dropzone to build an interface to an online storage api, for uploading files. I've to upload multiple files and to make an ajax call everytime a file is uploaded so that an input field of the hidden form below get added. It's not a big deal for itself, i just have to add a call to the init property of dropzone (i'm not creating a custo dropzone, i'm just using the default one). So at line 1581 i wrote:
Dropzone.options = {
init: function() {
this.on("addedfile", function(file) { alert("added file"); });
}
};
but when i add i file to the dropzone nothing happens.
I'm processing multiple files, so am I calling the wrong event? maybe should i call successmultiple? this is the dropzone tutorial. Any idea?
if you have a form, with an id="my-awesome-dropzone" like in the example
<form action="/file-upload"
class="dropzone"
id="my-awesome-dropzone"></form>
You have to create a config object in the same document, i.e. in the header
<script src="./path/to/dropzone.js"></script>
<script >
//"myAwesomeDropzone" is the camelized version of the HTML element's ID
Dropzone.options.myAwesomeDropzone = {
init: function() {
this.on("addedfile", function(file) { alert("Added file."); });
}
};
</script>
If instead of this, you are creating the dropzone by
var myDropzone = new Dropzone("form.myFormClass"); //or something like this
you have to add the options as the second parameter
var myDropzone = new Dropzone("form.myFormClass", {
init: function() {
this.on("addedfile", function(file) { alert("Added file."); });
}
});
With jquery button click i need to cancel(drop, discard) file that i choose to upload
Here is my jquery code:
$('.upic9').bind('click', { imgId: $(this).attr('id') }, function (evt) {
$('.fileselectionbox').empty();
});
you can use jQuery File Upload plugin
I guess this can works in your case.
jQuery File Upload plugin
probably this code example will help you.
I'm not sure if html5 works for your case, if not see link above
$('#html5FileInput').fileupload({
....
add: function (e, data) {
$.each(data.files, function (index, file) {
var newFileDiv = $(newfileDiv(file.name));
$('#fsUploadProgressHtml5').append(newFileDiv);
newFileDiv.find('a').bind('click', function (event) {
event.preventDefault();
var uploadFilesBox = $("#fsUploadProgressHtml5");
var remDiv = $(document.getElementById("fileDiv_" + event.data.filename));
removeFileFromArray(event.data.filename);
remDiv.remove();
data.files.length = 0;
...
});
data.context = newFileDiv;
});
...
)};
or see this