162 lines
3.8 KiB
Vue
162 lines
3.8 KiB
Vue
![]() |
<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>
|