mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-04 03:27:05 -04:00

The invisible input element covering the button also covered the translation text. I found a post on stackoverflow that suggested hiding the input element entirely and instead attaching a label to it and styling that. This seems to still work for uploads and can be translated now. https://stackoverflow.com/questions/572768/styling-an-input-type-file-button
98 lines
2.9 KiB
Vue
98 lines
2.9 KiB
Vue
<template>
|
|
<div>
|
|
<input type="file"
|
|
:id="id"
|
|
:name="name + (multiple ? '[]' : '')"
|
|
:multiple="multiple"
|
|
:disabled="uploading"
|
|
@change="filesChange($event.target.name, $event.target.files)"
|
|
:accept="mime"/>
|
|
<label
|
|
:for="id"
|
|
:class="['uploader-container', form ? 'form-control p-2' : classes, drag ? 'drag' : '']"
|
|
@dragover="drag=true" @dragleave="drag=false"
|
|
>
|
|
<p v-if="errorMessage" class="text-danger mb-0">
|
|
<Icon v="exclamation-circle"/>
|
|
<T>{{errorMessage}}</T>
|
|
</p>
|
|
<p v-else-if="uploading" class="mb-0">
|
|
<Spinner/>
|
|
</p>
|
|
<p v-else class="mb-0">
|
|
<slot>
|
|
<Icon v="upload"/>
|
|
<T>images.upload.instructionShort</T>
|
|
</slot>
|
|
</p>
|
|
</label>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
url: {required: true},
|
|
multiple: {type: Boolean},
|
|
mime: {'default': '*/*'},
|
|
name: {'default': 'files'},
|
|
form: {type: Boolean},
|
|
classes: {'default': 'btn btn-outline-primary btn-sm'},
|
|
},
|
|
data() {
|
|
return {
|
|
uploading: false,
|
|
drag: false,
|
|
errorMessage: '',
|
|
id: `upload-${this.name}`,
|
|
}
|
|
},
|
|
methods: {
|
|
async filesChange(fieldName, fileList) {
|
|
if (!fileList.length) {
|
|
return;
|
|
}
|
|
this.drag = false;
|
|
const formData = new FormData();
|
|
for (let file of fileList) {
|
|
formData.append(fieldName, file, file.name);
|
|
}
|
|
await this.save(formData);
|
|
},
|
|
async save(formData) {
|
|
this.uploading = true;
|
|
this.errorMessage = '';
|
|
try {
|
|
const ids = await this.$axios.$post(this.url, formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data'
|
|
}
|
|
});
|
|
this.$emit('uploaded', ids);
|
|
} catch (e) {
|
|
this.errorMessage = e?.response?.data?.error || 'error.invalidImage';
|
|
}
|
|
this.uploading = false;
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "../assets/style";
|
|
|
|
.uploader-container {
|
|
position: relative;
|
|
cursor: pointer;
|
|
&.form-control {
|
|
&:hover, &.drag {
|
|
background: lighten($primary, 50%);
|
|
}
|
|
}
|
|
}
|
|
|
|
input[type="file"] {
|
|
display: none;
|
|
}
|
|
</style>
|