0

I have a component that dynamically adds inputs to my application. One input is a text input and another is a file input. In the case of text input everything works, I take the value via v-model. In the case of file input it is not possible to use v-model, instead v-on: change is used. How do I add the filename to the lists object dynamically?

Template

<template lang="html">

    <div v-for="list in lists">

        <input type="text" v-model="list.text" >
        
        <input type="file" @change="upload">

    </div>
    
    <button @click="addItem">Add Item</button>

</template>

Script

<script>

export default {

    data() {
        return {
        lists:[{text: '', filename: '',}]
        }
    },
    
    methods: {
        addItem() {
            this.lists.push({ text: '', filename: '' })
        },

        upload(event) {
            this.lists.filename = event.target.files[0].name
        },
    }
}

</script>

I'm using Vue 3.

Thanks in advance.

  • Does this answer your question? [javascript - get the filename and extension from input type=file](https://stackoverflow.com/questions/43708127/javascript-get-the-filename-and-extension-from-input-type-file) – Majid Ghafoorzade Jan 06 '21 at 05:37

3 Answers3

1

You can iterate with the index as well, then pass the index to the upload function, like this:

<script>

export default {

    data() {
        return {
        lists:[{text: '', filename: '',}]
        }
    },
    
    methods: {
        addItem() {
            this.lists.push({ text: '', filename: '' })
        },

        upload(event, index) {
            this.lists[index].filename = event.target.files[0].name
        },
    }
}

</script>
<template lang="html">

    <div v-for="(list, index) in lists">

        <input type="text" v-model="list.text" >
        
        <input type="file" @change="upload($event, index)">

    </div>
    
    <button @click="addItem">Add Item</button>

</template>
Yair Cohen
  • 2,032
  • 7
  • 13
0

You can bind with array index, do not need upload method

new Vue({
      el: '#app',
      data() {
        return {
          title: "Vue app",
          lists:[{text: '', filename: '',}]
        };
      },
      methods:{
      addItem() {
            this.lists.push({ text: '', filename: '' })
        }
      }
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app"><h2>{{title}}</h2>
     <div v-for="(list,i) in lists">

        <input type="text" v-model="lists[i].text" >
        
        <input type="file" v-model="lists[i].filename">

    </div>
    
    <button @click="addItem">Add Item</button>
    <pre>{{lists}}</pre>
    </div>
Nilesh Patel
  • 3,193
  • 6
  • 12
0

You can do it like this:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<input id='inputfile' type='file' name='inputfile' onChange='getoutput()'>

new Vue({
    el: '#app',
    data() {
        return {
            title: "Vue app",
            lists:[{text: '', filename: '',}]
        };
    },
    methods:{
        addItem() {
            this.lists.push({ text: '', filename: '' })
        },
        getFile(filePath) {
            return filePath.substr(filePath.lastIndexOf('\\') + 1).split('.')[0];
        },
        getoutput(e, index) {
            let fileName = this.getFile(e.target.value);
            let fileExtention = e.target.value.split('.')[1];
            this.lists[index].filename = `${fileName}.${fileExtention}`;
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app"><h2>{{title}}</h2>
     <div v-for="(list,i) in lists">

        <input type="text" v-model="lists[i].text" >
        
        <input type="file" @change="getoutput($event, i)">

    </div>
    
    <button @click="addItem">Add Item</button>
    <pre>{{lists}}</pre>
    </div>