Files
exchange-2.0/resources/assets/vue/components/general/forms/FileUploadComponent.vue
T
2026-01-12 13:32:23 +08:00

179 lines
12 KiB
Vue

<template>
<div class="dropzone no-border no-padding text-center" style="min-height: auto;">
<div class="dz-message hide"></div>
<div class="dragzone row m-l-0 m-r-0 bg-master-lightest" :class="[{'m-b-15': hasFile}]" style="border-width: 1px;">
<div class="col">
<loading-component style="height: 200px; top: 0;" color="success" v-show="isLoading"></loading-component>
<div class="row" v-show="!isLoading">
<div class="col">
<div class="row p-b-20 p-t-15" v-show="!hasFile" style="min-height: 150px;">
<div class="col">
<div class="row justify-content-center m-b-10 m-t-10">
<div class="col-auto">
<div class="icon-thumbnail bg-transparent">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 172 172"
style=" fill:#000000;"><defs><linearGradient x1="86" y1="79.28125" x2="86" y2="149.85769" gradientUnits="userSpaceOnUse" id="color-1_48264_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="19.48438" x2="86" y2="131.01831" gradientUnits="userSpaceOnUse" id="color-2_48264_gr2"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g><path d="M104.8125,104.8125l-16.60337,-23.71987c-1.075,-1.53456 -3.34594,-1.53456 -4.41825,0l-16.60338,23.71988h13.4375v40.3125c0,1.4835 1.204,2.6875 2.6875,2.6875h5.375c1.4835,0 2.6875,-1.204 2.6875,-2.6875v-40.3125z" fill="url(#color-1_48264_gr1)"></path><path d="M137.60269,67.97763c1.41362,-3.66575 2.14731,-7.53037 2.14731,-11.54013c0,-17.78319 -14.46681,-32.25 -32.25,-32.25c-13.87287,0 -25.95319,8.82306 -30.41444,21.55912c-0.16394,-0.13437 -0.34937,-0.23919 -0.516,-0.36819c-0.52406,-0.40581 -1.05888,-0.79281 -1.61519,-1.15563c-0.35206,-0.22844 -0.7095,-0.44344 -1.06963,-0.65306c-0.52137,-0.301 -1.05619,-0.57781 -1.60175,-0.84119c-0.31712,-0.15319 -0.62619,-0.3225 -0.95137,-0.45956c-0.8385,-0.36012 -1.70119,-0.66919 -2.58537,-0.93256c-0.29025,-0.086 -0.58588,-0.1505 -0.87881,-0.22575c-0.69875,-0.18006 -1.40825,-0.33325 -2.13119,-0.44881c-0.301,-0.05106 -0.59663,-0.10213 -0.90031,-0.13706c-0.99438,-0.12631 -1.99681,-0.21231 -3.02344,-0.21231c-13.33537,0 -24.1875,10.84944 -24.1875,24.1875v8.0625c-11.85456,0 -21.5,9.64544 -21.5,21.5c0,11.85456 9.64544,21.5 21.5,21.5h2.6875v2.6875c0,4.44512 3.61738,8.0625 8.0625,8.0625h24.1875v-5.375h-24.1875c-1.48081,0 -2.6875,-1.204 -2.6875,-2.6875v-2.6875h26.875v-5.375h-34.9375c-8.89294,0 -16.125,-7.23206 -16.125,-16.125c0,-8.89294 7.23206,-16.125 16.125,-16.125h10.75v-5.375h-5.375v-8.0625c0,-10.37106 8.43875,-18.8125 18.8125,-18.8125c0.7955,0 1.57756,0.06719 2.35156,0.16394c0.23112,0.02956 0.45956,0.06719 0.688,0.1075c0.56975,0.09406 1.12875,0.21231 1.68238,0.35475c0.22037,0.05644 0.44075,0.10481 0.65844,0.16931c0.69338,0.20694 1.37063,0.44881 2.03175,0.73369c0.23381,0.10213 0.45956,0.22306 0.688,0.33325c0.44613,0.215 0.88688,0.44344 1.31419,0.69069c0.26337,0.15319 0.52406,0.30906 0.77669,0.473c0.47569,0.30906 0.93794,0.63963 1.38406,0.99169c0.19081,0.1505 0.38431,0.29831 0.56975,0.45688c0.50525,0.43 0.98631,0.88687 1.44319,1.37063c0.14781,0.15588 0.28756,0.31444 0.43,0.473c0.47837,0.5375 0.93525,1.0965 1.3545,1.69312c0.02419,0.03225 0.04838,0.06181 0.06987,0.09406c0.48375,0.69875 0.92181,1.43781 1.31419,2.21181c1.30612,2.55313 2.05594,5.43413 2.05594,8.49519h5.375c0,-3.913 -0.95406,-7.59756 -2.60956,-10.86825l0.00806,-0.00269c-0.01613,-0.02956 -0.03494,-0.05644 -0.05106,-0.086c-0.4945,-0.96481 -1.04006,-1.89738 -1.6555,-2.78425c-0.05644,-0.08331 -0.12363,-0.15856 -0.18275,-0.24188c-0.05106,-0.06987 -0.10481,-0.13975 -0.15587,-0.20962c2.81919,-12.09106 13.60144,-20.74481 26.14669,-20.74481c14.81888,0 26.875,12.05613 26.875,26.875c0,3.77056 -0.80088,7.3745 -2.29512,10.7715l-8.4495,-0.0215l-0.01344,5.375l8.44144,0.0215c10.1695,0.19888 18.44163,8.62956 18.44163,18.791c0,10.37106 -8.43875,18.8125 -18.8125,18.8125h-32.25v5.375h26.875v2.6875c0,1.4835 -1.20669,2.6875 -2.6875,2.6875h-24.1875v5.375h24.1875c4.44512,0 8.0625,-3.61738 8.0625,-8.0625v-2.6875c13.33538,0 24.1875,-10.84944 24.1875,-24.1875c0,-11.18537 -7.80181,-20.71256 -18.27231,-23.39737z" fill="url(#color-2_48264_gr2)"></path></g></g></svg>
</div>
</div>
</div>
<div class="row m-b-10">
<div class="col">
<div class="all-caps fs-12 hint-text" style="letter-spacing: 1px;">Drag and drop files here</div>
</div>
</div>
<div class="row m-b-10 justify-content-center">
<div class="col-4">
<div class="row align-items-center">
<div class="col b-t b-grey"></div>
<div class="col-auto all-caps fs-10 hint-text muted">Or</div>
<div class="col b-t b-grey"></div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="btn btn-sm btn-outline-complete b-rad-none pointer select-btn hint-text">Browse files</div>
</div>
</div>
</div>
</div>
<div class="row text-left" v-show="hasFile">
<div class="col p-b-15 p-t-15">
<div class="all-caps fs-12 hint-text" style="letter-spacing: 1px;">Drag and drop files here</div>
</div>
<div class="col-2 no-padding">
<div class="btn btn-xs btn-primary btn-block b-rad-none pointer select-btn h-100">
<div class="row align-items-center h-100">
<div class="col">
<i class="fa fa-plus"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: Array,
required: false
},
withMeta: {
type: Boolean,
default: false
}
},
data(){
return {
isLoading: false,
hasFile: false,
files: []
}
},
mounted(){
let vm = this;
var dropzone = new Dropzone(this.$el, {
url: '#',
autoQueue: false,
processQueue: false,
acceptedFiles: 'image/*, application/*',
uploadMultiple: true,
clickable: '.select-btn',
previewTemplate: '<div class="row m-l-0 m-r-0 align-items-center m-t-5 m-b-5 bg-master-lightest text-left p-t-10 p-b-10 "> <div class="col-auto p-r-0"> <img data-dz-thumbnail style="width: 35px; height: 35px;" /> </div> <div class="col"> <div class="row m-b-5"> <div class="col"> <div class="dz-filename fs-8 bold"><span data-dz-name></span></div> </div> </div> <div class="row"> <div class="col"> <div class="dz-size muted light fs-10" data-dz-size></div> </div> </div> </div> <div class="col-auto"><i class="fs-16 fa fa-times-circle pointer hint-text" data-dz-remove></i></div> </div>'
});
dropzone.autoDiscover = false;
dropzone.on("removedfile", function() {
vm.updateFiles(dropzone.files);
});
dropzone.on("addedfile", function(file) {
vm.isLoading = true;
// const pdfIconUrl = "https://assets.izyim.com/public/images/icons/pdf.png";
// const xlsIconUrl = "https://assets.izyim.com/public/images/icons/xlsx.png";
if(file.name.split('.').pop() === 'pdf'){
//$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", Vapor.asset("images/icons/pdf.png"));
//$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", pdfIconUrl);
const thumbnailElement = file.previewElement.querySelector("[data-dz-thumbnail]");
if (thumbnailElement) {
thumbnailElement.src = Vapor.asset("images/icons/pdf.png");
}
}
if(file.name.split('.').pop().indexOf("xls") !== -1){
//$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", Vapor.asset("images/icons/xlsx.png"));
//$(file.previewElement).closest("img[data-dz-thumbnail]").attr("src", xlsIconUrl);
const thumbnailElement = file.previewElement.querySelector("[data-dz-thumbnail]");
if (thumbnailElement) {
thumbnailElement.src = Vapor.asset("images/icons/xlsx.png");
}
}
Promise.all(dropzone.files.map(function(file){
return vm.fileToBase64(file).then(function(data){
return data;
})
})).then(function(files) {
vm.isLoading = false;
vm.updateFiles(files);
})
});
dropzone.on("dragover", function() {
$(vm.$el).closest('.dragzone').css('opacity', 0.5)
});
dropzone.on("dragleave", function() {
$(vm.$el).closest('.dragzone').css('opacity', 1)
});
dropzone.on("drop", function() {
$(vm.$el).closest('.dragzone').css('opacity', 1)
});
},
methods: {
fileToBase64(file) {
const vm = this;
return new Promise(resolve => {
var reader = new FileReader();
reader.onload = function(event) {
// If meta requested, return object
if (vm.withMeta) {
resolve({
name: file.name,
type: file.type,
size: file.size,
base64: event.target.result
});
} else {
resolve(event.target.result);
}
};
reader.readAsDataURL(file);
});
},
updateFiles(files){
this.hasFile = !!files.length;
this.files = files;
this.$emit('input', files)
}
}
}
</script>