Dropzone.js - Display existing files on server
Asked Answered
I

7

12

I'm currently using dropzone.js v3.10.2 I am having issues displaying my existing files I have already uploaded. I am more than competent with php however I have limited knowledge when it comes to ajax and js

If you could help that would be awesome

Thanks in advance

index.php

    <html>

<head>  

<link href="css/dropzone.css" type="text/css" rel="stylesheet" />


<script src="ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

<script src="dropzone.min.js"></script>

<script>

Dropzone.options.myDropzone = {
    init: function() {
        thisDropzone = this;

        $.get('upload.php', function(data) {


            $.each(data, function(key,value){

                var mockFile = { name: value.name, size: value.size };

                thisDropzone.options.addedfile.call(thisDropzone, mockFile);

                thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name);

            });

        });
    }
};
</script>

</head>

<body>


<form action="upload.php" class="dropzone" id="my-dropzone"></form>

</body>

upload.php

<?php
$ds          = DIRECTORY_SEPARATOR; 

$storeFolder = 'uploads';  

if (!empty($_FILES)) {

    $tempFile = $_FILES['file']['tmp_name'];         

    $targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds; 

    $targetFile =  $targetPath. $_FILES['file']['name']; 

    move_uploaded_file($tempFile,$targetFile);

} else {                                                           
    $result  = array();

    $files = scandir($storeFolder);                 //1
    if ( false!==$files ) {
        foreach ( $files as $file ) {
            if ( '.'!=$file && '..'!=$file) {       //2
                $obj['name'] = $file;
                $obj['size'] = filesize($storeFolder.$ds.$file);
                $result[] = $obj;
            }
        }
    }

    header('Content-type: text/json');              //3
    header('Content-type: application/json');
    echo json_encode($result);
}
?>

PS. I know the php is retrieving the data

Thanks in advance

Damian

Infuse answered 3/6, 2014 at 7:23 Comment(2)
Hi Damian, I checked the code (from startutorial) with the most recent version of jquery 1.x and I see an error. Did you try using firebug or asking the guy who wrote the tut?Stroganoff
github.com/enyo/dropzone/wiki/…Kreisler
S
18

I checked the code (from starTutorial) and it didn't work for me either(?)

I managed to get it working by replacing this:

$.get('upload.php', function(data) {
  $.each(data, function(key,value) {
    var mockFile = { name: value.name, size: value.size };
    thisDropzone.options.addedfile.call(thisDropzone, mockFile);
    thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name);
  });
});

with this:

$.getJSON('files/list-all', function(data) {
  $.each(data, function(index, val) {
    var mockFile = { name: val.name, size: val.size };
    thisDropzone.options.addedfile.call(thisDropzone, mockFile);
    thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/" + val.name);
  });
});

Credit to this answer: https://mcmap.net/q/149561/-jquery-loop-over-json-result-from-ajax-success

EDIT: In version 4.0 the thumbnails of the existing files will be showed with the cue bar in it. To solve this add:

thisDropzone.emit("complete", mockFile);
Stroganoff answered 3/7, 2014 at 4:51 Comment(8)
I would like to suggest that keeping the uploaded files with their original names on the user's local driver like StarTutorial suggests is a very irresponsible practice. Files would often be overwritten for one.Stroganoff
Do the thumbnails resize properly in your application? I have trouble in mine. :/Low
Yeah, it worked perfectly. What exactly is happening?Stroganoff
imgur.com/zDcYMHb.jpg image to left is the reloaded one, image to right the just uploaded one. Maybe it is a type, will redo the code a couple of times, maybe I'll find the bug. Maybe some different jQuery versions...Low
@Low i am facing same issue of re-sizing thumbnails, any solutions??Swirl
@Swirl Rule of thumb: You need to be specific about browser version and include a link to the webpage. Otherwise, the question is not detailed enough to get useful answers. Like asking about my fruit salad being stale.Stroganoff
@zehelvion , i totally understand, similar problem has already been pointed out by previous comment. So smaller jpeg image thumbnails are shown correctly but images of size 3MB have zoomed in thumbnails. i67.tinypic.com/2lwssyd.jpg . Dropzone version 4.3, browser Chrome version 49.0.2. First image (3MB) is loaded from server side. Second image (38KB) loaded from server side, while third image(3MB) is loaded from client side. First and third image are duplicate.Swirl
@zehelvion the issue is resolved by letting Dropzone download and resize it through function myDropzone.createThumbnailFromUrl(file,imageurl). ThanksSwirl
C
17

