Skip to main content

How to Make the File Input 'change' Event Fire for the Same File in JavaScript

A common and frustrating issue when working with <input type="file"> is that the change event will not fire if the user selects the same file multiple times in a row. The event only triggers the first time, leading to unresponsive UI and confused users.

This guide will explain why this happens and teach you the simple, standard solution to ensure the change event fires every single time the user selects a file, even if it's the same one.

The Core Problem: Why the change Event Doesn't Fire

The change event is designed to fire only when the value of an input element changes.

  • When the user selects a file for the first time, the input's value changes from empty ('') to the file's path, so the change event fires.
  • If the user immediately opens the file dialog again and selects the exact same file, the input's value does not change—it's the same file path as before. Because there is no change, the browser does not dispatch the change event.

The most robust and common solution is to programmatically reset the input's value to null or an empty string at the end of your change event handler. This ensures that the next time the user selects a file, its value will always be different from the now-empty state.

For example, this code works only the first time a specific file is selected.

<input type="file" id="file-input" />
const fileInput = document.getElementById('file-input');

fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;

console.log(`Selected file: ${file.name}`);
// The value is now set to the file's path.
// If the user selects this same file again, the value won't change.
});

We can fix the problem by adding one line to the end of the handler.

const fileInput = document.getElementById('file-input');

fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;

console.log(`Selected file: ${file.name}`);

// Your file handling logic goes here...
// For example, uploadFile(file);

// THIS IS THE FIX:
// Reset the input's value so the change event will fire again.
event.target.value = null;
});
note

This is the recommended best practice because it keeps all the related logic within a single event handler, making the code self-contained and easy to understand. Using event.target is also a good practice as it refers directly to the element that triggered the event.

An Alternative Method: Resetting the Value on click

An alternative approach is to reset the input's value every time the user clicks on it, which happens just before they open the file selection dialog.

This solution uses two separate event listeners.

const fileInput = document.getElementById('file-input');

// Main handler for when a file is selected
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;
console.log(`Selected file: ${file.name}`);
// (Your file handling logic here)
});

// Helper handler to reset the value on every click
fileInput.addEventListener('click', (event) => {
// This resets the value before the file dialog opens.
event.target.value = null;
});
note

This solution also works perfectly but separates the reset logic from the handling logic. While some developers may prefer this separation, the single-handler approach in the previous section is generally more common and intuitive.

Conclusion

The behavior of the file input's change event is intentional, but it often conflicts with the desired user experience.

  • The root cause of the issue is that the event only fires when the input's value changes.
  • The definitive solution is to programmatically reset the input's value after each selection.
  • The recommended best practice is to set event.target.value = null at the end of your change event handler, which makes your code clean, self-contained, and reliable.