simioluwatomi's avatar

Dropzone and Laravel

I have a form. It has two dropzones. Each dropzone is for different file types; the first is for audio files and the second is for image files. Then the form has other input fields that need to be saved in the database.

Each dropzone is supposed to receive only one file at a time. So that the audio file can be associated with the image file; and they both can be associated with other form data that is submitted by the user.

Is there anyone here who has done something like this before? How did you go about it? Thank you

0 likes
5 replies
mikefolsom's avatar

Using this setup, I believe you will end up with three POST requests: two AJAX requests for the Dropzone uploads and a third for your primary form, all of which you will somehow have to piece back together. I do understand that submitting everything in the same request is not ideal, because if you have large file uploads (audio and image files) that fail for some reason, it can hang the browser for quite awhile before giving feedback, which is not a very good user experience.

I would normally create the primary database record first (submitting the main form), then put the Dropzone forms on a second page. That way, you can use your database record's primary key (for example) in the upload URL. This makes it easy to associate the uploaded files with the primary record.

jlrdw's avatar

Decide which you want first, add that, let other be an edit to same record.

simioluwatomi's avatar

@mikefolsom I understand your points but each dropzone would be limited to one file per upload. The maxFile would be one for each dropzone.

Then I found an answer here https://stackoverflow.com/questions/22048353/uploading-multiple-single-files-using-separate-dropzones-in-one-form after much digging.

Answer is by Enyo and it says

"The problem is not that the fields are appended to the body, but that the whole Dropzone uploading process is different from a normal form submission.

You can not use Dropzone to drop files in the browser, and then use the normal form submit to submit it.

There are two ways to accomplish what you are doing:

Don't let the user submit the form until all your files in the Dropzones have uploaded (or better yet: create event listeners on all your Dropzones that will fire the submit function on the form as soon as all Dropzones have uploaded). You need to store the files on your server and wait for the actual form submission to assemble the data.

This is by far the most elegant solution, because this way the files are already uploading while the user may still be editing form data. Create one Dropzone on the actual form, that will handle the whole uploading of the form via AJAX. (See the docs for that). If you want different dropzone targets inside that dropzone, you'll have to create them separately, and "delegate" the file drops to the main dropzone (basically, just take the file object, and add it to the main Dropzone)."

The first option looks like what I want to do. The problem now is how do I do it?

mikefolsom's avatar

You would need to use JavaScript to prevent the form from submitting until both Dropzone uploads are successfully processed. Then use JS to append hidden elements with some kind of identifier (file name/hash?) for each upload (which would be returned from your upload PHP scripts to the main page in the AJAX response). Then when the main form is submitted, the hidden fields would allow you to associate the uploaded files with your main form data.

simioluwatomi's avatar

So I decided to use Dropzone to upload an image. What I get is error 500.

My code


<form action="{{ url('dropzone/upload') }}" method="POST" enctype="multipart/form-data" class="dropzone dropzone-file-area" id="my-dropzone" style="width: 500px; margin-top: 50px; margin-bottom:100px">

<h3 class="sbold">Drop files here or click to upload</h3>

 <p> This is just a demo dropzone. Selected files are not actually uploaded. </p>

</form>

Route


Route::post('dropzone/upload', 'MessageController@dropzoneStore');
                       

MessgeController


public function dropzoneStore(Request $request)
    {
        $image = $request->file('file');
        $imageName = time().$image->getClientOriginalName();
        $image->move(public_path('images'),$imageName);
        return response()->json(['success'=>$imageName]);
    }
                       

My dropzone javascript config


Dropzone.autoDiscover = false;
$(document).ready(function () {
    Dropzone.autoDiscover = false;
    $("#my-dropzone").dropzone({
        maxFilesize: 1,
        dictResponseError: "Error uploading file.",
        dictInvalidFileType: "You can't upload files of this type.",
        paramName: "file",
        dictFileTooBig: "File size is too large. Maximum filesize is 50MB.",
        acceptedFiles: ".jpeg,.jpg,.png,.gif",
        headers: {
        'X-CSRFToken': $('meta[name="token"]').attr('content')
        },
    });
});
                       

Please or to participate in this conversation.