PeraMika
PeraMika

Reputation: 3678

Laravel 5.2 & Dropzone.js - Remove (Delete) uploaded images

In routes.php I have the following routes:

Route::post('dropzone', ['as' => 'dropzone.upload', 'uses' => 'AdminPhotoController@dropzoneUpload']);
Route::post('dropzone/delete', ['as' => 'dropzone.delete', 'uses' => 'AdminPhotoController@dropzoneDelete']);

In AdminPhotoController.php I did in the following way:

public function dropzoneUpload(Request $request)
{
    if($request->ajax()) {  // hmm, do I really need this?
        if ($request->hasFile('file') && $request->file('file')->isValid()) {
            $image_file = $request->file('file');
            $image_name = time() . '_' . $image_file->getClientOriginalName();
            $destinationPath = 'images/photos';

            if ($image_file->move($destinationPath, $image_name)) {
                $photo = new Photo(['file_name' => $image_name, 'title' => 'No title', 'description' => 'No description']);
                \Auth::user()->photos()->save($photo);

                return \Response::json('success', 200);
            } else {
                return \Response::json('error', 400);
            }
        }
    }
}

Finally, here are my HTML & JS:

<div class="dropzone" id="dropzoneFileUpload">
</div>

<script type="text/javascript">

    Dropzone.autoDiscover = false; // to disable the auto discover behaviour of Dropzone (sami ga definisemo ispod)

    var myDropzone = new Dropzone("div#dropzoneFileUpload", {
        url: "{{ route('dropzone.upload') }}",
        headers: {
            'X-CSRF-TOKEN': '{!! csrf_token() !!}'
        }
    });

</script>

And it works, uploading files works. But I would like to have the remove links for deleting uploaded images. I was reading the official documentation on http://www.dropzonejs.com/ but I still don't understand how to do it. I see that there are:

So I started like this but I don't know how to do it, how to delete those images:

    Dropzone.options.dropzoneFileUpload = { // div has id=dropzoneFileUpload?
        addRemoveLinks: true,  // but still link to delete is not displayed?
        dictRemoveFile: 'Remove'
    };

    myDropzone.on("complete", function(file) {
        myDropzone.removeFile(file); // What should I do here?
    });

.


EDIT:

If I remove this code:

    Dropzone.autoDiscover = false;

    var myDropzone = new Dropzone("#my-dropzone", {
        url: "{{ route('dropzone.upload') }}",
        headers: {
            'X-CSRF-TOKEN': '{!! csrf_token() !!}'
        }
    });

solution that that @Manuel Azar gave will work, Remove Links are now displayed (for each uploaded image). So, there is some problem with this code, something is missing.

Upvotes: 2

Views: 6892

Answers (1)

Manuel Azar
Manuel Azar

Reputation: 863

Take a look at this answer to help you understand the dropzone events:

https://stackoverflow.com/a/19454507/4734404

Then you should add an action to your controller for your delete request to remove the image from DB and disk:

public function dropzoneRemove(Request $request)
{
    if($request->ajax()) { 
        $photo = Photo::find($request->photoId); //Get image by id or desired parameters

        if(File::exists($destinationPath.$photo->file_name)) //Check if file exists
            File::delete($destinationPath.$photo->file_name) //Delete file from storage
            
        $photo->delete()   //Delete file record from DB

        return response('Photo deleted', 200); //return success
    }
}

I would recommend you to take a look at laravel's Storage facade, to keep your files well organized in your filesystem.

https://laravel.com/docs/5.2/filesystem

EDIT:

How to add a button to remove each file preview?

Starting with Dropzone version 3.5.0, there is an option that will handle all this for you: addRemoveLinks. This will add an Remove file element to the file preview that will remove the file, and it will change to Cancel upload if the file is currently being uploaded (this will trigger a confirmation dialog).

You can change those sentences with the dictRemoveFile, dictCancelUpload and dictCancelUploadConfirmation options.

If you still want to create the button yourself, you can do so like this:

<form action="/target-url" id="my-dropzone" class="dropzone"></form>

<script>
    // myDropzone is the configuration for the element that has an id attribute
    // with the value my-dropzone (or myDropzone)
    Dropzone.options.myDropzone = {
        init: function() {
            this.on("addedfile", function(file) {

                // Create the remove button
                var removeButton = Dropzone.createElement("<button>Remove file</button>");


                // Capture the Dropzone instance as closure.
                var _this = this;

                // Listen to the click event
                removeButton.addEventListener("click", function(e) {
                    // Make sure the button click doesn't submit the form:
                    e.preventDefault();
                    e.stopPropagation();

                    // Remove the file preview.
                    _this.removeFile(file);
                    // If you want to the delete the file on the server as well,
                    // you can do the AJAX request here.
                });

                // Add the button to the file preview element.
                file.previewElement.appendChild(removeButton);
            });
        }
    };
</script>

From FAQ: https://github.com/enyo/dropzone/wiki/FAQ#how-to-add-a-button-to-remove-each-file-preview

More info here about customizing dropzone properties: http://www.dropzonejs.com/#layout

EDIT 2

The problem is here:

Dropzone will find all form elements with the class dropzone, automatically attach itself to it, and upload files dropped into it to the specified action attribute. http://www.dropzonejs.com/#usage

Alternatively you can create dropzones programmaticaly (even on non form elements) by instantiating the Dropzone class http://www.dropzonejs.com/#create-dropzones-programmatically

Dropzone.autoDiscover = false; // to disable the auto discover behaviour of Dropzone (sami ga definisemo ispod)

var myDropzone = new Dropzone("div#dropzoneFileUpload", {

I believe you have two instances of Dropzone because you are creating another Dropzone object. You should stick to the quick config and edit the options directly, and remove autoDiscover = false, instead of doing it programatically.

if your dropzone element id is 'my-awesome-dropzone':

<form action="/file-upload"class="dropzone" id="my-awesome-dropzone"></form>

Dropzone automatically will create a property with the camelized id name 'myAwesomeDropzone' and attach it to the current object.

So you set the Dropzone options by doing:

//myAwesomeDropzone = camelized version of ID = my-awesome-dropzone
Dropzone.options.myAwesomeDropzone = { 
    addRemoveLinks: true
}

I've made this plunker with minimun setup for you, just add your request config like you did before and it should work, i set the addRemoveLinks to true so you can see that they are working:

https://plnkr.co/edit/9850jCOpTwjSSxI1wS1K?p=info

Upvotes: 2

Related Questions