Uploading multiple files from multiple input field

2019-05-24 17:16发布

问题:

I'm trying to use the blueimp/jQuery-File-Upload plugin to store images in a server via a PHP uploads handler. I've been following this posts in order to make it work:

  • https://github.com/blueimp/jQuery-File-Upload/wiki/API
  • https://github.com/blueimp/jQuery-File-Upload/wiki/Multiple-File-Input-Fields-in-One-Form
  • Sending multiple file input fields programmatically in one form
  • BlueImp Plugin jQuery File Upload : How to use the fileInput option so that fileupload() can bind new dynamically added inputs?

The file upload form I'm using, has multiple dynamically added file input fields. As an example, after adding 3 fields:

<form id="entry_form" class="entry-form" role="form">
    <div class="entry">
        ...
        <input type="file" class="file-upload" name="files0[]" multiple>
        ...
    </div>
    <div class="entry">
        ...
        <input type="file" class="file-upload" name="files1[]" multiple>
        ...
    </div>
    <div class="entry">
        ...
        <input type="file" class="file-upload" name="files2[]" multiple>
        ...
    </div>
</form>

<div class="col-xs-6 col-sm-4">
    <button id="save_btn" class="btn btn-lg btn-block">Save</button>
</div>

I can successfully upload files from this fields using the following JS code:

var imageUpload = {
    init: function (selector, context, options) {

        selector = selector || '.file-upload';
        context = context || $('.entry');

        var filesList = [];
        var url = site_url + '/doUpload';

        $(selector).fileupload(options || {
            url: url,
            type: 'POST',
            dataType: 'json',
            autoUpload: false,
            singleFileUploads: false,
            formData: {},

            add: function (e, data) {
                for (var i = 0; i < data.files.length; i++) {
                    filesList.push(data.files[i]);
                }

                return false;
            }
        }).on('change', function () {
            $(this).fileupload('add', {
                fileInput: $(selector)
            });
        });

        $('#save_btn').click(function (e) {
            e.preventDefault();

            $(selector).fileupload('send', {files: filesList});
        });
    }
};

As you can see in the 'add:' event callback and the 'send' method near the end, I'm sending all files in one POST to the server, this is the intended functionality. My problem is that the $_FILES server side variable is reaching the server in the following way:

$_FILES array[1]        
    [files0]    array[1]        
        [name]  array[1]        
            [0] string  "Collapse.png"  
            [1] string  "Expand.png"    
            [2] string  "Map.jpg"

In this way, I can't relate which image was added to which input. So, what I'd need to get to the server is something like this:

$_FILES array[3]        
    [files0]    array[1]        
        [name]  array[1]        
            [0] string  "Collapse.png"  
    [files1]    array[1]        
        [name]  array[1]        
            [0] string  "Expand.png"    
    [files2]    array[1]        
        [name]  array[1]        
            [0] string  "Map.jpg"

I have been looking for a solution to this for a while and haven't reached the desired result. Can you help me please?

Thanks!

回答1:

It seems you have to manually add the array keys,

Something roughly like...

        add: function (e, data) {
            for (var i = 0; i < data.files.length; i++) {
                filesList['files'+ i].push(data.files[i]);
            }


回答2:

Solved after reading this post: Uploading multiple files asynchronously by blueimp jquery-fileupload

All it was needed was to save the input field name into a 'paramNames' variable to send it alongside the 'filesList' variable.

Updated working code:

var imageUpload = {
init: function (selector, context, options) {

    selector = selector || '.file-upload';
    context = context || $('.entry_form');

    var filesList = [],
        paramNames = [];
    var url = site_url + '/doUpload';

    $(selector, context).fileupload(options || {
        url: url,
        type: 'POST',
        dataType: 'json',
        autoUpload: false,
        singleFileUploads: false,
        add: function (e, data) {
            for (var i = 0; i < data.files.length; i++) {
                filesList.push(data.files[i]);
                paramNames.push(e.delegatedEvent.target.name);
            }

            return false;
        },
        change: function (e, data) {

        },
        done: function (e, data) {

        }

    });
    $('#save_btn').click(function (e) {
        e.preventDefault();

        $(selector, context).fileupload('send', {files:filesList, paramName: paramNames});
    });
}
};