I see you're using Alpine as well, well I didn't go through the whole code, @Sinnbeck wrote about this, and it is probably the best article about file uploading with this stack, and it's well detailed, so take a look
Issues with file upload
Hello all !👋 I’m trying to learn Laravel Livewire and its file upload part.(https://laravel-livewire.com/docs/2.x/file-uploads) For this, I made an application with a droparea for an Excel file.
Here, you can retrieve the code :
<div x-data="dropFile()">
<div x-show="error" class="alert alert--danger alert--icon">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<p x-text="errorMsg"></p>
</div>
@error('file')
<div class="alert alert--danger alert--icon">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<p>{{ $message }}</p>
</div>
@enderror
<div
id="dropzone"
x-bind:class="dropingFile ? 'dropzone is-highlighted' : 'dropzone'"
x-on:drop="dropingFile = false"
x-on:drop.prevent="handleFileDrop($event)"
x-on:dragover.prevent="dropingFile = true"
x-on:dragleave.prevent="dropingFile = false"
x-on:livewire-upload-start="isUploading = true"
x-on:livewire-upload-finish="isUploading = false"
x-on:livewire-upload-error="isUploading = false"
x-on:livewire-upload-progress="progress = $event.detail.progress"
>
<form wire:submit.prevent="saveFile" enctype="multipart/form-data">
<input type="file" name="file" wire:model="file">
</form>
<h3>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
</svg>
Drop a .csv or xls file here
</h3>
</div>
<div x-show="isUploading">
<progress max="100" x-bind:value="progress"></progress>
</div>
</div>
<script>
const dropFile = () => {
return {
dropingFile: false,
isUploading: false,
error: false,
errorMsg: '',
progress: 0,
handleFileDrop(e) {
this.error = false;
if (e.dataTransfer.files.length > 0) {
const file = e.dataTransfer.files;
if (e.dataTransfer.files.length > 1) {
this.error = true;
this.errorMsg = 'You can only import one file.';
} else if
(
e.dataTransfer.files[0].type !== "application/vnd.ms-excel" &&
e.dataTransfer.files[0].type !== "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
this.error = true;
this.errorMsg = "You can only import a CSV or XLS file";
} else {
@this.upload('file', file[0], (uploadedFilename) => {
this.isUploading = false;
}, () => {
console.log('error');
}, (event) => {
this.isUploading = true;
this.progress = event.detail.progress;
})
}
}
}
}
}
</script>
As you can see, I use the droparea to drag and drop a file (with AlpineJS), or if you click on the area, it will trigger the input[type="file"].
The component’s Livewire code is:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithFileUploads;
class UploadExcel extends Component
{
use WithFileUploads;
public $file = [];
protected $rules = [
'file' => 'required|file|mimes:csv,xlsx,xls|max:102400',
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function saveFile()
{
$this->validate();
$this->file->store('csv', 'local');
}
public function render()
{
return view('livewire.upload-excel');
}
}
My problems are :
- The validation does not work. Whether it is via input or drag and drop. I am told that the file field must be a file.
- If I remove the "file" in $rules, I am told that the file type is not the right one, although I do have an Excel file.
- If I remove the rules, the file is present in the "livewire-tmp" folder, but nothing on the final disk.
I'm in local, on Windows with Laragon. The storage:link on storage folder is good, permissions also.
I’m starting with Livewire and wondering if I missed something... I don’t understand why validation fails every time and why the file is not transferring from temporary folder to final folder.
Thank you for your help😇
@Vable I notice that you dont have anything to call the save() method in the shown html?
<button type="button" wire:click="save">Save</button>
Please or to participate in this conversation.