File uploading is a vital function in web development that allows users to share and store files on a server. CodeIgniter 4, a powerful PHP framework, offers developers a robust environment for creating web applications.
By leveraging the simplicity of jQuery AJAX and the capabilities of CodeIgniter 4, you can easily build an efficient file upload system without any complications.
In this tutorial, we will explore how to upload files using jQuery AJAX in CodeIgniter 4 and display a preview of the uploaded file. We will guide you through the process of setting up a CodeIgniter 4 project, creating a controller to handle file uploads, and implementing an upload form view.
Through this tutorial, you will learn how to leverage the capabilities of CodeIgniter 4 and jQuery AJAX to create a smooth and interactive file upload functionality.
Table of Content
- Enable CSRF
- Configure Routes
- Create a Controller – Handle file upload request
- View – Create HTML form & Write AJAX code for file upload
- Output
- Conclusion
1. Enable CSRF
- Open
.env
file. - Remove # from the start of the
security.tokenName
,security.headerName
,security.cookieName
,security.expires
,andsecurity.regenerate
. - I update the
security.tokenName
value with'csrf_hash_name'
. With this name read CSRF hash. You can update it with any other value. - If you don’t want to regenerate CSRF hash after each AJAX request then set
security.regenerate = false
.
security.tokenName = 'csrf_hash_name' security.headerName = 'X-CSRF-TOKEN' security.cookieName = 'csrf_cookie_name' security.expires = 7200 security.regenerate = true
- Open
app/Config/Filters.php
file and uncomment'csrf'
in'before'
if commented.
// Always applied before every request public $globals = [ 'before' => [ // 'honeypot', 'csrf', // 'invalidchars', ], 'after' => [ 'toolbar', // 'honeypot', // 'secureheaders', ], ];
2. Configure Routes
- Open
app/Config/Routes.php
file. - Define 2 routes –
- / – Display file upload view.
- users/fileUpload – It is used to upload a file.
$routes->get('/', 'UsersController::index'); $routes->post('users/fileUpload', 'UsersController::fileUpload');
3. Create a Controller – Handle file upload request
- Create
UsersController
controller using the following command:
php spark make:controller UsersController
- Open the file and define two methods:
- index() – Load
index
view. - fileUpload() – Handles the AJAX request.
- index() – Load
Generate a new CSRF token and assign it to $data['token']
.
Implement file validation using the following rules:
'file' => 'uploaded[file]|max_size[file,1024]|ext_in[file,jpeg,jpg,docx,pdf],'
If the file fails validation, assign 0 to $data['success']
and the validation response to $data['error']
.
If the file is validated then read the file name and extension and upload the file to the "public/uploads"
location. Assign 1 to $data['success']
, 'Uploaded Successfully!'
to $data['message']
, file path to $data['filepath']
, and file extension to $data['extension']
.
If the file fails to upload, assign 2 to $data['success']
and 'File not uploaded.'
to $data['message']
.
Return the $data
array in JSON format.
<?php namespace App\Controllers; use App\Models\Users; class UsersController extends BaseController{ public function index(){ return view('index'); } 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,1024]|ext_in[file,jpeg,jpg,docx,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); // File path to display preview $filepath = base_url()."/uploads/".$newName; // Response $data['success'] = 1; $data['message'] = 'Uploaded Successfully!'; $data['filepath'] = $filepath; $data['extension'] = $ext; }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 HTML form & Write AJAX code for file upload
- Create a file
index.php
in theapp/Views/
folder. - Include a hidden element in the HTML file to store the CSRF token name obtained from the
.env
file. Assign the CSRF hash value to thevalue
attribute.
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
- Utilize jQuery to display the AJAX response message within the
<div id="responseMsg">
element. - Using jQuery, create an
<img>
and<a>
element within the<div id="filepreview">
to display a file preview based on the file extension. - Build a form with the method set to
post
and the action attribute set to"<?=site_url('users/fileUpload')?>"
. Include an input element of type"file"
and a button in the form. - Apply jQuery to display any validation errors in the
<div id="err_file">
element if the file fails to pass validation.
jQuery Script –
- When the button is clicked, retrieve the CSRF Token name and hash from the hidden field and assign them to the variables
csrfName
andcsrfHash
. - Check if a file has been selected. If not, display an alert message saying
"Please select a file."
- If a file is selected, use the
FormData
object to pass the selected file. Include the CSRF Token with theFormData
. - Send an AJAX POST request to
"<?=site_url('users/fileUpload')?>"
, passing theFormData
object as the data. - In the successful callback, update the CSRF Token by assigning
response.token
to.txt_csrfname
. - If
response.success
equals 1, it means the file was successfully uploaded. Display the response message and preview the file based on its extension. - If
response.success
equals 2, it means the file was not uploaded. Display the response message. - If
response.success
is neither 1 nor 2, it means the file did not pass validation. Display the error message.
<!DOCTYPE html> <html> <head> <title>How to upload a file using jQuery AJAX in CodeIgniter 4</title> <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <style type="text/css"> .displaynone{ display: none; } </style> </head> <body> <div class="container"> <!-- CSRF token --> <input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" /> <div class="row"> <div class="col-md-12"> <!-- Response message --> <div class="alert displaynone" id="responseMsg"></div> <!-- File preview --> <div id="filepreview" class="displaynone" > <img src="" class="displaynone" with="200px" height="200px"><br> <a href="#" class="displaynone" >Click Here..</a> </div> <!-- File upload form --> <form method="post" action="<?=site_url('users/fileUpload')?>" enctype="multipart/form-data"> <div class="form-group"> <label for="file">File:</label> <input type="file" class="form-control" id="file" name="file" /> <!-- Error --> <div class='alert alert-danger mt-2 d-none' id="err_file"></div> </div> <input type="button" class="btn btn-success" id="submit" value="Upload"> </form> </div> </div> </div> <!-- Script --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('#submit').click(function(){ // CSRF Hash var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name var csrfHash = $('.txt_csrfname').val(); // CSRF hash // Get the selected file var files = $('#file')[0].files; if(files.length > 0){ var fd = new FormData(); // Append data fd.append('file',files[0]); fd.append([csrfName],csrfHash); // Hide alert $('#responseMsg').hide(); // AJAX request $.ajax({ url: "<?=site_url('users/fileUpload')?>", method: 'post', data: fd, contentType: false, processData: false, dataType: 'json', success: function(response){ // Update CSRF hash $('.txt_csrfname').val(response.token); // Hide error container $('#err_file').removeClass('d-block'); $('#err_file').addClass('d-none'); if(response.success == 1){ // Uploaded successfully // Response message $('#responseMsg').removeClass("alert-danger"); $('#responseMsg').addClass("alert-success"); $('#responseMsg').html(response.message); $('#responseMsg').show(); // File preview $('#filepreview').show(); $('#filepreview img,#filepreview a').hide(); if(response.extension == 'jpg' || response.extension == 'jpeg'){ $('#filepreview img').attr('src',response.filepath); $('#filepreview img').show(); }else{ $('#filepreview a').attr('href',response.filepath).show(); $('#filepreview a').show(); } }else if(response.success == 2){ // File not uploaded // Response message $('#responseMsg').removeClass("alert-success"); $('#responseMsg').addClass("alert-danger"); $('#responseMsg').html(response.message); $('#responseMsg').show(); }else{ // Display Error $('#err_file').text(response.error); $('#err_file').removeClass('d-none'); $('#err_file').addClass('d-block'); } }, error: function(response){ console.log("error : " + JSON.stringify(response) ); } }); }else{ alert("Please select a file."); } }); }); </script> </body> </html>
5. Output
6. Conclusion
This article explains how to use jQuery AJAX and CodeIgniter 4 to upload files and display preview in web applications. With the combination of jQuery’s simplicity and CodeIgniter 4’s powerful features, you can create an efficient yet user-friendly file upload functionality according to your project needs.
Don’t hesitate to explore and enhance this process further.
If you found this tutorial helpful then don't forget to share.