Multiple image upload is a common requirement for many web applications. Mostly, if you are working on any portal or kind of management system application. Similar to single image upload, you can upload multiple images in Laravel 10 using Ajax. Ajax can provide a smoother and more seamless user experience for multiple image uploads. In this post, we will be implementing Ajax images upload in Laravel 10. You can validate images on the client side and server side as well.
We are going to achieve the multiple images upload using Ajax. Take a look at the result before proceeding to this post.
After uploading the selected images, you will get the success response in the AJAX call.
In case, if you get any validation error then it will be returned in the same ajax response and will be populated the same as success.
Now, let’s start the example in this post.
Prerequisites
Directly, we will be jumping on Ajax image upload in Laravel 10. So, I am assuming, you are ready and familiar with the basic setup of the Laravel 10 application.
If you don’t have a Laravel 10 application, then you may create a new one. However, in order to create a Laravel 10 project, you will be needing the below tools and configurations.
- PHP >=8.1
- Composer
- Apache/Nginx Server
- VS Code Editor (Optional)
- MySQL (version > 5)
Configure Database For Ajax Images Upload in Laravel 10
Firstly, you need to create a database in MySQL. Secondly, navigate to the project folder. Then look at .env file and add the DB configuration as shown below.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE={{ DB_NAME }}
DB_USERNAME={{ DB_USER_NAME }}
DB_PASSWORD={{ DB_PASSWORD }}
Once you added the DB configuration then next you will need to create a model and migration file.
Create a Model, Migration, and Controller
For creating a model, migration, and controller, you can hit the below command.
php artisan make:model Image -mc
After adding the migration, let’s add a schema in the created migration file. Hence, let’s add the below schema.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('image_name')->nullable();
$table->string('image_original_name')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('images');
}
};
Next, after adding the schema, you need to run the migrate command.
php artisan migrate
After migrating the schema, you need to add the mass assignment in the model.
Add Mass Assignment in Model For Ajax Images Upload in Laravel
We will be uploading multiple images in Laravel using Ajax. However, you need to add a fillable property in the Image model as shown below.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
use HasFactory;
protected $fillable = [
'image_name',
'image_original_name',
];
}
After that, we will be adding the functionality for multiple ajax image upload in Laravel.
Add Functionality For Ajax Images Upload in Laravel 10
We already created the controller, hence, we can put the functionality over there. So, you need to add the below snippets.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Image;
class ImageController extends Controller
{
/**
* Display a listing of the resource.
*/
public function create()
{
return view('image-upload');
}
/**
* Upload image and save image name.
*/
public function upload(Request $request) {
$validatedData = $request->validate([
'images' => 'required',
'images.*' => 'required|image|mimes:jpeg,png,jpg,svg|max:2048'
]);
$images = array();
if ($request->hasfile('images')) {
foreach($request->file('images') as $image) {
$imageName = time().rand(1,100).'.'.$image->extension();
$imageOriginalName = $image->getClientOriginalName();
if($image->move(public_path('uploads'), $imageName)) {
$images[] = $imageName;
$image = Image::create([
"image_name" => $image,
'image_original_name' => $imageOriginalName,
]);
}
}
}
if (count($images) > 0) {
return back()->with('success', 'Success! Images have been uploaded');
}
else {
return back()->with("failed", "Alert! Unable to upload image");
}
}
}
After adding the above functions for image upload, you need to add routes as shown below.
Add Routes in Laravel 10
For adding the web routes, you need to navigate to the web.php file
<?php
use App\Http\Controllers\ImageController;
use Illuminate\Support\Facades\Route;
Route::get('images', [ImageController::class, 'create'])->name('images');
Route::post('images', [ImageController::class, 'upload'])->name('images.store');
After adding the routes, you need to create a view from there you will be able to upload multiple images.
Create a View to Upload Multiple Images in Laravel 10
For creating the view, simply navigate to the views folder and create a new file by giving the name image-upload.blade.php
.
After creating the view, just add the below snippet.
<!doctype html>
<html lang="en">
<head>
<title> Laravel 10 AJAX Multiple Image Upload with Validation - Programming Fields</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<style>
.error {
color: #ff0000;
}
</style>
</head>
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-xl-8 col-md-8 col-sm-12 m-auto">
<form method="POST" id="upload-form" enctype="multipart/form-data">
@csrf
<div class="card shadow">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" />
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path
d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" />
</symbol>
</svg>
{{-- Display alert message --}}
<div id="response-container"></div>
<div class="card-header">
<h4 class="card-title fw-bold"> Laravel 10 Ajax Multiple Image Upload</h4>
</div>
<div class="card-body">
<div class="form-group">
<label> Image(s) <span class="text-danger">*</span> </label>
<input type="file" name="images[]" id="images" class="form-control @error('images') is-invalid @enderror" multiple>
@error('images')
<div class="invalid-feedback">{{$message}}</div>
@enderror
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary"> Upload </button>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.min.js" integrity="sha512-37T7leoNS06R80c8Ulq7cdCDU5MNQBwlYoy1TX/WUsLFC2eYNqtKlV0QjH7r8JpG/S0GUMZwebnVFLPd6SU5yg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
</html>
For handling the AJAX request, you will require to have the below script as well. Either you can add it in the same blade or you can create a separate script file for this.
<script>
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$("#upload-form").validate({
rules: {
images: {
required: true,
}
},
messages: {
images: {
required: "Please upload the image",
}
},
submitHandler: function(form, event) {
event.preventDefault();
const formData = new FormData(form);
$.ajax({
url: "{{ route('images') }}",
type: 'POST',
data: formData,
processData: false,
cache: false,
contentType: false,
success: function(response) {
form.reset();
if (response && response.status === 'success') {
$("#response-container").append(`<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"> <use xlink:href="#check-circle-fill" /> </svg>
${response.message}<div><button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div></div>`);
setTimeout(() => {
$(".alert").remove();
}, 5000);
}
else if(response.status === 'failed') {
$("#response-container").append(`<div class="alert alert-danger d-flex alert-dismissible align-items-center" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"><use xlink:href="#exclamation-triangle-fill" /></svg>
<div> ${response.message} <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div></div>`);
setTimeout(() => {
$(".alert").remove();
}, 5000);
}
else if(response.status === 'error') {
$("#response-container").append(`<div class="alert alert-danger d-flex alert-dismissible align-items-center" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"><use xlink:href="#exclamation-triangle-fill" /></svg>
<div> ${response.message.image} <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div></div>`);
setTimeout(() => {
$(".alert").remove();
}, 5000);
}
}
});
}
});
});
</script>
Once you are done with the above script, you will be able to run the application to check the results.
php artisan serve
Run the application using the serve command and checkout the result.
I hope this post will make sense for you for uploading multiple images in Laravel 10 using AJAX.
Leave a Reply