VueJS - repeating input fields for file uploads

I need help removing duplicate items from an array in JavaScript, but when I try to delete one, it always deletes the last occurrence! https://i.sstatic.net/NeJRJ.jpg

let app = new Vue({
  el: '#app',
  data: {
    items: []
  },
  methods: {
    addItem() {
      this.items.push('');
    },
    removeItem(index) {
      this.items.splice(index, 1);
    }
  }
});
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3543405075071b041b0405">[email protected]</a>/dist/vue.js"></script>
<div id="app">
  <ul class="list-group">
    <li class="list-group-item" v-for="(item , index) in items">
      <a href="#" v-on:click.prevent="removeItem(index)">remove</a>
      <input name="form[]" type='file'>
    </li>
  </ul>
  <button @click='addItem'>new item</button>
</div>

Check out my JSFiddle for more details: https://jsfiddle.net/6hvbqju2/

Answer №1

Vue takes on an "in-place patch strategy" when managing lists of elements, which may not work well with form input values.

It's advisable to specify a v-bind:key when using the v-for directive to help Vue track each individual node effectively.

We will be storing numbers in the items array and utilizing them as keys. In your scenario, it would be best to use a property of the item that can function as a unique key.

let app = new Vue({
  el: '#app',
  data: {
    counter: 0,
    items: []
  },
  methods: {
    addItem() {
      this.items.push(this.counter++);
    },
    removeItem(index) {
      this.items.splice(index, 1);
    }
  }
});
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d4a2a1b194e6fae5fae5e4">[email protected]</a>/dist/vue.js"></script>
<div id="app">

  <ul class="list-group">
    <li class="list-group-item" v-for="(item , index) in items" :key="item">
      <a href="#" v-on:click.prevent="removeItem(index)">remove</a>
      <input name="form[]" type='file'>

    </li>
  </ul>
  <button @click='addItem'>new item</button>


</div>

Answer №2

Your code is functioning properly, but there is an issue with the file input autocomplete behavior.

Take a look at this example:

let app = new Vue({
  el : '#app',
  data : {
    items: [],
  },
  methods : {
    addItem() {
      this.items.push({file: null});
      console.log(this.items)
    },
    removeItem(index) {
      this.items.splice(index,1);
    },
    handleChange(item, event){
      item.file = event.target.files["0"];
    }
  }
});
.upload-btn-wrapper {
  position: relative;
  overflow: hidden;
  display: inline-block;
  vertical-align: middle;
}
.btn {
  border: 1px solid gray;
  color: gray;
  background-color: white;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 15px;
  font-weight: bold;
}
.upload-btn-wrapper input[type=file] {
  font-size: 100px;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
}
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5b2d2e3e1b69756a756a6b">[email protected]</a>/dist/vue.js"></script>

<div id="app">
  <ul class="list-group">
    <li class="list-group-item" v-for="(item , index) in items">
      <a href="#" v-on:click.prevent="removeItem(index)">remove</a>
      <div type="button" class="upload-btn-wrapper">
        <button class="btn">{{ item.file ? item.file.name : 'Choose File' }}</button>
        <input name="form[]" type="file" @change="handleChange(item, $event)">
      </div>
    </li>
  </ul>
  <button @click='addItem'>new item</button>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ensure that Colorbox remains centrally positioned even while scrolling

I have noticed a difference in behavior between thickbox and colorbox when it comes to scrolling. Thickbox always stays centered on the screen even when the user scrolls vertically, while colorbox fades out and leaves just a grayed background. Is there a w ...

Set up a single array containing multiple objects in a table, each with its own unique set of keys

I am currently developing an application that retrieves data from one or multiple databases, each with different names and varying numbers of columns. The goal is to consolidate this data into a single report screen and export it as a table. While the tabl ...

JavaScript application throwing error: "require is not defined"

Currently, I am working on storing an array in a .json file using NodeJS. However, when trying to execute the code below, I encountered an error message saying require is not defined. Can someone provide some guidance on how to resolve this issue? let ans ...

Error: The property 'case sensitive routing' cannot be accessed because it is undefined

Task at hand: Running ExpressJS port using Node.js, nodemon, and lib. Operating System: Windows 10 Home x64 Node.JS Version: Lts The Challenge: Getting the ExpressJS port to run successfully. Current Issue: Encountering an internal file error, potentiall ...

