11

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

user3702005
  • 113
  • 1
  • 1
  • 6
  • 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? – AturSams Jul 03 '14 at 04:13
  • https://github.com/enyo/dropzone/wiki/FAQ#how-to-show-files-already-stored-on-server – Disapamok Dec 20 '19 at 05:32

7 Answers7

17

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://stackoverflow.com/a/5531883/984975

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);
Community
  • 1
  • 1
AturSams
  • 7,568
  • 18
  • 64
  • 98
  • 1
    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. – AturSams Jul 03 '14 at 04:52
  • Do the thumbnails resize properly in your application? I have trouble in mine. :/ – LoveAndHappiness Apr 07 '15 at 16:34
  • Yeah, it worked perfectly. What exactly is happening? – AturSams Apr 07 '15 at 20:39
  • http://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... – LoveAndHappiness Apr 08 '15 at 10:49
  • @LoveAndHappiness i am facing same issue of re-sizing thumbnails, any solutions?? – waheebyaqub Apr 14 '16 at 10:34
  • @waheebyaqub 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. – AturSams Apr 14 '16 at 11:36
  • @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. http://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. – waheebyaqub Apr 14 '16 at 12:05
  • 1
    @zehelvion the issue is resolved by letting Dropzone download and resize it through function myDropzone.createThumbnailFromUrl(file,imageurl). Thanks – waheebyaqub Apr 14 '16 at 12:17
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

Community
  • 1
  • 1
Niket Pathak
  • 6,323
  • 1
  • 39
  • 51
  • 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. – Chris Aug 17 '17 at 07:09
  • @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) – Niket Pathak Aug 17 '17 at 10:05
  • @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? – justdan0227 Oct 03 '17 at 15:05
  • @justdan0227 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. – Niket Pathak Oct 03 '17 at 16:32
  • 1
    This is my solution: https://github.com/dropzone/dropzone/issues/443#issuecomment-905357585 inspired by this solution. – xhafan Aug 25 '21 at 11:12
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.

Adem Tepe
  • 564
  • 5
  • 10
2

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;
chebaby
  • 7,362
  • 50
  • 46
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);
    });
}
gihanchanuka
  • 4,783
  • 2
  • 32
  • 32
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);
}); 
Ricardo França
  • 2,923
  • 2
  • 18
  • 18
0

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)               
        });
    })
}
pravnkay
  • 54
  • 4