How to Display existing file in Dropzone – CodeIgniter 4

Dropzone display preview after file upload but thumbnail gets removed after page reload.

To recreate thumbnails require to send AJAX request while Dropzone initialization.

In this tutorial, I show how you can display existing files in the Dropzone container in CodeIgniter 4.

How to Display existing files in Dropzone - CodeIgniter 4


Contents

  1. Enable CSRF
  2. Route
  3. Controller
  4. View
  5. Run
  6. Demo
  7. Conclusion

1. Enable CSRF

  • Open .env file.
  • Remove # from the start of the security.tokenName, security.headerName, security.cookieName, security.expires, and security.regenerate.
  • Using security.tokenName read CSRF hash. You can update it with any other value.
# security.csrfProtection = 'cookie'
# security.tokenRandomize = false
security.tokenName = 'csrf_token_name'
security.headerName = 'X-CSRF-TOKEN'
security.cookieName = 'csrf_cookie_name'
security.expires = 7200
security.regenerate = true
# security.redirect = true
# security.samesite = 'Lax'
  • Open app/Config/Filters.php file.
  • Uncomment in 'csrf' in 'before' if commented.
public $globals = [
    'before' => [
        // 'honeypot',
        'csrf',
        // 'invalidchars',
     ],
     'after' => [
        'toolbar',
        // 'honeypot',
        // 'secureheaders',
     ],
];

2. Route

  • Open app/Config/Routes.php file.
  • Define 2 routes –
    • / – Display file upload view.
    • page/readFiles – Read existing files.
    • page/fileUpload – It is used to upload a file.

Completed Code

$routes->get('/', 'PageController::index');
$routes->get('page/readFiles', 'PageController::readFiles');
$routes->post('page/fileUpload', 'PageController::fileUpload');

3. Controller

  • Create PageController Controller –
php spark make:controller PageController
  • Open app/Controllers/PageController.php file.
  • Create 2 methods –
    • index() – Load index view.
    • readFiles() – This method is used to read existing files to display in Dropzone.

Assign valid file extensions in $validextension_arr Array. Read files from uploads folder and check file extension exists in $validextension_arr Array. If it exists then initialize $file_list Array with name, file size, and path.

Return $file_list Array in JSON format.

    • fileUpload() – This method is used to upload the selected file of Dropzone.

Define file validation. I set the max file size to 2 MB (2048 Kb).

If the file is not validated then assign 0 to $data['success'] and validation response to $data['error'].

If file is validated successfully then upload the file to "uploads" location. Assign 1 to $data['success'] and assign Uploaded Successfully! to $data['message'].

Return $data Array in JSON format.

Completed Code

<?php 
namespace App\Controllers;

class PageController extends BaseController{

   public function index(){
      return view('index');
   }

   // Read files
   public function readFiles(){
      $file_list = array();

      $validextension_arr = array('jpeg','jpg','png','pdf');

      // Target location
      $target_dir = "uploads/";
      $dir = $target_dir;

      if (is_dir($dir)){

         if ($dh = opendir($dir)){

            // Read files
            while (($file = readdir($dh)) !== false){

               if($file != '' && $file != '.' && $file != '..'){

                  // File path
                  $file_path = $target_dir.$file;

                  // Check if it is folder or not
                  if(!is_dir($file_path)){

                     $size = filesize($file_path);
                     $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));

                     if (in_array($extension,$validextension_arr)) {
                        $file_list[] = array('name'=>$file,'size'=>$size,'path'=>$file_path);
                     }
                  }
               }

            }
            closedir($dh);
         }
      }

      return $this->response->setJSON($file_list);
   }

   // Upload file
   public function fileUpload(){

      $data = array();

      // Read new token and assign to $data['token']
      $data['token'] = csrf_hash();

      ## Validation
      $validation = \Config\Services::validation();

      $input = $validation->setRules([
         'file' => 'uploaded[file]|max_size[file,2048]|ext_in[file,jpeg,jpg,png,pdf],'
      ]);

      if ($validation->withRequest($this->request)->run() == FALSE){

         $data['success'] = 0;
         $data['error'] = $validation->getError('file');// Error response

      }else{

         if($file = $this->request->getFile('file')) {
            if ($file->isValid() && ! $file->hasMoved()) {
               // Get file name and extension
               $name = $file->getName();
               $ext = $file->getClientExtension();

               // Get random file name
               $newName = $file->getRandomName();

               // Store file in public/uploads/ folder
               $file->move('../public/uploads', $newName);

               // Response
               $data['success'] = 1;
               $data['message'] = 'Uploaded Successfully!';

            }else{
               // Response
               $data['success'] = 2;
               $data['message'] = 'File not uploaded.'; 
            }
         }else{
            // Response
            $data['success'] = 2;
            $data['message'] = 'File not uploaded.';
         }
      }
      return $this->response->setJSON($data);

   }

}

