<div x-data="xData()">
<input type="file" x-ref="input" x-on:change="selectedFiles($event)">
<div x-on:click="$refs.input.click()" class="flex justify-center items-center gap-2 p-8 bg-gray-100 dark:bg-dark-eval-1 rounded-md border border-dashed border-gray-400 dark:border-gray-600 cursor-pointer">
<div class="w-5">
<x-admin.icons.upload></x-admin.icons.upload>
</div>
Завантажити файл
</div>
<template x-for="(file, index) in getData().files" :key="index">
<div class="mb-5 mt-5 grid grid-cols-5 gap-4 items-center">
<div class="col-span-5 sm:col-span-1">
<template x-if="file.isImage">
<img :src="file.src" alt="image" x-show="file.src.length" class="w-full h-[100px] object-cover rounded-md">
</template>
<template x-if="!file.isImage">
<div class="w-full h-[100px] bg-gray-100 dark:bg-dark-eval-1 border dark:border-gray-600 rounded-md flex justify-center items-center text-gray-400">
<x-admin.icons.document class="w-10"></x-admin.icons.document>
</div>
</template>
</div>
<div class="col-span-5 sm:col-span-4">
<div x-text="file.name" class="mb-2 text-sm md:text-base"></div>
<div x-text="file.size" class="mb-2 text-xs text-gray-500"></div>
<div class="flex gap-4">
<div x-on:click="changeFile(index)" x-show="file.src.length" class="cursor-pointer text-sm md:text-base text-blue-500">
{{ __('Редагувати') }}
</div>
<div x-on:click="deleteFile(index)" x-show="file.src.length" class="cursor-pointer text-sm md:text-base text-red-500">
{{ __('Видалити') }}
</div>
</div>
</div>
</div>
</template>
</div>
<script>
function xData() {
return {
data: {
files: [],
inputFiles: [],
index: null
},
getData: function() {
return this.data
},
selectedFiles: function(event) {
if (event.target && event.target.files) {
const files = event.target.files;
if (files.length > 0 && this.data.index == undefined && this.data.index == null) {
if (this.data.inputFiles.length > 0) {
let updatedFileList = new DataTransfer();
Array.from(this.data.inputFiles).forEach(file => updatedFileList.items.add(file));
Array.from(files).forEach(file => updatedFileList.items.add(file));
this.data.inputFiles = updatedFileList.files;
this.$refs.input.files = this.data.inputFiles;
} else {
this.data.inputFiles = files;
}
this.data.files = this.loopFileArray(this.$refs.input.files)
console.log(this.$refs.input.files)
}
if (this.data.index !== undefined && this.data.index !== null) {
// remove file with index
if (files.length > 0) {
const newFileList = new DataTransfer();
const originalFiles = this.data.inputFiles;
let uploadedFiles = this.$refs.input.files;
Array.from(originalFiles).forEach((value, index) => {
if (index === this.data.index) {
console.log('true')
Array.from(uploadedFiles).forEach((uploadedFile) => {
newFileList.items.add(uploadedFile);
});
} else {
newFileList.items.add(value);
}
});
this.data.inputFiles = newFileList.files;
this.$refs.input.files = newFileList.files;
this.data.files = this.loopFileArray(this.$refs.input.files);
console.log(this.$refs.input.files)
}
this.data.index = null;
}
}
},
changeFile: function(index) {
this.$refs.input.click();
this.data.index = index;
},
deleteFile: function(index) {
this.data.files.splice(index, 1);
const newFileList = new DataTransfer();
const originalFiles = this.$refs.input.files;
const filesToKeep = Array.from(originalFiles).filter((file, i) => index !== i);
filesToKeep.forEach(file => newFileList.items.add(file));
this.$refs.input.files = newFileList.files;
this.data.inputFiles = newFileList.files;
this.data.files = this.loopFileArray(this.$refs.input.files);
console.log(this.$refs.input.files);
},
loopFileArray: function(data) {
return Array.prototype.map.call(data, function(file) {
const fileSizeInMB = (file.size / (1024 * 1024)).toFixed(2);
const fileSizeInKB = (file.size / 1024).toFixed(2);
return {
'size': fileSizeInMB > 1 ? fileSizeInMB + ' MB' : fileSizeInKB + ' KB',
'src': URL.createObjectURL(file),
'name': file.name,
'isImage': file.type.match('image.*')
};
});
},
}
}
</script>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.