Utilizing Three.js to Upload Images and Apply Them as Textures

While attempting to upload an image via URL and set it as a texture, I encountered an issue. The error message THREE.WebGLState: DOMException: Failed to execute 'texImage2D' on 'WebGLRenderingContext': Tainted canvases may not be loaded ...

What is the best way to define the scope of an HTTP request within my application?

I need assistance with setting the scope for an http request in my Ionic App. Our Backend is built with Node.JS using the Hapi Framework. Since I primarily work on the frontend, I lack knowledge of server-side operations. Currently, I am able to successfu ...

Accessing the statusText of a 403 response in Axios (React, Express, Node.js)

Within my component, there is a register function that makes an API call. The API checks if the email already exists and provides an appropriate status and statusText based on the result. Below is the API call handler in my Express app: router.post(' ...

The Vuex store was initialized in main.js, however, it seems to be undefined when accessed in App

index.js: import Vue from "vue"; import Axios from "axios"; import App from "./App.vue"; import router from "./router"; import store from "./store"; const axios = Axios.create({ baseURL: process.env.VUE_APP_BASE_URL }) Vue.prototype.$http = axios; n ...

Fetching from the same origin results in a null comparison issue due to HTTP CORS restrictions

Encountering an issue where a simple same-origin fetch("fetch.xml") call fails, resulting in a console error message Access to fetch at 'http://127.0.0.1:8000/fetch.xml' from origin 'null' has been blocked by CORS policy: Th ...

Converting a class-based component into a functional component

TL;DR : I am in the process of converting my class-based App component to a Functional component but encountering unexpected outcomes with the useEffect Hook. Being relatively new to React, I originally built my movie search app using a class-based approa ...

JavaScript - undefined results when trying to map an array of objects

In the process of passing an object from a function containing an array named arrCombined, I encountered a challenge with converting strings into integers. The goal is to map and remove these strings from an object titled results so they can be converted i ...

Utilizing jQuery to Trigger a JavaScript Function in a Separate File

Here is my question: I currently have 2 files: //File1.js function TaskA() { //do something here } //File2.js function TaskB() { //do something here } $(function() { TaskA(); }); The issue I am facing is that the TaskB function in File2.js ...

Issues arise when the Angular controller fails to load

I'm experiencing an issue with my Angular controller where the code inside its constructor is not running. Here's a snippet of the relevant pieces: conversationcontrollers.js: var exampleApp = angular.module('exampleApp',[]); console ...

Using React Native to implement Firebase onSnapshot with FlatList pagination

INTRODUCTION I have a collection of items stored in FireStore with the "date" property. On the client side, I'm using a FlatList to display these items ordered by date, starting with the most recent item at the top. The challenge I'm facing is ...

Is it possible to load the response from the $.post function, which contains GIF content, into a JavaScript Image object

How can I preload an image that the server only returns on a POST request? I want to load the image before displaying it. How can I store the result in a JavaScript object? $.post('image.php', {params: complexParamsObject}, function(result) { ...

Unable to invoke the setState function within the onSubmit handler of Formik

Every time I submit my form, I want to display an alert. I attempted to pass my state as a prop to the component, but it didn't work. Here's how my class state looks: this.state = { alert_variant: '', alert_heading: ...

Encountering difficulties linking to a stylesheet or a script in an HTML file delivered by Express server

Currently, I'm facing the challenge of breaking down my Express app code into multiple files. Unfortunately, I am unable to utilize <link href> or <script src> for linking stylesheets or scripts. Below is the relevant snippet from my inde ...

What is the best way to connect an external JSON file to an Angular controller?

As I embark on my first Angular JS project, I find myself in need of exporting a JSON array from my controller to an external JSON file. Here is the snippet from my controller containing the JSON data: Fantacalcio.controller('fantacalcioController&ap ...

What is the best way to set up a task scheduler using node-cron in a Vue.js

Following the documentation in Node.js, each * symbol has a specific meaning. cron.schedule('* * * * *', () => { console.log('running a task every minute'); }); # ┌────────────── second (optional) # ...

What is the best way to merge javascript files and have them load after the page has already loaded on an asp.net site?

I recently came across a helpful SE Post that discussed combining external javascript files for better optimization, which is something I'm interested in. Following recommendations, I have converted internal javascripts into an external .js file and s ...