72

I want to reset a file upload field when the user selects another option.

Is this possible via JavaScript? I'm suspecting that the file upload element is treated differently because it interacts with the user's file system, and maybe it's immutable.

Basically, what I want is something like (pseudo-code):

// Choose selecting existing file
$('#select-file').bind('focus', function() {
  // Clear any files currently selected in #upload-file
  $('#upload-file').val(''); 
}) ;

// Choose uploading new one - this works ok
$('#upload-file').bind('focus', function() {
  // Clear any files currently selected in #select-file
  $('#select-file').val(''); 
}) ;

NB: This question and its answers span the period from 2009 to today. Browsers and approaches have changed in that time, please select your solutions with this in mind :)

1

18 Answers 18

90

You can't set the input value in most browsers, but what you can do is create a new element, copy the attributes from the old element, and swap the two.

Given a form like:

<form> 
    <input id="fileInput" name="fileInput" type="file" /> 
</form>

The straight DOM way:

function clearFileInput(id) 
{ 
    var oldInput = document.getElementById(id); 

    var newInput = document.createElement("input"); 

    newInput.type = "file"; 
    newInput.id = oldInput.id; 
    newInput.name = oldInput.name; 
    newInput.className = oldInput.className; 
    newInput.style.cssText = oldInput.style.cssText; 
    // TODO: copy any other relevant attributes 

    oldInput.parentNode.replaceChild(newInput, oldInput); 
}

clearFileInput("fileInput");

Simple DOM way. This may not work in older browsers that don't like file inputs:

oldInput.parentNode.replaceChild(oldInput.cloneNode(), oldInput);

The jQuery way:

$("#fileInput").replaceWith($("#fileInput").val('').clone(true));

// .val('') required for FF compatibility as per @nmit026

Resetting the whole form via jQuery: https://stackoverflow.com/a/13351234/1091947

8
  • I tried the other two suggested options above, and the sample code at this link was the one which worked best in the end. I really expected Udo's answer to do it, but it wasn't the go. I also tried gusiev.com/2009/04/clear-upload-file-input-field Thanks Chris H Commented Jun 16, 2009 at 12:28
  • This is the best I've found so far, but I still have issue with events attached to the field. Thanks, though!
    – William
    Commented Aug 26, 2011 at 15:11
  • 6
    Or with jQuery (inside the change event handler): $(this).replaceWith( $(this).clone(true) ); Commented Jan 22, 2013 at 22:46
  • You could also wrap it into a form and reset it with jQuery as described here: stackoverflow.com/a/13351234/1091947
    – Gigi2m02
    Commented Jan 3, 2015 at 5:14
  • 1
    $("#CV").replaceWith($("#CV").clone(true)); doesn't work in Firefox but does work in other desktop browsers (haven't tested Safari). $("#CV").replaceWith($("#CV").val('').clone(true)); seems to work everywhere.
    – nmit026
    Commented Jan 18, 2016 at 6:00
68

Simply now in 2014 the input element having an id supports the function val('').

For the input -

<input type="file" multiple="true" id="File1" name="choose-file" />

This js clears the input element -

$("#File1").val('');
2
  • 2
    Does this work in all browsers, or at least the past few versions of the big 4? I've seen some issues where it works in FF but not IE. Commented Jan 5, 2015 at 2:12
  • 1
    The accepted answer does not work for me, as I use Angular 2, and replacing the element doesn't seem to play nice with Angular. This solution however does work -- so it gets my upvote! Commented Feb 15, 2017 at 0:18
25

Simple solution:

document.getElementById("upload-files").value = "";
0
7

Yes, the upload element is protected from direct manipulation in different browsers. However, you could erase the element from the DOM tree and then insert a new one in its place via JavaScript. That would give you the same result.

Something along the lines of:

$('#container-element').html('<input id="upload-file" type="file"/>');
1
  • very nice - will give this a shot, should be v little hassle to run off a copy of the existing element Commented May 6, 2009 at 14:31
5

The code I ended up using was,

clearReviewFileSel: function() {
  var oldInput = document.getElementById('edit-file-upload-review-pdf') ;
  var newInput = document.createElement('input');
  newInput.id    = oldInput.id ;
  newInput.type  = oldInput.type ;
  newInput.name  = oldInput.name ;
  newInput.size  = oldInput.size ;
  newInput.class  = oldInput.class ;
  oldInput.parentNode.replaceChild(newInput, oldInput); 
}

