7

I have an issue using the JQuery-File-Upload plugin. I am using the plugin directly and not through the author's provided html example pages. Basically I have a form with some inputs one of which is a file input. The first upload works fine but when I attempt a second upload both files are sent (the first one for the second time) when it should only be the second one.

Example:

  • File 1 is selected.
  • File 1 is uploaded.
  • Success.
  • Using jquery I reset the form with $(FORM_SELECTOR).trigger('reset')
  • File 2 is selected.
  • File 1 and file 2 are BOTH uploaded.
  • Problem.

Now I have two copies of file 1. This is not what I want.

Obviously there isn't much point of using an ajax form upload if it only works once so I assume that there is something I am missing.

Is there a way to reset the file queue?

When examining the data.files object I can see that the files are there after the form is reset. What can I do to sync the plugin with the input or clear out the data.files. If I manually clear out the data.files array (via pop or data.files = []) attempting a second upload does not work.

I init the upload form like this:

    $('#file-upload-form').fileupload({
    url: 'uploads/upload',
    type: 'POST',
    dataType: 'json',
    multipart: true,
    dropZone: null,
    formAcceptCharset: 'utf-8',
    autoUpload: true,
    add: function (e, data) {
        fileUploadData = data;
        $("#upload-file-btn").click(function () {
            data.submit()
                .success(function (e, status, data) {
                    console.log("success response from post", status, data);
                    var i = '<input id="file-select-input" name="files[]" multiple/>';
                    $('#file-select-input').replaceWith(i);
                })
        });
    }
});
etteyafed
  • 211
  • 1
  • 2
  • 9
  • you could replace the input http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery – Mx. Aug 26 '14 at 14:07
  • Thanks. Replacing the input basically accomplishes something similar to triggering the reset. I have replaced the input before but the plugin will still upload both files. – etteyafed Aug 26 '14 at 14:25
  • and after that the input contains a file ? you can check via the dev tools console and `$("yourinput").val()` http://liveweave.com/Zz8TK0 – Mx. Aug 26 '14 at 14:37
  • Did you find a solution to this? This is by far the most common issue regarding this library that's posted, and I haven't found a single clear answer. The documents don't touch on this at all. It's amazing how poorly documented such a core functionality is. – Andrew Mar 16 '15 at 21:10
  • I never got this to work. I eventually just used the file api directly and dropped support for older browsers. I didn't find any file upload plugins that didn't fail on an edge case that I needed to support. Sorry, no answer. – etteyafed Jul 26 '15 at 14:36

5 Answers5

1

I have a custom .add event handler, in which I have called .off("click") on my button:

                add: function (e, data) {

                    $('#btnstartupload').off("click");
                    data.context = $('#btnstartupload')
                        .click(function () {
                            data.submit();
                            $(".fileinput-button").hide();
                        });
}
Fabio Napodano
  • 1,210
  • 1
  • 16
  • 17
1

I had the same problem and the only way I've managed to solve that was to check in the submit callback if the file was already uploaded. I just check if the file name is included in the array fileNames which I push the current file name before the submission and checks on the next time if the next one is present on the array and if so cancel the submission.

var fileNames = new Array();

$('#uploadfile').fileupload({
  submit: function(e, data) ->
    var fileName = data.files[0].name;
    if ($.inArray(fileName, fileNames) === -1)
      fileNames.push(fileName);
    else
      return false;
});
Kevin Crowell
  • 10,082
  • 4
  • 35
  • 51
0

You can reset inputs quite easy. If that does not work for you, you might store the file somwhere.

DEMO

