HTML input file selection event not firing upon selecting the same file
Asked Answered
E

11

341

Is there any chance to detect every file selection the user made for an HTML input of type file element?

This was asked many times before, but the usually proposed onchange event doesn't fire if the user select the same file again.

Expiratory answered 19/8, 2012 at 23:6 Comment(7)
Would your code then also have to fire if the user hits Cancel then? One expects that hitting Cancel will do nothing, and I think most users would further expect that re-selecting the same file would have the same effect as Cancel. I don't know if this is possible or not but I suggest you reconsider this design anyway.Livelong
On cancel it should not fire or make it otherwise detectable. It is more meant to remove an UI ceveat: If some action is invoked after the file is choosen, the user usually expect the action to repeat if he choose the file again.Expiratory
Maybe we can have this behaviour if we set the inputs value to '' after doing something with the file. But that would remove the visible filename too. However, that may be ok, as the file is actually processed and the result of that action may appear somewhere else.Expiratory
Plz Explain the Que What you want to do?Transpose
related: Capturing the close of the open-file-dialog with JavaScriptIndigested
Have you tried the jquery trigger to fire it againBrainwashing
All I want is to simulate the old school behaviour desktop applications have. If I 'open' the same file again in an desktop application, it is usually reloaded, or if some action is done with the file (like converting it so another format for example) this action is done again. This is what desktop users may expect from a web app too, but the file input onchange event doesn't resemble.Expiratory
E
433

Set the value of the input to null on each onclick event. This will reset the input's value and trigger the onchange event even if the same path is selected.

var input = document.getElementsByTagName('input')[0];

input.onclick = function () {
  this.value = null;
};
  
input.onchange = function () {
  console.log(this.value);
};
<input type="file" value="C:\fakepath">

Note: It's normal if your file is prefixed with 'C:\fakepath'. That's a security feature preventing JavaScript from knowing the file's absolute path. The browser still knows it internally.

Emulsion answered 24/8, 2012 at 4:4 Comment(10)
I tried the demo, but (using Chrome 21) I keep getting `C:\fakepath` + then the filename I selected (excluding the path). The alert is show on every select of the same file though.Fay
@JasperdeVries That's a security feature preventing JavaScript from knowing a file's absolute path. The browser still knows the path internally.Emulsion
As an aside, null is the only permitted value for <input type="file">. So if you're trying to set it to undefined and getting an exception then that's the reason why.Abrogate
It doesn't work well in IE11 unless you make a small change: demo.Boarding
It's better to put this.value = null at the end of the onchange because it's possible to active an input element without clicking on it (by using the keyboard). You can store input.files if you need to reference it later.Dickie
Setting this.value == null worked for me. The change event was being triggered when I click the input button but without selecting a file. Thanks!Kandace
Worked for me too. I needed to do the same thing in Vue JS.Carom
The problem with this approach is that if you then cancel the file selection, the file you previously had selected will now have been lost.Margaretamargarete
The value should be set to an empty string since the type of this.value is a string. setting it to null will result in a Typescript error. I also agree with @Dickie this cleanup should be handled in the onChange event.Wineskin
I had a similar problem in Blazor's <InputFile> component. When opening the file selection dialog and NOT choosing any file, none of OnChange, onchange or oninput events were firing. On the standard HTML <input type="file"..> however these (onchange and oninput) fired regardless of whether I selected a file or not. I employed OnClick(which was firing every time of course) and reset my "value" variable. Problem solved. Thanx!Leatherback
M
54

Use onClick event to clear value of target input, each time user clicks on field. This ensures that the onChange event will be triggered for the same file as well. Worked for me :)

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

Using TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}
Ministry answered 11/2, 2019 at 14:45 Comment(0)
U
28
<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); this.value=null; return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

this.value=null; is only necessary for Chrome, Firefox will work fine just with return false;

Here is a FIDDLE

Uneducated answered 20/9, 2014 at 12:52 Comment(1)
simple and effective just tested in latest IE and chrome and works like a charm. Thanks for sharing itSheila
M
11
handleChange({target}) {
    const files = target.files
    target.value = ''
}
Meade answered 27/3, 2020 at 13:23 Comment(3)
Hey ngCourse ! Code-only answers may solve the problem but they are much more useful if you explain how they solve it. Community requires theory as well as code both to understand your answer fully.Simulation
While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. From ReviewFalbala
Yes, This worked. But as @Falbala said, you should explain the answer. And thanks btwCornet
A
10

In this article, under the title "Using form input for selecting"

http://www.html5rocks.com/en/tutorials/file/dndfiles/

<input type="file" id="files" name="files[]" multiple />

<script>
function handleFileSelect(evt) {

    var files = evt.target.files; // FileList object

    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
     // Code to execute for every file selected
    }
    // Code to execute after that

}

document.getElementById('files').addEventListener('change', 
                                                  handleFileSelect, 
                                                  false);
</script>

It adds an event listener to 'change', but I tested it and it triggers even if you choose the same file and not if you cancel.

Allseed answered 24/8, 2012 at 3:4 Comment(2)
Considering the potentially ambiguous meaning of "change" in this case, did you try this in multiple browsers? You may want to specify which ones you tried it on as on the web, browsers aren't exactly always in consensus about these things.Polypus
What environment you use for your test? My experience with Chrome was the one I stated in the question, the change event would fire only on filename changes.Expiratory
K
3

The selected answer (using state to set input value null) gave me an error.

I use empty strings instead

    const [fileValue, setFileValue] = React.useState("")

    <input
        onClick={() => {
           setFileValue("");
        }}
        type="file"
        value={fileValue}
        onChange={handleAddFile}
    />


Katabatic answered 8/7, 2022 at 18:5 Comment(0)
Z
2

Usage of two way binding worked for me if you are working with Angular.

Here is my HMTL

<input type="file" #upload name="upload" [(ngModel)]="inputValue"(change)='fileEvent($event)'/>

and TS..

  @ViewChild('upload') uploadBtn: HTMLElement;

  fileEvent(e: any){
    
   //file upload part... 

    this.inputValue = "";
  }
Zebe answered 26/4, 2021 at 9:14 Comment(2)
I guess there are many frameworks (like angular) that would make this working out of the box. But the question was meant for vanilla JS.Expiratory
it is also an issue in Angular, hence ibrahim's solution. Thanks Ibrahim.Duplicity
P
2
<input #myInput type="file" id="imgFile" (click)="$event.target.value=null"
       (change)="detectUploadedImage($event)" accept="image/*" />
Probative answered 22/7, 2021 at 6:42 Comment(0)
K
1

Clearing the value of 0th index of input worked for me. Please try the below code, hope this will work (AngularJs).

          scope.onClick = function() {
            input[0].value = "";
                input.click();
            };
Kayekayla answered 19/6, 2020 at 9:21 Comment(0)
R
0

Do whatever you want to do after the file loads successfully.just after the completion of your file processing set the value of file control to blank string.so the .change() will always be called even the file name changes or not. like for example you can do this thing and worked for me like charm

   $('#myFile').change(function () {
       LoadFile("myFile");//function to do processing of file.
       $('#myFile').val('');// set the value to empty of myfile control.
    });
Rosanarosane answered 7/8, 2018 at 13:4 Comment(0)
A
0

I can't use javascript in the project i'm working on.

Simply used:

<input type="file" onclick="this.value = null;" ..>
Annates answered 20/5, 2023 at 10:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.