Laravel Livewire Multiple Files Upload API with Loading and Preview Image
Simple File Upload Component and View
Now the basic setup is done the next thing is to create a simple file upload component and view for this run below command.
php artisan make:livewire file-upload
You’ll see a new file at app/Http/Livewire/FileUpload.php and view at resources/views/livewire/file-upload.blade.php.
After component and view get create you must include them inside base.blade.php.
@livewireStyles </head> <body> @livewire('file-upload') @livewireScripts </body>
Simple File Upload Snippet
resources/views/livewire/file-upload.blade.php
<div> <h2>File Upload Form</h2> <!-- Create File Upload Form --> <form wire:submit.prevent="uploadSelectedFile" > <div class="row"> <div class="col-md-3"> <label for="">Choose File</label> <input type="file" wire:model="profile_image" > <!-- Did a mistake here --> @error('profile_image') <span style="color:red;">{{ $message }}</span> @enderror </div> <div class="col-md-12"> <input type="submit" name="submit" value="Upload Image"> </div> </div> </form> </div>
app/Http/Livewire/FileUpload.php
<?php namespace App\Http\Livewire; use Livewire\Component; use Livewire\WithFileUploads; class FileUpload extends Component { use WithFileUploads; public $profile_image; public function uploadSelectedFile(){ $this->validate([ 'profile_image' => 'required|image', ]); $ext = $this->profile_image->getClientOriginalExtension(); dd($this->profile_image->storeAs('public/uploads', 'my-profile-pic2.'.$ext)); } public function render() { return view('livewire.file-upload'); } }
After this step is done goto URL http://localhost/my_new_laravel/public/ and there you’ll see a file upload form.
The uploaded files will be saved inside storage/app/public directory by folder name uploads.
Laravel will implicitly create the folder if does not exists.
Multiple Files Upload Component, View and with Image Preview
For uploading, multiple files use attribute multiple on the HTML file field.
Create a fresh Multiple File Upload Component with view
php artisan make:livewire multile-files-upload
Change the calling of component file-upload with below component in base.blade.php
<!-- Change from this --> @livewire('file-upload') <!-- TO this --> @livewire('multiple-files-upload')
Multiple Files Upload Snippet
resources\views\livewire\multiple-files-upload.blade.php
<div> <h2>Multiple Files Uploads</h2> <form wire:submit.prevent="uploadMultipleFiles" > <div class="row"> <div class="col-md-3"> <label for="">Slides</label> <input type="file" class="form-control" wire:model="slides" multiple > @error('slides.*') <span style="color: red;" >{{ $message }}</span> @enderror <h2>Preview Images</h2> <!-- Loading Message for Images --> <div wire:loading wire:target="slides">Uploading Slide Images...</div> @if( !empty( $slides ) ) <div> @foreach ( $slides as $slide ) <img src="{{ $slide->temporaryUrl() }}" alt="" style="width: 100px;" > @endforeach </div> @endif </div> <div class="col-md-12"> <button type="submit" class="btn btn-primary" >Upload Slides</button> </div> </div> </form> </div>
app\Http\Livewire\MultipleFilesUpload.php
<?php namespace App\Http\Livewire; use Livewire\Component; use Livewire\WithFileUploads; class MultipleFilesUpload extends Component { use WithFileUploads; public $slides=[]; public function uploadMultipleFiles(){ $this->validate([ 'slides.*' => 'image' ]); if( !empty( $this->slides ) ){ foreach( $this->slides as $slide ){ $slide->store('public/slides-images'); } } } public function render() { return view('livewire.multiple-files-upload'); } }
Initialize the public $slides=[]; as an array and after submitting validate each of the files using slides.*. Here the asterisk * means multiple items.
After successful validation loop over $slides and call store() methond on each $slide.
You’ll see that a new folder named slides-images will be created inside storage\app\public and this folder contains all the files you have uploaded.
Previewing Multiple Files before Upload
In template resources\views\livewire\multiple-files-upload.blade.php. The file field is mapped to wire:model=”slides” and onchange the livewire detects the files and displays them when we loop over each of them before the file is just ready to upload.
@if( !empty( $slides ) ) <div> @foreach ( $slides as $slide ) <img src="{{ $slide->temporaryUrl() }}" alt="" style="width: 100px;" > @endforeach </div> @endif
The path through which images are displayed are stored in $slide->temporaryUrl().
Show loading message before previewing the image
The simplest solution provided by livewire is to use wire:loading directive which has slides as a target.
<div wire:loading wire:target="slides">Uploading Slide Images...</div>
No comments