Reputation: 331
Pretty straightforward. Trying to get multiple files to display but the only one will since there is always only one in the array. When adding another file, the one uploaded before it gets overwritten. this.files is always just one file and and wont add on instead. How can I add on to files, instead of always overwriting? Any help or direction would be greatly appreciated.
<v-file-input
v-model="files"
small-chips
show-size
multiple
clearable
>
<template v-slot:selection="{ text, index, file }">
<v-chip
small
text-color="white"
color="#295671"
close
@click:close="remove(index)"
>
{{ text }}
</v-chip>
</template>
</v-file-input>
<script>
export default {
data: () => ({
files: []
}),
methods: {
remove (index) {
this.files.splice(index, 1)
}
}
}
</script>
Working Example: https://codepen.io/jhernandez_dev/pen/YzzRxMq?&editable=true&editors=101#anon-signup
Upvotes: 4
Views: 15612
Reputation: 11
My problem was to add multiple files from multiple locations on the drive.
I succeed to achieve that by adding a simple watcher :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
currFiles: [],
previousFiles: [],
files: []
}),
watch: {
files(val) {
this.previousFiles = val
}
},
methods: {
remove (index) {
this.files.splice(index, 1)
},
fileAdded () {
console.log(this.files)
if (this.previousFiles.length > 0) {
this.files.push(...this.previousFiles)
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<v-app>
<div class="container">
<v-file-input v-model="files"
small-chips
:show-size="1000"
counter
outlined
placeholder="Select your files"
multiple
clearable
label="Add files"
@change="fileAdded">
<template v-slot:selection="{ text, index, file }">
<v-chip small text-color="white" color="#295671" close @click:close="remove(index)">
{{ text }}
</v-chip>
</template>
</v-file-input>
</div>
</v-app>
</div>
Upvotes: 0
Reputation: 1943
You can do one thing
input
tag and add a reference to itv-select
component with prepend icon and append outer icon as a part of actionsTemplate
<input type="file" hidden multiple ref="files" @change="listFiles">
<v-select
v-model="files"
:items="files"
chips
readonly
prepend-icon="attach_file"
multiple
@click="$refs.files.click()"
@click:prepend="$refs.files.click()"
@click:append-outer="uploadHere"
label="Files"
append-icon
append-outer-icon="cloud_upload"
></v-select>
Script
export default {
data() {
return {
files: []
};
},
methods: {
listFiles() {
this.files = [];
for (let i = 0; i < this.$refs.files.files.length; i++)
this.files.push(this.$refs.files.files[i].name);
},
uploadHere()
{
console.log("Uploading");
let formData = new FormData();
// iteratate this.$refs.files.files
// add data to formData
// Post the form data with 'Content-Type': 'multipart/form-data' via fetch or Axios
console.log("Uploaded");
this.files = []
}
},
created() {}
};
PS: This is an approach. If you find any difficulty in understanding, comment below
Upvotes: 2
Reputation: 362360
I solved this problem by merging 2 file arrays. One for the current selected files, and another for all files...
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
currFiles: [],
files: []
}),
methods: {
remove (index) {
this.files.splice(index, 1)
},
inputChanged () {
console.log(this.files)
this.files = [
...this.currFiles,
...this.files
]
}
}
})
Upvotes: 4
Reputation: 1
You can try doing something like this.
<template>
<v-file-input
id="uploadedfiles"
v-model="files"
show-size
counter
multiple
clearable
label="File input"
name="uploadedfiles"
:rules="[filesizeLimit]"
@change="inputChanged"
>
<template #selection="{ index, text }">
<v-chip small label close color="primary" @click:close="deleteChip(index, text)">{{ text }}</v-chip>
</template>
</v-file-input>
</template>
<script>
export default {
methods: {
deleteChip(index, text) {
// Prompt here with text if required
this.previousFiles.splice(index, 1)
this.files = this.previousFiles
},
inputChanged() {
this.files = []
const uploadedFiles = this.$refs.form.$el.querySelector('#uploadedfiles').files
for (let i = 0; i < uploadedFiles.length; i++) {
if (
this.previousFiles !== undefined &&
this.previousFiles !== null &&
this.previousFiles.length <= 0
) {
this.previousFiles.push(uploadedFiles[i])
} else {
const index = this.previousFiles.findIndex((x) => x.name === uploadedFiles[i].name)
if (index >= 0) {
this.previousFiles.splice(index, 1)
}
this.previousFiles.push(uploadedFiles[i])
}
}
this.files = this.previousFiles
},
},
}
</script>
Upvotes: 0