Laravel Livewire & Multiple Image Select

Laravel Livewire & Multiple Image Select

In this article, I am going to show you a simple idea to fix the loss of previously selected image/images whenever you want to select more images using livewire with laravel.

I know there are several ways to achieve this but I find this method very easy with the help of some livewire lifecycle hooks which are the

updating and the updated hooks.

This screenshot shows the full code needed by your livewire component class

carbon (1).png

Let's start by looking at what Updating and Updated hooks does then I will explain the codes in the above screenshot step by step.

Updating:

This runs before any update to the Livewire component's data is completed.

Updated:

This runs after any update to the Livewire component's data is completed.

The code explanation goes thus:

First, add the WithFileUploads trait to your component. Then declare the following properties

<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithFileUploads;

class Create extends Component {
use WithFileUploads;
public $images = [], $prevImages;
}

In your blade template, add an input tag with a type of file and set the model name as images like this:

<input type="file" wire:model="images" multiple accept="image/jpg,image/jpeg,image/png" />

So if you attempt to select multiple images, Livewire will handle it and render the image for you and you can add a preview by using the code below:

<div class="w-full">
         @if (!empty($images))
                 @foreach ($images as $key => $image)
                      <div class="relative float-left pt-[10px] pl-[15px] pr-[10px] pb-[0px] h-[150px] mb-8">
                          <a class="absolute bg-[#ddd] p-[8px] right-[25px] top-[20%] rounded-[50%]" wire:click.prevent='removeItem({{ json_encode($key) }})'>
                                 <i class="fa fa-trash text-red-600"></i>
                          </a>
                         <img src="{{ $image->temporaryUrl() }}" alt="" class="w-[150px] h-[150px] rounded-[15px]" />
                      </div>
                  @endforeach
         @endif
</div>

The problem with the above code is that anytime you click on the input tag to select a new set of files, the previously selected one(s) is lost during the process. Here is the quick fix I provided using two of the lifecycle hooks in Livewire.

The first one is the updatingImages method. See the code sample below:

public function updatingImages($value) {
    $this->prevImages = $this->images;
}

The above code is simply storing the content of the images property in $prevImages property while the $images property is about to start updating so as to prevent loss of content.

The second one is the updatedImages method. See the code sample below:

public function updatedImages($value) {
    $this->images = array_merge($this->prevImages, $value);
}

The above code merges the data of the $prevImages property with the data of the newly selected image/images then store it back into the $images property after the update is complete.

This is one of the simplest ways of solving the issue stated at the beginning of this article. I hope you find it helpful.

Thank you for reading!!!