Thanks everyone for the suggestions and pointers!

2
  • Thank you for posting the code! You saved me time and frustration tonight.
    – rf_circ
    Commented Dec 9, 2009 at 22:36
  • 1
    In IE8, "class" is not a valid attribute. It's "className".
    – rf_circ
    Commented Dec 11, 2009 at 15:32
5

Shorter version that works perfect for me that is as follow:

document.querySelector('#fileUpload').value = "";
4

They don't get focus events, so you'll have to use a trick like this: only way to clear it is to clear the entire form

<script type="text/javascript">
    $(function() {
        $("#wrapper").bind("mouseover", function() {
            $("form").get(0).reset();
        });
    });
</script>

<form>
<div id="wrapper">
    <input type=file value="" />
</div>
</form>
2
  • thanks - yes i had also wondered if there's even a UI method for the user to clear their own file upload field without resetting the entire form Commented May 6, 2009 at 14:32
  • @ChadGrant good point, thank you. What i did just wrap input with form, reseted form, and unwrap it:)
    – dmi3y
    Commented Dec 7, 2012 at 21:35
4

really like keep things simple like this :)

$('input[type=file]').wrap('<form></form>').parent().trigger('reset').children().unwrap('<form></form>');
3

This jQuery worked for me in IE11, Chrome 53, and Firefox 49:

cloned = $("#fileInput").clone(true);
cloned.val("");
$("#fileInput").replaceWith(cloned);
2

try this its work fine

document.getElementById('fileUpload').parentNode.innerHTML = document.getElementById('fileUpload').parentNode.innerHTML;
0
2

For compatibility when ajax is not available, set .val('') or it will resend the last ajax-uploaded file that is still present in the input. The following should properly clear the input whilst retaining .on() events:

var input = $("input[type='file']");
input.html(input.html()).val('');
2

If you have the following:

<input type="file" id="FileSelect">

then just do:

$("#FileSelect").val('');

to reset or clear last selected file.

1

Try this code...

$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile'   style='display:none'>"+$("#fileWrapper").html()+"   </div>");
$("#fileWrapper").html($("#duplicateFile").html());
1

jQuery tested method working fine in FF & Chrome:

$(function(){
    $.clearUploadField = function(idsel){
        $('#your-id input[name="'+idsel+'"]').val("") 
    }
});
1

I know the FormData api is not so friendly for older browsers and such, but in many cases you are anyways using it (and hopefully testing for support) so this will work fine!

function clearFile(form) {
  // make a copy of your form
  var formData = new FormData(form);
  // reset the form temporarily, your copy is safe!
  form.reset();
  for (var pair of formData.entries()) {
    // if it's not the file, 
    if (pair[0] != "uploadNameAttributeFromForm") {
      // refill form value
      form[pair[0]].value = pair[1];
    }
    
  }
  // make new copy for AJAX submission if you into that...
  formData = new FormData(form);
}

1

Just another one for the pot but you can actually change the type of an input. If you set the type to text, then back to file, it seems to reset the element.

var myFileInput = document.getElementById('myfileinput');
myFileInput.type = "text";
myFileInput.type = "file";

It resets. Tested in Google Chrome, Opera, Edge, IE 11

0

I faced the issue with ng2-file-upload for angular. if you are looking for the solution on angular by ng2-file-upload, refer below code

HTML:

<input type="file" name="myfile" #activeFrameinputFile ng2FileSelect [uploader]="frameUploader" (change)="frameUploader.uploadAll()" />

component

import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';

@ViewChild('activeFrameinputFile')InputFrameVariable: ElementRef;

this.frameUploader.onSuccessItem = (item, response, status, headers) => { this.InputFrameVariable.nativeElement.value = ''; };

0

I know it is quite old, but testing in the browser:

$0.value=null; // when $0 is the file upload element we talking about

erased the value and allow me to rechoose THE SAME FILE as before (means it worked!)

Tested in Chrome 81, FF 76, Safari (on iPad mini), 360 browser, Baidu browser, QQ browser, android browser.

Explanation:

As per my point of view that files selected can be more than 1, you'd better not set the value to a string - the final value sits in $0.files which may be more than 1. The browser need to parse the selected values from "value", so it is an active property. Set it to null, as per my understanding, will cause the browser to parse it to [] empty list in $0.files (this is what happened...)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.