Search code examples
jqueryajaxcodeigniterdropzone

Upload Dropzone files using a jQuery AJAX form with other data


In my project a registered user should be able to add news via a jQuery AJAX form, at the same time he could select and upload multiple images that will be attached to the post.

I'm using Codeigniter 3, jQuery and I'm trying to add Dropzone to select and preview the pictures. What I'm aiming to do is to attach the Dropzone selected files to the jQuery AJAX form and sent files and data when submit button is clicked.

The jQuery form works fine so far to send the text data, the code is the following:

$('#news_form').on("submit",function(e){
    e.preventDefault();
    var form_action = `${HOST_URL}/news/add_post`;
    var fdata = new FormData(this);
    fdata.append(token_name, token_hash);
    fdata.append('file', $('#file_dropzone')[0].dropzone.getAcceptedFiles()[0]);
    
    $.ajax({
        url: form_action,
        type: 'POST',
        data: fdata,
        processData:false,
        contentType: false,
        cache: false,
        dataType:'json',
    })
    .done(function(data){            
        if(data.status){
            $("#news_form")[0].reset();
            $( ".telegram_input" ).prop( "disabled", true );
            toastr.success(data.toastmsg, 'Success!', {timeOut: 5000});
        }else{   
            toastr.error(data.toastmsg, 'Error!', {timeOut: 5000});
        }
    })
    .fail(function(data) {
        toastr.error(data.toastmsg, 'Error!', {timeOut: 5000});
    })
    .always(function(data) {
        token_hash = data.csrf_test_name;
    });
});

In the cose above I've added the Dropzone selected files with the following row:

fdata.append('files', $('#file_dropzone')[0].dropzone.getAcceptedFiles()[0]);

To initialize the Dropboz area I'm using the following code:

"use strict";
var LIDBDropzone = function () {
    // Private functions
    var dropfile = function () {
        Dropzone.autoDiscover = false;

        var myDropzone = new Dropzone(".dropzone", {
            url: '',
            autoProcessQueue: false,
            paramName: "files",
            maxFilesize: 1,
            maxFiles: 5,
            acceptedFiles: ".jpeg,.jpg,.png",
            parallelUploads:10,
            uploadMultiple:true,
        });
    }

    return {
        init: function() {
            dropfile();
        }
    };
}();

KTUtil.ready(function() {
    LIDBDropzone.init();
});

The Dropzone HTML code is below:

<div class="dropzone dropzone-default dropzone-primary" id="file_dropzone">
    <div class="dropzone-msg dz-message needsclick">
        <h3 class="dropzone-msg-title">Drop files here or click to upload.</h3>
        <span class="dropzone-msg-desc">Upload up to 10 files</span>
    </div>
</div>

The issue arise when I try to send the form and data and files are processed by the Codeigniter function below:

# Count uploaded files
$countfiles = count($_FILES['files']['name']);

# Do the dirt job ... upload all the pictures
for($i=0;$i<$countfiles;$i++)
{               
    if(!empty($_FILES['files']['name'][$i]))
    {
        // Define new $_FILES array - $_FILES['file']
        $_FILES['file']['name'] = $_FILES['files']['name'][$i];
        $_FILES['file']['type'] = $_FILES['files']['type'][$i];
        $_FILES['file']['tmp_name'] = $_FILES['files']['tmp_name'][$i];
        $_FILES['file']['error'] = $_FILES['files']['error'][$i];
        $_FILES['file']['size'] = $_FILES['files']['size'][$i];
        
        # Load and configure upload library
        $this->load->library('upload');
        $config = array(
                'upload_path'      => $upload_path,
                'allowed_types'    => 'jpg|png',
                'max_size'         => '250', // 250Kb
                'max_width'        => '1400',
                'max_height'       => '1200',
                //'file_name'        => $filename,
                'encrypt_name'     => TRUE,
                'overwrite'        => false,
                'file_ext_tolower' => true
                );
        $this->upload->initialize($config);
                    
        # Upload each file
        if (!$this->upload->do_upload('file'))
        {
            $jsondata['status'] = FALSE;
            $jsondata['error'] = TRUE;
            $jsondata['toastmsg'] = $this->upload->display_errors();
            die(json_encode($jsondata));
        }

        $data = $this->upload->data(); 
        
        $picture = $data['file_name'];
        # End upload
    }
}

The error that I get is the following:

A PHP Error was encountered
Severity: Warning

Message: count(): Parameter must be an array or an object that implements Countable

so it seems that no files are passed to the PHP code.

The questions are:

  • is it possible to achieve what I need? So, how to append selected Dropzone files to a jQuery AJAX form?

Thanks a lot for any help


Solution

  • You should count the elements (files) in the super global $_FILES['files'] that will give you the count of uploaded files not $_FILES['files']['name']