I’m working on an avatar uploader for my project. Everything has been so far so good, and this morning I had no issues. A little while later, BOOM. Death and destruction. Very sadness.
When I first choose a file, it pops up the crop tool immediately, and works fine. If I attempt to upload a different file, the crop tool disappears and not even a preview of the image is presented.
Here’s the form I’m working on. It’s also the component that’s refreshed every time that Livewire sees a new file in the input.
<label for="image-upload">
<div class="w-full mt-4 button"><i class="far fa-fw fa-upload"></i> Drag and drop, or <b>browse</b></div>
</label>
<input id="image-upload" type="file" wire:model="image" class="hidden" accept="image/png, image/gif, image/jpeg">
@if($image)
<div id="avatar-preview" class="w-full" style="height: 300px;"></div>
<script>
new Croppie(document.querySelector('#avatar-preview'), {
viewport: { width: 200, height: 200, type: 'circle' },
enforceBoundary: true,
}).bind('{!! $image->temporaryUrl() !!}');
</script>
<button type="submit" class="w-full mt-16 button is-green">Submit new avatar</button>
@endif
I’m using the Croppie JS package for the crop tool. It requires that I either pass it an img
element it’ll attach to, or a container to fit into. I picked a container so I could control the size of the crop tool. I attempt to create a new Croppie instance, attach it to my preview container, and bind the temporary image to it.
This works on the first file upload! Then, when I attempt to change the file (as a user might) the entire instance disappears. I attempted to check and see if it was an issue instantiating Croppie again, since in my mind if the component is refreshed, creating a new instance of the tool shouldn’t be an issue.
<script>
if (typeof crop === 'undefined') {
console.log('crop undefined');
let crop = new Croppie(document.querySelector('#avatar-preview'), {
viewport: { width: 200, height: 200, type: 'circle' },
enforceBoundary: true,
}).bind('{!! $image->temporaryUrl() !!}');
} else {
console.log('crop defined');
crop.bind('{!! $image->temporaryUrl() !!}');
}
console.log('crop finished');
</script>
And the ‘undefined’ and ‘finished’ logs come in on the first upload, but nothing happens on the refresh.
So I also tested just doing this…
@if($image)
<img src="{{ $image->temporaryUrl() }}">
@endif
To ensure at the very least that the preview was working correctly, and lo and behold it does!
The big problem is that even when the Croppie doesn’t refresh, no errors or warnings occur. It just doesn’t seem to execute what’s in the <script>
tag at all.
Any tips or advice?