For Dropzone 5.x

The solutions given so far did not work with dropzone version 5.x. What worked for me was to modify dropzone's config options as follows:

init: function () {
                var mockFile = {
                    name: 'FileName',
                    size: '1000', 
                    type: 'image/jpeg',
                    accepted: true            // required if using 'MaxFiles' option
                };
                this.files.push(mockFile);    // add to files array
                this.emit("addedfile", mockFile);
                this.emit("thumbnail", mockFile, 'http://url/to/file');
                this.emit("complete", mockFile); 
            }

The concept is, to create a mock file, and call the event handlers addedfile and thumbnail to draw the preview. And then finally call on complete event to ensure that there are no progress bars, etc. being displayed.

Reference

Collusive answered 15/8, 2017 at 20:39 Comment(5)
Thanks - this works for me! Do you know how to use these images when the form is submitted though? When I submit the form only newly added images are sent to the server.Roselinerosella
@Chris. You're welcome. Only the new images will be sent to the server because the file you displayed via init() was a mock file (and it already exists on your server)Collusive
@NiketPathak not sure I'm following how this gets the 3 files that have been previously uploaded to a url folder. I have a folder per property and then have uploaded files placed there. Not sure how this reads the contents of that folder and populates the DZ?Goodard
@Goodard This doesn't read the folder contents. It's you who needs to provide that information. For example, in PHP, you can read the concerned directory, prepare the mockFile object(s) and then echo the same in javascript directly. Thats how DZ becomes aware of already uploaded files.Collusive
This is my solution: github.com/dropzone/dropzone/issues/443#issuecomment-905357585 inspired by this solution.Scoville
M
4

I'm leaving here the solution that worked for me. (Dropzone v5.7.0 and Codeigniter v3.1.11)

  1. Use Dropzone option init
  2. Make AJAX call to back-end script which returns json encoded array of objects containing images' info (PHP way above in the question, Codeigniter way here)
  3. Use jQuery each function to iterate on every object containing image info
  4. Use the snippet here: https://github.com/enyo/dropzone/wiki/FAQ#how-to-show-files-already-stored-on-server to display each image

in my App controller:

public function ilan_fotolari($ilan_id = 0)
{
    $this->load->helper('ilan');
    $dirPath = './assets/uploads/'.ilan_dir($ilan_id);
    $this->load->helper('file');
    $file_names = get_filenames($dirPath);
    $mocks = [];
    foreach ($file_names as $file_name) {
        $mock['name'] = $file_name;
        $dirUrl = base_url('assets/uploads/'.ilan_dir($ilan_id));
        $mock['url'] = $dirUrl.$file_name;
        $mocks[] = $mock;
    }
    $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode($mocks));
}

in my script.js:

Dropzone.options.ilanFotoAlani = {
    paramName: "foto", // The name that will be used to transfer the file
    maxFilesize: 5, // MB
    maxFiles: 9,
    resizeWidth: 1000,
    resizeHeight: 644,
    resizeMimeType: 'image/jpeg',
    addRemoveLinks: true,
    dictDefaultMessage: 'Fotoğraf sürükle veya seç',
    dictFileTooBig: 'Fotoğraf boyutu en fazla 5MB olmalı',
    dictRemoveFile: 'Fotoğrafı sil',
    dictCancelUpload: 'İptal et',
    dictMaxFilesExceeded: 'En fazla 9 fotoğraf yükleyebilirsin',
    init: function () {
        let myDropzone = this;
        $.ajax({
            type: 'get',
            url: '/ilan-fotolari',
            success: function(mocks){
                $.each(mocks, function(key,value) {
                    let mockFile = { name: value.name, size: 1024 };
                    myDropzone.displayExistingFile(mockFile, value.url);
                });
            },
            error: function(xhr, durum, hata) {
                alert("Hata: " + hata);
            }
        });
    }
};

I have mixed up solutions from different solutions into this.

Musa answered 5/11, 2020 at 18:39 Comment(0)
S
4

New updates

This is an old question, but in recent versions of Dropzone, from version 5.7.0 to be more precise, it's possible to display existing files with ease through a dedicated method named displayExistingFile.

Example

let myDropzone = new Dropzone("div#myId", { 
    url: "/file/post"
});

