Laravel 8 Ajax Image Upload with Validation and Preview
This tutorial explains how to upload images in Laravel 8 using Ajax and jQuery. We will create an image upload feature that validates, previews, and stores the image in a database without reloading the page.
Step 1: Install Laravel 8 Application
Run the following command to install Laravel 8:
composer create-project --prefer-dist laravel/laravel uploadImages
Step 2: Configure Database
Open the .env
file and update your database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_images
DB_USERNAME=root
DB_PASSWORD=
Step 3: Create Model & Migration
Generate the model and migration file using:
php artisan make:model Image -m
Now, update the migration file (database/migrations/YYYY_MM_DD_create_images_table.php
):
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateImagesTable extends Migration {
public function up() {
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('path')->nullable();
$table->timestamps();
});
}
public function down() {
Schema::dropIfExists('images');
}
}
Run the migration to create the table:
php artisan migrate
Update Image Model
Modify app/Models/Image.php
to allow mass assignment:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Image extends Model {
use HasFactory;
protected $fillable = ['name', 'path'];
}
Step 4: Define Routes
Add the following routes in routes/web.php
:
use App\Http\Controllers\ImageController;
use Illuminate\Support\Facades\Route;
Route::get('upload-images', [ImageController::class, 'index']);
Route::post('upload-images', [ImageController::class, 'storeImage'])->name('images.store');
Route::get('/', function () {
return view('welcome');
});
Step 5: Create ImageController
Generate a new controller:
php artisan make:controller ImageController
Now, open app/Http/Controllers/ImageController.php
and add the following code:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Image;
class ImageController extends Controller {
public function index() {
return view('images');
}
public function storeImage(Request $request) {
$request->validate([
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($request->file('file')) {
$imagePath = $request->file('file');
$imageName = $imagePath->getClientOriginalName();
$path = $request->file('file')->storeAs('uploads', $imageName, 'public');
}
$image = new Image();
$image->name = $imageName;
$image->path = '/storage/' . $path;
$image->save();
return response()->json('Image uploaded successfully');
}
}
Step 6: Create Blade View
Create resources/views/images.blade.php
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel Ajax Image Upload</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="container mt-4">
<h2>Laravel Image Upload Using Ajax</h2>
<form method="post" id="upload-image-form" enctype="multipart/form-data">
@csrf
<div class="form-group">
<input type="file" name="file" class="form-control" id="image-input">
<span class="text-danger" id="image-input-error"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Upload</button>
</div>
</form>
</div>
<script>
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('#upload-image-form').submit(function(e) {
e.preventDefault();
let formData = new FormData(this);
$('#image-input-error').text('');
$.ajax({
type: 'POST',
url: '{{ route("images.store") }}',
data: formData,
contentType: false,
processData: false,
success: (response) => {
alert('Image uploaded successfully');
this.reset();
},
error: function(response) {
$('#image-input-error').text(response.responseJSON.errors.file);
}
});
});
</script>
</body>
</html>
Step 7: Create Storage Link
Run the following command to link storage to public:
php artisan storage:link
Step 8: Create Uploads Directory
Manually create an uploads
folder inside the public
directory.
Grant permissions if needed:
sudo chmod -R 777 public/uploads
sudo chmod -R 777 storage
Conclusion
This tutorial covered how to upload images using Ajax in Laravel 8 with validation, preview, and error handling. If you have any questions, feel free to comment below!