125 lines
3.7 KiB
Vue
125 lines
3.7 KiB
Vue
<template>
|
|
<div class="a-select-file">
|
|
<div class="a-select-file-list" ref="list">
|
|
<div class="flex-column file-preview">
|
|
<div class="field flex-grow-1" v-if="!uploadFile">
|
|
<label class="label">{{ uploadLabel }}</label>
|
|
<input type="file" @change="previewFile"/>
|
|
</div>
|
|
<slot name="upload-preview" :item="uploadFile"></slot>
|
|
<div v-if="uploadFile">
|
|
<button class="button secondary" @click="removeUpload">
|
|
<span class="icon">
|
|
<i class="fa fa-trash"></i>
|
|
</span>
|
|
</button>
|
|
<button class="button float-right" @click="doUpload">
|
|
<span class="icon">
|
|
<i class="fa fa-upload"></i>
|
|
</span>
|
|
Upload
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="prevUrl">
|
|
<a href="#" @click="load(prevUrl)">
|
|
{{ prevLabel }}
|
|
</a>
|
|
</div>
|
|
|
|
<template v-for="item in items" v-bind:key="item.id">
|
|
<div :class="['file-preview', this.item && item.id == this.item.id && 'active']" @click="select(item)">
|
|
<slot :item="item"></slot>
|
|
</div>
|
|
</template>
|
|
|
|
<div v-if="nextUrl">
|
|
<a href="#" @click="load(nextUrl)">
|
|
{{ nextLabel }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="a-select-footer">
|
|
<slot name="footer" :item="item" :items="items"></slot>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import {getCsrf} from "../model"
|
|
|
|
export default {
|
|
props: {
|
|
name: { type: String },
|
|
prevLabel: { type: String, default: "Prev" },
|
|
nextLabel: { type: String, default: "Next" },
|
|
listUrl: { type: String },
|
|
uploadLabel: { type: String, default: "Upload a file" },
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
item: null,
|
|
items: [],
|
|
uploadFile: null,
|
|
uploadUrl: null,
|
|
uploadFieldName: null,
|
|
uploadCSRF: null,
|
|
nextUrl: "",
|
|
prevUrl: "",
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
previewFile(event) {
|
|
const [file] = event.target.files
|
|
this.uploadFile = file && {
|
|
file: file,
|
|
src: URL.createObjectURL(file)
|
|
}
|
|
},
|
|
|
|
removeUpload() {
|
|
this.uploadFile = null;
|
|
},
|
|
|
|
doUpload() {
|
|
const formData = new FormData();
|
|
formData.append('file', this.uploadFile.file)
|
|
formData.append('original_filename', this.uploadFile.file.name)
|
|
formData.append('csrfmiddlewaretoken', getCsrf())
|
|
fetch(this.listUrl, {
|
|
method: "POST",
|
|
body: formData
|
|
}).then(
|
|
() => {
|
|
this.uploadFile = null;
|
|
this.load()
|
|
}
|
|
)
|
|
},
|
|
|
|
load(url) {
|
|
fetch(url || this.listUrl).then(
|
|
response => response.ok ? response.json() : Promise.reject(response)
|
|
).then(data => {
|
|
this.nextUrl = data.next
|
|
this.prevUrl = data.previous
|
|
this.items = data.results
|
|
|
|
this.$forceUpdate()
|
|
this.$refs.list.scroll(0, 0)
|
|
})
|
|
},
|
|
|
|
select(item) {
|
|
this.item = item;
|
|
},
|
|
},
|
|
|
|
mounted() {
|
|
this.load()
|
|
},
|
|
}
|
|
</script>
|