<template> <div class="row form-group" :key="$attrs.key"> <label :for="localFormElement?.key" class="col-md-3">{{ localFormElement?.label }}:</label> <div v-if="isInitial" class="dropbox"> <input type="file" multiple :name="uploadFieldName" :disabled="isSaving" @change=" filesChange($event.target.name, $event.target.files); fileCount = $event.target.files.length; " accept="image/*" class="input-file" /> <p v-if="isInitial"> Drag your file(s) here to begin<br /> or click to browse </p> <p v-if="isSaving">Uploading {{ fileCount }} files...</p> </div> <!--SUCCESS--> <div v-if="isSuccess"> <h2>{{ uploadedFiles.length }} فایل با موفقیت آپلود شد.</h2> <p> <a href="javascript:void(0)" @click="reset()">فایل جدید</a> </p> <ul class="list-unstyled"> <li v-for="item in uploadedFiles"> <img :src="item.url" class="img-responsive img-thumbnail" :alt="item.originalName" /> </li> </ul> </div> <!--FAILED--> <div v-if="isFailed"> <h2>آپلود فایل ناموفق بود.</h2> <p> <a href="javascript:void(0)" @click="reset()">تلاش مجدد</a> </p> <pre>{{ uploadError }}</pre> </div> </div> </template> <script> const STATUS_INITIAL = 0, STATUS_SAVING = 1, STATUS_SUCCESS = 2, STATUS_FAILED = 3; import { upload } from "@services/fileUploadService"; import { wait } from "@utilities/utilities.js"; import formBuilderMixin from "@mixins/formBuilderMixin"; export default { mixins: [formBuilderMixin], mounted() { this.reset(); }, data() { return { uploadedFiles: [], uploadError: null, currentStatus: null, uploadFieldName: "photos", }; }, computed: { isInitial() { return this.currentStatus === STATUS_INITIAL; }, isSaving() { return this.currentStatus === STATUS_SAVING; }, isSuccess() { return this.currentStatus === STATUS_SUCCESS; }, isFailed() { return this.currentStatus === STATUS_FAILED; }, }, methods: { filesChange(fieldName, fileList) { // handle file changes const formData = new FormData(); if (!fileList.length) return; // append the files to FormData Array.from(Array(fileList.length).keys()).map((x) => { formData.append(fieldName, fileList[x], fileList[x].name); }); // save it this.save(formData); }, save(formData) { // upload data to the server this.currentStatus = STATUS_SAVING; upload(formData) .then(wait(1500)) // DEV ONLY: wait for 1.5s .then((x) => { this.uploadedFiles = [].concat(x); this.currentStatus = STATUS_SUCCESS; }) .catch((err) => { this.uploadError = err.response; this.currentStatus = STATUS_FAILED; }); }, reset() { // reset form to initial state this.currentStatus = STATUS_INITIAL; this.uploadedFiles = []; this.uploadError = null; }, }, }; </script> <!-- SASS styling --> <style lang="scss"> .dropbox { outline: 2px dashed grey; /* the dash box */ outline-offset: -10px; background: lightcyan; color: dimgray; padding: 10px 10px; min-height: 200px; /* minimum height */ position: relative; cursor: pointer; } .input-file { opacity: 0; /* invisible but it's there! */ width: 100%; height: 200px; position: absolute; cursor: pointer; } .dropbox:hover { background: lightblue; /* when mouse over to the drop zone, change color */ } .dropbox p { font-size: 1.2em; text-align: center; padding: 50px 0; } </style>