简体   繁体   中英

Strange behavior with click event on button?

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?

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.

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;
   }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM