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.
Contents
1. Enable CSRF
- Open
.env
file. - Remove # from the start of the
security.tokenName
,security.headerName
,security.cookieName
,security.expires
, andsecurity.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 onclass="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 }
inmockFile
. - 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 ifresponse.status == 2
means file is not uploaded. Display error message usingalert()
.
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
7. Conclusion
With the use of init
option while Dropzone initialization you can load existing files using jQuery AJAX in the Dropzone container.