DEV Community

Ridwan Kasim
Ridwan Kasim

Posted on

Working with multiple image select in Laravel Livewire

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

full code

Let's start by looking at what Updating and Updated hooks do. 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;
}
Enter fullscreen mode Exit fullscreen mode

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" />
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

The above code merges the data of the $prevImages property with the data of the newly selected image/images then stores 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!!!

Top comments (0)