DEV Community

Alan Schio
Alan Schio

Posted on • Edited on

9

Vue and Input File - Clear File or Select same file

Have you ever had the case where ou have a file selector component, you clear the file model but then you can't select the same file again?

File selection

Codepen: https://codepen.io/schirrel/pen/YzRGrvq

Well its kinda hard and curious to explain.
First of all to the TL/DR:
You need to use Vue's $refs and set the input to null.

Now if you want to understand why, let's pass thru some important stuff:

First: Vue doesn't work with v-model and file input, even has a discussion about it on the offical Vue's repo: Discussion.

Now lets undestand why doesnt work, two main things:

  1. input with type="file" only triggers change event, while v-model listen to input event.
  2. v-model needs to set the value html attribute, if you ever try to do :value="myFileModel" this error will show up:

Error in nextTick: "InvalidStateError: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

So with this comes a question: how to a clear a file, and most important, how make it possible to select again?

Lets paint a simple use case: You have your own file wrapper the uses a file input (obviously) but you save the file on the data. Example:

<template>
 <label for="inputFile">
      Click here to select you file
      <input type="file" name="inputFile" id="inputFile" @change="selectFile" />
    </label>
    <span v-if="file">
      File Selected {{ file.name }}
      <button @click="clearFile">remove</button>
    </span>
</template>
<script>
export default {
  data() {
    return {
      file: null
    };
  },
  methods: {
    selectFile(event) {
      this.file = event.target.files[0];
    },
    clearFile() {
      this.file = null;
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Even if clearFile is setting file as null, when selecting the file again the @change wont be triggered again. Thats why because the html value attribute still the same, the file prop on data doesn't affect it. Take a look at the codepen example.

Once we have seen that :value don't work with files, the proper way to do this is acessing the HTML <input type="file" /> and reset this value programmatically.

By adding a ref="fileInput" to the <input> and inside the clearFile method add:

this.$refs.fileInput.value = null
Enter fullscreen mode Exit fullscreen mode

Now it works:

Vue select same file

The codepen final solution: https://codepen.io/schirrel/pen/XWyjeOw

Note: this is common behavior across frameworks;

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (1)

Collapse
 
gabrielaschlemper profile image
Gabriela Schlemper

thanks for that!

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay