How to Create upload a file using jQuery AJAX in Laravel 8

How to upload a file using jQuery AJAX in Laravel 8

 

Using AJAX you can upload a file to the server without reloading the page.

Require to send CSRF token with AJAX request to upload the file.

In this tutorial, I show how you can upload a file using jQuery AJAX and display preview in Laravel 8. 

1. Controller

Create a PageController controller.

php artisan make:controller PageController

Create 2 methods –

  • index() – Load index view.
  • uploadFile() – This method is used to upload the file.

Create $data Array to store return response.

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 the file is validated then assign file name to $filename and file extension to $extension variable. Assign upload location "files" to $location variable.

Execute $file->move($location,$filename); to store the file.

Assign 1 to $data['success']'Uploaded Successfully!' to $data['message'], file path to $data['filepath'], and file extension to $data['extension'].

If the file is not uploaded then assign 2 to $data['success'] and 'File not uploaded.' message to $data['message'].

Return $data Array in JSON format.

Completed Code

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class PageController extends Controller {

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

   public function uploadFile(Request $request){

      $data = array();

      $validator = Validator::make($request->all(), [
         'file' => 'required|mimes:png,jpg,jpeg,csv,txt,pdf|max:2048'
      ]);

      if ($validator->fails()) {

         $data['success'] = 0;
         $data['error'] = $validator->errors()->first('file');// Error response

      }else{
         if($request->file('file')) {

             $file = $request->file('file');
             $filename = time().'_'.$file->getClientOriginalName();

             // File extension
             $extension = $file->getClientOriginalExtension();

             // File upload location
             $location = 'files';

             // Upload file
             $file->move($location,$filename);
             
             // File path
             $filepath = url('files/'.$filename);

             // Response
             $data['success'] = 1;
             $data['message'] = 'Uploaded Successfully!';
             $data['filepath'] = $filepath;
             $data['extension'] = $extension;
         }else{
             // Response
             $data['success'] = 2;
             $data['message'] = 'File not uploaded.'; 
         }
      }

      return response()->json($data);
   }

}

2. Route

  • Open routes/web.php file.
  • Define 2 routes –
    • / – Load index view.
    • /uploadFile – This use to upload a file using AJAX.

Completed Code

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PageController;

Route::get('/', [PageController::class, 'index']);
Route::post('/uploadFile', [PageController::class, 'uploadFile'])->name('uploadFile');

3. View

Create index.blade.php file in resources/views/.

Stored CSRF token in the <meta > tag.

Display file upload response message in <div id="responseMsg"> using jQuery.

Created <img > and <a > element in <div id="filepreview"> to display a file preview according to the file extension using jQuery.

Create a file element and a button. Display error in <div id="err_file"> if file not validated using jQuery.

Script

Read CSRF token from <meta > tag and assign to CSRF_TOKEN variable.

On the button click read the selected file and assign to files variable.

If file not selected then alert("Please select a file."); otherwise, pass the selected file using FormData object. Also, pass CSRF_TOKEN with FormData.

Send AJAX POST request to "{{route('uploadFile')}} where pass FormData Object as data.

On successful callback check upload status.

If response.success == 1 means file successfully uploaded. Display the response message and preview the file according to the file extension.

If response.success == 2 means file is not uploaded. Display the response message.

If response.success does not equal 1 or 2 means the file is not validated. Display the error message.

Completed Code

<!DOCTYPE html>
<html>
<head>
<title>How to upload a file using jQuery AJAX in Laravel 8</title>

<!-- Meta -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="csrf-token" content="{{ csrf_token() }}">

<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">

    <div class="row">

      <div class="col-md-12 col-sm-12 col-xs-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>

        <!-- Form -->
        <div class="form-group">
           <label class="control-label col-md-3 col-sm-3 col-xs-12" for="name">File    <span class="required">*</span></label>
           <div class="col-md-6 col-sm-6 col-xs-12">

              <input type='file' id="file" name='file' class="form-control">

              <!-- Error -->
              <div class='alert alert-danger mt-2 d-none text-danger' id="err_file"></div>

           </div>
        </div>

        <div class="form-group">
           <div class="col-md-6">
              <input type="button" id="submit" value='Submit' class='btn btn-success'>
           </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Script -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script type="text/javascript">
  var CSRF_TOKEN = document.querySelector('meta[name="csrf-token"]').getAttribute("content");

  $(document).ready(function(){

    $('#submit').click(function(){
   
      // 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('_token',CSRF_TOKEN);

         // Hide alert 
         $('#responseMsg').hide();

         // AJAX request 
         $.ajax({
           url: "{{route('uploadFile')}}",
           method: 'post',
           data: fd,
           contentType: false,
           processData: false,
           dataType: 'json',
           success: function(response){

             // 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' || response.extension == 'png'){

                  $('#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>

4. Output

View Output


5. Conclusion

Use the FormData object if you want to pass extra data while sending AJAX request e.g. – fd.append('filename',"file 1");. Here, fd is FormData object.

Make sure to check upload_max_filesize and post_max_size values in the php.ini file if you are allowing large files to upload.

You can view this tutorial to know file upload without jQuery AJAX.



Comments