[Livewire 3, Laravel, some Alpine.js] Progress bar for Image-Upload Nested Component not working
I have extracted the important code, this is not my full code. I have a simple ImageUpload Livewire 3 component. I use this as a nested component in my Listing/ create.blade.php View Component:
<form wire:submit="save">
<livewire:image.image-upload wire:model="image"></livewire:image.image-upload>
</form>
So, here is the actual ImageUpload Component
class ImageUpload extends Component
{
use WithFileUploads;
#[Validate]
public $image;
public function render()
{
return view('livewire.image.upload');
}
public function updatedImage(): bool
{
try{
$this->validate();
return true;
}catch (ValidationException $e) {
$this->reset('image');
return false;
}
}
}
Then in my Image/ upload.blade.php View Component I have:
...
<form>
{{-- Progress Bar--}}
<div
x-data="{ uploading: false, progress: 0, paused: false }"
x-on:livewire-upload-start="uploading = true; console.log('started');"
x-on:livewire-upload-finish="uploading = false; console.log('finished');"
x-on:livewire-upload-error="uploading = false"
x-on:livewire-upload-progress="progress = $event.detail.progress"
>
<div x-show="uploading">
<progress max="100" x-bind:value="progress"></progress>
</div>
</div>
{{-- Image Input--}}
<input type="file" id="image" wire:model="image" class="hidden"
x-ref="image" x-on:change="handleImageChange"
accept="image/png, image/jpeg, image/webp"
>
<x-secondary-button type="button"
x-on:click.prevent="$refs.image.click();"
>
{{ __('Upload a new image') }}
</x-secondary-button>
<x-input-error for="image" class="mt-2" />
</form>
...
<script>
function handleImageChange(event) {
const input = event.target;
const reader = new FileReader();
reader.onload = (e) => {
this.imageName = input.files[0].name;
this.imagePreview = e.target.result;
};
reader.readAsDataURL(input.files[0]);
}
</script>
I have console.logs in the x-on:livewire-upload-start/finish and they never show up in the console when I upload an image, nor when I load the page and upload for the first time. I added this JS to test it out, to my <script> tags:
document.addEventListener('livewire-upload-start', () => {
console.log('Livewire upload started');
});
document.addEventListener('livewire-upload-progress', (event) => {
console.log('Livewire upload progress:', event.detail.progress);
});
And this works. When I upload a 2MB image I get this printed in the Console:
Livewire upload started
Livewire upload progress: 19
Livewire upload progress: 20
Livewire upload progress: 29
Livewire upload progress: 45
Livewire upload progress: 61
Livewire upload progress: 79
Livewire upload progress: 99
Livewire upload progress: 100
I uploaded 2 consecutive files and it works each time. I dont have a submit on the form, because I dont need it, I actually dont even need the form. I think so, anyways, correct me If Im wrong, please. I place the ImageUpload component inside a form element already (In the Listing/ create.blade.php Livewire View component). Not really sure how nested components are supposed to work in this case, the Livewire documentation is...Average to say the least. At this point Im guessing there's something wrong with the x-show or the x-on in x-on:livewire-upload-start="uploading = true; console.log('started');", because no progress bar is shown, but what could be wrong? I mean the Livewire Progress Bar documentation is pretty clear and simple, so maybe the nesting somehow?
I tried it without the form, still the same. I need to use the updatedImage(). I had the idea where I change the code of the <x-secondary-button> so that it submits to a function in the ImageUpload Component, as well as a wire:submit on the form, nothing
Please or to participate in this conversation.