const files = [
    {name: 'square-600', size: 1000, url: 'https://via.placeholder.com/600'},
    {name: 'square-800', size: 1200, url: 'https://via.placeholder.com/800'}
];

files.forEach(function (file) {

    let mockFile = {
        name: file.name,
        size: file.size,
    };

    myDropzone.displayExistingFile(mockFile, file.url);
});

Type definition for displayExistingFile

displayExistingFile(
    mockFile: Dropzone.DropzoneMockFile,
    imageUrl: string,
    callback?: () => void,
    crossOrigin?: 'anonymous' | 'use-credentials',
    resizeThumbnail?: boolean,
): any;
Supernational answered 11/1, 2022 at 10:43 Comment(0)
D
1

This is the way which I implemented it. I have used createThumbnailFromUrl rather using emitting a thumbnail event.

HTML element;

<form id="sample-img" action="/upload" class="dropzone">
    <div class="dz-default dz-message"></div>
</form>

JS code;

previewThumbailFromUrl({
    selector: 'sample-img',
    fileName: 'sampleImg',
    imageURL: '/images/sample.png'
});

function previewThumbailFromUrl(opts) {
    var imgDropzone = Dropzone.forElement("#" + opts.selector);
    var mockFile = {
        name: opts.fileName,
        size: 12345,
        accepted: true,
        kind: 'image'
    };
    imgDropzone.emit("addedfile", mockFile);
    imgDropzone.files.push(mockFile);
    imgDropzone.createThumbnailFromUrl(mockFile, opts.imageURL, function() {
        imgDropzone.emit("complete", mockFile);
    });
}
Drowsy answered 13/5, 2016 at 2:56 Comment(0)
A
1

I am just leaving the solution that worked for me.

This setup counts the already uploaded files to the maxFiles limit and also uses simple convention.

  • Laravel 9.19
  • Dropzone 6.0.0 Beta

Assuming you have stored the files in your storage\app\public folder and have created a symlink using

php artisan storage:link

command, follow the below snippet to setup a GET route to return files from server side

use Illuminate\Support\Facades\File;

$uploaded_path  = 'storage\\uploads\\'.$user['id'].'\\images';
$images_info = []; 

$images = File::allFiles(public_path($uploaded_path));

// Read images
foreach ($images as $image) { 

    $filename = $image->getFilename(); 
    $size = $image->getSize();
            
    $images_info[] = array( 
        "name" => $filename, 
        "size" => $size, 
        "path" => url($uploaded_path.'\\'.$filename) 
    ); 
} 

return response()->json($images_info, 200); 

And then in the frontend, inside the dropzone init() function,

init: function() {
    var thisDropzone = this
    $.get('insert_the_route_to_above_function_on_serverside', function(data) {
        $.each(data, function(key, value){           
            var mockFile = { 
                name: value.name, 
                size: value.size,
                accepted: true
            }
            thisDropzone.files.push(mockFile);
            thisDropzone.displayExistingFile(mockFile, value.path)               
        });
    })
}
Actress answered 6/4, 2023 at 19:33 Comment(0)
P
0

I was having trouble with maxFiles/maxfilesexceeded and take some while looking for a anwser and then I found this links below:

https://www.bountysource.com/issues/1444854-use-files-already-stored-on-server-wiki-example-incomplete?utm_campaign=plugin&utm_content=tracker%2F283989&utm_medium=issues&utm_source=github

$.each(obj, function(i, item) {

  ///faking the BytesSent its not essanail to me.. if you need it just pass the correct one
  var upload = {bytesSent: 12345};

  /// again fake the size..
  var mockFile = {name: item.name, size: 12345, accepted: true};

  mockFile.upload = upload;
  mockFile.kind = "file";
  Dropzone.forElement("#editfileuploader").emit("addedfile", mockFile);

  //push the file to files array because getAcceptedFiles using this array length to get the currct files count..
  Dropzone.forElement("#editfileuploader").files.push(mockFile);

  //this for lettig dropzone to creat the thumbnail(item.ts has the file location)
  Dropzone.forElement("#editfileuploader").emit("thumbnail", mockFile, item.ts);

  //to show the success mark and to return image id response
  Dropzone.forElement("#editfileuploader").emit("success", mockFile, item.id);
}); 
Proselyte answered 10/12, 2014 at 19:30 Comment(1)
I also emit complete after the success: Dropzone.forElement("#editfileuploader").emit("complete", mockFile)Lambaste

© 2022 - 2024 — McMap. All rights reserved.