forked from rc/aircox
cfr #121 Co-authored-by: Christophe Siraut <d@tobald.eu.org> Co-authored-by: bkfox <thomas bkfox net> Co-authored-by: Thomas Kairos <thomas@bkfox.net> Reviewed-on: rc/aircox#131 Co-authored-by: Chris Tactic <ctactic@noreply.git.radiocampus.be> Co-committed-by: Chris Tactic <ctactic@noreply.git.radiocampus.be>
111 lines
3.4 KiB
Vue
111 lines
3.4 KiB
Vue
<template>
|
|
<div ref="list" class="a-select-file-list">
|
|
<form ref="form" class="flex-column" v-if="state == STATE.DEFAULT">
|
|
<slot name="form"></slot>
|
|
<div class="field is-horizontal">
|
|
<label class="label">{{ label }}</label>
|
|
<input type="file" ref="uploadFile" :name="fieldName" @change="onFileChange"/>
|
|
</div>
|
|
<div class="flex-row align-right" v-if="submitLabel">
|
|
<button type="button" class="button small" @click="submit">
|
|
{{ submitLabel }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
<div class="flex-column" v-else>
|
|
<slot name="preview" :fileUrl="fileUrl" :file="file" :loaded="loaded" :total="total"></slot>
|
|
<div class="flex-row">
|
|
<progress :max="total" :value="loaded"/>
|
|
<button type="button" class="button small square ml-2" @click="abort">
|
|
<span class="icon small">
|
|
<i class="fa fa-close"></i>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import {getCsrf} from "../model.js"
|
|
|
|
export default {
|
|
emit: ["fileChange", "load", "abort", "error"],
|
|
|
|
props: {
|
|
url: { type: String },
|
|
fieldName: { type: String, default: "file" },
|
|
label: { type: String, default: "Select a file" },
|
|
submitLabel: { type: String, default: "Upload" },
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
STATE: {
|
|
DEFAULT: 0,
|
|
UPLOADING: 1,
|
|
},
|
|
state: 0,
|
|
upload: {},
|
|
file: null,
|
|
fileUrl: null,
|
|
total: 0,
|
|
loaded: 0,
|
|
request: null,
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
abort() {
|
|
this.request && this.request.abort()
|
|
},
|
|
|
|
onFileChange() {
|
|
const [file] = this.$refs.uploadFile.files
|
|
if(!file)
|
|
return
|
|
this._setUploadFile(file)
|
|
this.$emit("fileChange", {upload: this, file: this.file, fileUrl: this.fileUrl})
|
|
},
|
|
|
|
submit() {
|
|
const req = new XMLHttpRequest()
|
|
req.open("POST", this.url)
|
|
req.upload.addEventListener("progress", (e) => this.onUploadProgress(e))
|
|
req.addEventListener("load", (e) => this.onUploadDone(e, 'load'))
|
|
req.addEventListener("abort", (e) => this.onUploadDone(e, 'abort'))
|
|
req.addEventListener("error", (e) => this.onUploadDone(e, 'error'))
|
|
|
|
const formData = new FormData(this.$refs.form);
|
|
formData.append('csrfmiddlewaretoken', getCsrf())
|
|
req.send(formData)
|
|
|
|
this._resetUpload(this.STATE.UPLOADING, false, req)
|
|
},
|
|
|
|
onUploadProgress(event) {
|
|
this.loaded = event.loaded
|
|
this.total = event.total
|
|
},
|
|
|
|
onUploadDone(event, eventName) {
|
|
this.$emit(eventName, event)
|
|
this._resetUpload(this.STATE.DEFAULT, true)
|
|
},
|
|
|
|
_setUploadFile(file) {
|
|
this.file = file
|
|
this.fileURL = file && URL.createObjectURL(file)
|
|
},
|
|
|
|
_resetUpload(state, resetFile=false, request=null) {
|
|
this.state = state
|
|
this.loaded = 0
|
|
this.total = 0
|
|
this.request = request
|
|
if(resetFile)
|
|
this.file = null
|
|
}
|
|
|
|
},}
|
|
</script>
|