4. View

Create index.php file in app/Views/.

Include Dropzone and jQuery library.

You can download Dropzone from here or you can use CDN –

<link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" type="text/css" />
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>

Create a hidden element to store CSRF token name specified in .env file in the name attribute and store CSRF hash in the value attribute.

<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />

Create <form action="<?=site_url('page/fileUpload')?>", class='dropzone' ></form> to initialize Dropzone.

Script

  • Disable dropzone autoDiscover – Dropzone.autoDiscover = false and initialize Dropzone on class="dropzone".
  • Set max upload filesize to 2 MB and valid file extensions – “.jpeg,.jpg,.png,.pdf”.
  • Use init to load existing files using jQuery AJAX. On successfully callback loop on the response and assign { name: value.name, size: value.size } in mockFile.
  • Using emit() method add thumbnail.
  • With Dropzone sending event send CSRF token – formData.append(csrfName, csrfHash);.
  • Using success event update token hash and check return response.
  • If response.status == 0 means there is an error and if response.status == 2 means file is not uploaded. Display error message using alert().

Completed Code

<!doctype html>
<html>
<head>
   <title>How to Display existing file in Dropzone - CodeIgniter 4</title>

   <!-- CSS -->
   <link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" type="text/css" />

   <!-- Script -->
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
   <script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>

   <style type="text/css">
   .dz-preview .dz-image img{
      width: 100% !important;
      height: 100% !important;
      object-fit: cover;
   }
   </style>
</head>
<body>

   <!-- CSRF token --> 
   <input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />

   <div class='content'>
      <!-- Dropzone -->
      <form action="<?=site_url('page/fileUpload')?>", class='dropzone' ></form> 
   </div>

   <!-- Script -->
   <script>

   Dropzone.autoDiscover = false;
   var myDropzone = new Dropzone(".dropzone",{ 
      maxFilesize: 2, // 2 mb
      acceptedFiles: ".jpeg,.jpg,.png,.pdf",
      init: function() { 
         myDropzone = this;
         $.ajax({
            url: '<?=site_url('page/readFiles')?>',
            type: 'get',
            dataType: 'json',
            success: function(response){

               $.each(response, function(key,value) {
                  var mockFile = { name: value.name, size: value.size };

                  myDropzone.emit("addedfile", mockFile);
                  myDropzone.emit("thumbnail", mockFile, value.path);
                  myDropzone.emit("complete", mockFile);

               });

            }
         });
      }
   });

   myDropzone.on("sending", function(file, xhr, formData) {
      // CSRF Hash
      var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
      var csrfHash = $('.txt_csrfname').val(); // CSRF hash

      formData.append(csrfName, csrfHash);
   }); 

   myDropzone.on("success", function(file, response) {
      $('.txt_csrfname').val(response.token);
      if(response.success == 0){ // Error
         alert(response.error);
      }
      if(response.success == 2){
         alert(response.message);
      }

   });
   </script>

</body>
</html>

5. Run

  • Navigate to the project using Command Prompt if you are on Windows or terminal if you are on Mac or Linux, and
  • Execute “php spark serve” command.
php spark serve
  • Run http://localhost:8080 in the web browser.

6. Demo

View Demo


7. Conclusion

With the use of init option while Dropzone initialization you can load existing files using jQuery AJAX in the Dropzone container.

If you found this tutorial helpful then don't forget to share.

Leave a Comment