<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>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.