182

Let's say we have this code:

<form action='' method='POST' enctype='multipart/form-data'>
    <input type='file' name='userFile'><br>
    <input type='submit' name='upload_btn' value='upload'>
</form>

which results in this:

image showing browse and upload button

When the user clicks the 'Browse...' button, a file search dialog box is opened:

image showing a file search dialog box with a file selected

The user will select the file either by double-clicking the file or by clicking the 'Open' button .

Is there a Javascript Event that I can use to be notified after the file is selected?

Riza Khan
  • 2,712
  • 4
  • 18
  • 42
Moon
  • 19,518
  • 56
  • 138
  • 200

6 Answers6

232

Listen to the change event.

 document.getElementById('input').addEventListener('change', function(e) {
  if (e.target.files[0]) {
    document.body.append('You selected ' + e.target.files[0].name);
  }
});
<input type="file" id="input">
Tofandel
  • 3,006
  • 1
  • 29
  • 48
Anurag
  • 140,337
  • 36
  • 221
  • 257
  • 3
    we gonna write it where.. in javascript script tags – Moon Aug 20 '10 at 05:34
  • 5
    yes in script tags, or you could add it as an attribute (``) although this is not recommended. – Anurag Aug 20 '10 at 05:52
  • 7
    Note that in IE7 and 8 that the 'change' event doesn't bubble up to the form event. You need to put your listener on the tag. – xer0x Jul 20 '11 at 18:07
  • 61
    What about if a user needs to "reload" a file? onchange will not trigger, but it should still reload as if it was loading it for the first time. – bryc Jan 09 '15 at 01:27
  • 23
    Note, this doesn't work if the user picks the same file more than once in a row since the file didn't change. – bob0the0mighty Oct 26 '16 at 15:21
  • 6
    Make sure to empty out the value after onchange event is handled, otherwise onchange wont get triggered next time if the user decides to choose different file after the initial selection – webjockey Jan 18 '17 at 05:03
  • 1
    @Anurag , I want to identify when a file is successfully uploaded, is there any way to find that out? onChange gets triggered if any file is selected to be uploaded. – Dip686 Aug 07 '20 at 05:39
  • If you also want it to trigger on cancel or the same file, you should listen to the `input` event instead of the `change` event – Tofandel Feb 01 '23 at 10:03
60

When you have to reload the file, you can erase the value of input. Next time you add a file, 'on change' event will trigger.

document.getElementById('my_input').value = null;
// ^ that just erase the file path but do the trick
jgillich
  • 71,459
  • 6
  • 57
  • 85
Clem
  • 2,150
  • 15
  • 17
  • 5
    That works fine but be aware of weird IE <11 behavior. It doesn't allow you to change input's value, so most likely you will need a workaround. http://stackoverflow.com/questions/9011644/how-to-reset-clear-file-input – Oleksandr Tkalenko Mar 13 '16 at 21:53
20

jQuery way:

$('input[name=myInputName]').change(function(ev) {

    // your code
});
Zanon
  • 29,231
  • 20
  • 113
  • 126
13

That's the way I did it with pure JS:

var files = document.getElementById('filePoster');
var submit = document.getElementById('submitFiles');
var warning = document.getElementById('warning');
files.addEventListener("change", function () {
  if (files.files.length > 10) {
    submit.disabled = true;
    warning.classList += "warn"
    return;
  }
  warning.classList -= "warn";
  submit.disabled = false;
});
#warning {
    text-align: center;
    transition: 1s all;
}

#warning.warn {
    color: red;
    transform: scale(1.5);
}
<section id="shortcode-5" class="shortcode-5 pb-50">
    <p id="warning">Please do not upload more than 10 images at once.</p>
    <form class="imagePoster" enctype="multipart/form-data" action="/gallery/imagePoster" method="post">
        <div class="input-group">
    <input id="filePoster" type="file" class="form-control" name="photo" required="required" multiple="multiple" />
        <button id="submitFiles" class="btn btn-primary" type="submit" name="button">Submit</button>
        </div>
    </form>
</section>
RegarBoy
  • 3,228
  • 1
  • 23
  • 44
6

The Change event gets called even if you click on cancel..

anthony
  • 61
  • 1
  • 1
  • 2
    it would help if you would provide some code to explain your answer, since there is no change event mentioned in the Questions code snippet – DevDig Jan 26 '17 at 15:42
  • I think @anthony is referring to the following scenario: Select a file. Now open the file selector again, but this time click on Cancel. Since no file was selected the second time, the file input control resets, thus changing its initial selection, and the change event is fired. – dvlsc Sep 16 '19 at 08:43
  • I tried it on Chrome 83 and the event doesn't get fired when I click on the Cancel button. This answer is pretty old and I guess it must've been fixed, at least on Chrome. – Saeed Ahadian Jul 11 '20 at 17:53
5

Though it is an old question, it is still a valid one.

Expected behavior:

  • Show selected file name after upload.
  • Do not do anything if the user clicks Cancel.
  • Show the file name even when the user selects the same file.

Code with a demonstration:

<!DOCTYPE html>
<html>

<head>
  <title>File upload event</title>
</head>

<body>
  <form action="" method="POST" enctype="multipart/form-data">
    <input type="file" name="userFile" id="userFile"><br>
    <input type="submit" name="upload_btn" value="upload">
  </form>
  <script type="text/javascript">
    document.getElementById("userFile").onchange = function(e) {
      alert(this.value);
      this.value = null;
    }
  </script>
</body>

</html>

Explanation:

  • The onchange event handler is used to handle any change in file selection event.
  • The onchange event is triggered only when the value of an element is changed. So, when we select the same file using the input field the event will not be triggered. To overcome this, I set this.value = null; at the end of the onchange event function. It sets the file path of the selected file to null. Thus, the onchange event is triggered even at the time of the same file selection.
arshovon
  • 13,270
  • 9
  • 51
  • 69