$("button#1").click(function(){
  //check file
    alert($("input").val());
      return false;
});
$("button#2").click(function(){
  //reset form
    $("form")[0].reset();
      return false;
}); 
$("button#3").click(function(){
  //replace input
    $("input").replaceWith($('<input type="file"/>'));
    return false;
}); 
Mx.
  • 3,588
  • 2
  • 25
  • 33
  • Thanks but if you read my response to your comment you will see that the issue isn't with clearing the actual file input but the plugin itself. I have not had any problem resetting the file input itself. Either via replace or the reset trigger. In other words I have already tried exactly what you are recommending with no effect. – etteyafed Aug 26 '14 at 14:48
  • 1
    I think this issue is with the plugin since replacing the input SHOULD do what we expect. In fact it does. It clears the file input but the plugin STILL uploads both files. – etteyafed Aug 26 '14 at 14:52
  • And you are surely resetting your form ? – Mx. Aug 26 '14 at 14:53
  • Because `$('input[type="file"]').trigger('reset');` does nothing in my example. – Mx. Aug 26 '14 at 14:54
  • Maybe it wasn't working although I know sending the reset event to the form itself will do it. Even with the replace I'm not seeing the desired results. – etteyafed Aug 26 '14 at 15:02
  • If it's not saved in the input nor in the form - where is it saved then ? May you should upload all your code somewhere. – Mx. Aug 26 '14 at 15:16
  • It is apparently being saved (somehow) by the plugin and I have provided a link to that in the question. I can't exactly paste the application code for a variety of reasons. I really appreciate your time on this. The bit of code in the question is the only thing I have that is dealing with the form though. So that should be sufficient. If anyone can reproduce my issue that might help. – etteyafed Aug 26 '14 at 15:25
  • me too.. If I'll find a solution, I will post it as an answer here – Fabio Napodano Jul 25 '15 at 09:48
  • I have found a solution which works for me. see my answer – Fabio Napodano Jul 25 '15 at 10:12
0

I ran into the same problem. It's puzzling why the library re-sends previously uploaded files. I tried to destroy it, re-initialize it and clear/reset the actual file input field, but none of them worked.

The solution I came up with is to keep track of all upload attempts by storing file names in an array and checking in the "send" callback if a file has been already uploaded.

Callback:

send: function (e, data) {
            var file = data.files[0];

            // if we already attempted to upload a file with the same file name
            // do not send it in order to avoid duplicates
            if (existsInAttemptedUploads(file.name)) {
                return false;
            }
        },

Helper methods:

// list of file names that a user attempted to upload
var attemptedUploads = [];

// adds a file name to the list of attempted uploads
function addAttemptedUpload(fileName) {
    attemptedUploads.push(fileName);
};

// removes a given file name from the list of attempted uploads
function removeAttemptedUpload(fileName) {
    var index = $.inArray(fileName, attemptedUploads);

    if (index > -1) {
        attemptedUploads.splice(index, 1);
    }
};

// checks if a given file name is in the list of attempted uploads
function existsInAttemptedUploads(fileName) {
    var result = $.inArray(fileName, attemptedUploads);

    if (result == -1) {
        return false;
    }

    return true
};

Make sure to update the list of attemptedUploads in your "done" and "fail" callbacks and remove a file from the list if it was removed. For example:

done: function (e, data) {
            var id = e.target.id;

            // List all uploaded files
            $.each(data.result.files[0], function (index, file) {
                // add the current file name to the list of attempted file names
                addAttemptedUpload(file.origFileName);

                $('#uploadedFiles').append('<li id="' + file.id + '" data-orig-filename="' + file.origFileName + '">' + file.fileName + ' <a class="removeFile" href="<?php echo $deleteUrl; ?>/' + file.id + '">' + ' Remove</a></li>');
            });
        },
Patryk K
  • 57
  • 3
-1

My code like that, when clicking the Remove link into the multiple file from JSP page, It's OK for IE11, Chrome and Firefox.

function removeFileLink(id) {
   var fileName = document.getElementById("import_file_" + id).value.replace(/^.*[\\\/]/, '');
   var objFiles = document.getElementsByName("import_fileList");
   for(var i=0; i<objFiles.length; i++){
       if(objFiles[i].value.replace(/^.*[\\\/]/, '') == fileName) {
           $(objFiles[i]).remove();                        
       }
   }
   document.getElementById("import_form").enctype="multipart/form-data";
   document.getElementById("import_form").submit();           
   return false;          
}
Nyeint
  • 11
  • 2