Reputation: 169
I am using jQuery File Upload plugin here for uploading files.
For each file that is added I generate a row in the table with a hidden button (that would be the single upload button for each file in the row) and another button for removing the file.
My code is below:
var addedFiles = 0;
var uploadedFiles = 0;
$('#uploadFile').fileupload({
replaceFileInput: false,
singleFileUploads: true,
autoUpload: false,
add: function (event, data) {
$.each(data.files, function (index, file) {
data.url = 'myUrl';
data.type = 'POST';
data.context = $('<tr><td><strong>Selected File : </strong>' + file.name + '</td><td><button name=singleuploadFile type="button" class="hidden">' +
'</button></td><td><button id=' + file.name + ' name=removeFile type="button" class="btn btn-default"><span class="glyphicon glyphicon-remove-circle">' +
'</span>Remove File</button></td></tr>')
.appendTo('#files');
$('button[name="singleUploadFile"]').click(function () {
if (data.files.length > 0) {
data.submit();
addedFiles += 1;
}
});
$('button[name="removeFile"]').on("click", function () {
var fileToRemoveId = this.id;
if (fileToRemoveId == data.files[0].name) {
data.files.splice(0, 1);
$(this).closest('tr').remove();
}
});
});
},
done: function () {
uploadedFiles += 1;
if (addedFiles == uploadedFiles) {
alert("All Files Uploaded");
addedFiles = 0;
uploadedFiles = 0;
}
}
});
$('#uploadAllFiles').on("click", function () {
$('button[name="singleUploadFile"]').click();
});
So you can see each individaul button for the file for Upload has a name of singleUploadFile but that button is hidden - I dont want the User to Upload Files individually. But I have a button called Upload All Files which when clicking I trigger the click event for any button with a name=singleuploadFile.
The functionality for this works and my files upload. The problem is my alert for the done function. in the click event for singleFileUpload I have a variable called addedFiles which gets incremented each time this event is hit. The done function will get called each time a file successfully uploads so I also have a variable in there called uploadedFiles - once they are equal I know that all files have uploaded so i can display this to the user. This works if I have one file and I get one created with 1 hidden singleFileUpload button. The addedFiles variable gets set to 1 and when hitting done function the uploadFiles variable is 1 and the alert fires.
However when I have 2 files - the singleFileUpload handler gets hit 3 times - the addedFiles variable therefore is 3 - done function gets hit twice as expected so uploadedFiles variable is 2 so my alert doesnt fire. For 3 files - the singleFileUpload event gets hit 6 times. For 4 files it gets hit 10 times and for 5 files it gets hit 15 times.
Cant figure out why when I have more that one row, why the click all button is triggering the singleUploadfile button the incorrect amount of times?
Upvotes: 0
Views: 168
Reputation: 21482
The following code binds the event to all buttons with the name "singleUploadFile".
$('button[name="singleUploadFile"]').click(function () {
if (data.files.length > 0) {
data.submit();
addedFiles += 1;
}
});
But you want it to bind the event just to the newly added button (not to buttons that already have it bound).
Do the following:
data.context.find('button[name="singleUploadFile"]').click(function () {
if (data.files.length > 0) {
data.submit();
addedFiles += 1;
}
});
Upvotes: 0
Reputation: 2536
try this change this event binding
$('button[name="singleUploadFile"]').click(function (){// Do Stuff}
to
$(document).on('click','button[name="singleUploadFile"]', function (){// Do stuff});
What i think is the bug is,
you are binding the events to buttons with [name="singleUploadFile"]
to a click event, b ut the dom elements that are already in the page at page load gets binded to this event twice, thus on a single click the event gets triggered more than once.
What you should do is
Modify this code
$('button[name="singleUploadFile"]').click(function () {
if (data.files.length > 0) {
data.submit();
addedFiles += 1;
}
});
$('button[name="removeFile"]').on("click", function () {
var fileToRemoveId = this.id;
if (fileToRemoveId == data.files[0].name) {
data.files.splice(0, 1);
$(this).closest('tr').remove();
}
});
so that all the events get binded to the document, so that only on event fire only one function gets executed.
Upvotes: 1