Is it possible to clear an <input type='file' /> control value with jQuery? I've tried the following:
$('#control').attr({ value: '' });
But it's not working.
Easy: you wrap a <form> around the element, call reset on the form, then remove the form using .unwrap(). Unlike the .clone() solutions otherwise in this thread, you end up with the same element at the end (including custom properties that were set on it).
Tested and working in Opera, Firefox, Safari, Chrome and IE6+. Also works on other types of form elements, with the exception of type="hidden".
window.reset = function(e) {
e.wrap('<form>').closest('form').get(0).reset();
e.unwrap();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input id="file" type="file">
<br>
<input id="text" type="text" value="Original">
</form>
<button onclick="reset($('#file'))">Reset file</button>
<button onclick="reset($('#text'))">Reset text</button>
JSFiddle
As Timo notes below, if you have the buttons to trigger the reset of the field inside of the <form>, you must call .preventDefault() on the event to prevent the <button> from triggering a submit.
EDIT
Does not work in IE 11 due to an unfixed bug. The text (file name) is cleared on the input, but its File list remains populated.
Quick answer: replace it.
In the code below I use the replaceWith jQuery method to replace the control with a clone of itself. In the event you have any handlers bound to events on this control, we'll want to preserve those as well. To do this we pass in true as the first parameter of the clone method.
<input type="file" id="control"/>
<button id="clear">Clear</button>
var control = $("#control");
$("#clear").on("click", function () {
control.replaceWith( control = control.clone( true ) );
});
Fiddle: http://jsfiddle.net/jonathansampson/dAQVM/
If cloning, while preserving event handlers, presents any issues you could consider using event delegation to handle clicks on this control from a parent element:
$("form").on("focus", "#control", doStuff);
This prevents the need for any handlers to be cloned along with the element when the control is being refreshed.
Jquery is supposed to take care of the cross-browser/older browser issues for you.
This works on modern browsers that I tested: Chromium v25, Firefox v20, Opera v12.14
Using jquery 1.9.1
HTML
<input id="fileopen" type="file" value="" />
<button id="clear">Clear</button>
Jquery
$("#clear").click(function () {
$("#fileopen").val("");
});
On jsfiddle
The following javascript solution also worked for me on the browsers mention above.
document.getElementById("clear").addEventListener("click", function () {
document.getElementById("fileopen").value = "";
}, false);
On jsfiddle
I have no way to test with IE, but theoretically this should work. If IE is different enough that the Javascript version does not work because MS have done it in a different way, the jquery method should in my opinion deal with it for you, else it would be worth pointing it out to the jquery team along with the method that IE requires. (I see people saying "this won't work on IE", but no vanilla javascript to show how it does work on IE (supposedly a "security feature"?), perhaps report it as a bug to MS too (if they would count it as such), so that it gets fixed in any newer release)
Like mentioned in another answer, a post on the jquery forum
if ($.browser.msie) {
$('#file').replaceWith($('#file').clone());
} else {
$('#file').val('');
}
But jquery have now removed support for browser testing, jquery.browser.
This javascript solution also worked for me, it is the vanilla equivalent of the jquery.replaceWith method.
document.getElementById("clear").addEventListener("click", function () {
var fileopen = document.getElementById("fileopen"),
clone = fileopen.cloneNode(true);
fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
On jsfiddle
The important thing to note is that the cloneNode method does not preserve associated event handlers.
See this example.
document.getElementById("fileopen").addEventListener("change", function () {
alert("change");
}, false);
document.getElementById("clear").addEventListener("click", function () {
var fileopen = document.getElementById("fileopen"),
clone = fileopen.cloneNode(true);
fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
On jsfiddle
But jquery.clone offers this [*1]
$("#fileopen").change(function () {
alert("change");
});
$("#clear").click(function () {
var fileopen = $("#fileopen"),
clone = fileopen.clone(true);
fileopen.replaceWith(clone);
});
On jsfiddle
[*1] jquery is able to do this if the events were added by jquery's methods as it keeps a copy in jquery.data, it does not work otherwise, so it's a bit of a cheat/work-around and means things are not compatible between different methods or libraries.
document.getElementById("fileopen").addEventListener("change", function () {
alert("change");
}, false);
$("#clear").click(function () {
var fileopen = $("#fileopen"),
clone = fileopen.clone(true);
fileopen.replaceWith(clone);
});
On jsfiddle
You can not get the attached event handler direct from the element itself.
Here is the general principle in vanilla javascript, this is how jquery an all other libraries do it (roughly).
(function () {
var listeners = [];
function getListeners(node) {
var length = listeners.length,
i = 0,
result = [],
listener;
while (i < length) {
listener = listeners[i];
if (listener.node === node) {
result.push(listener);
}
i += 1;
}
return result;
}
function addEventListener(node, type, handler) {
listeners.push({
"node": node,
"type": type,
"handler": handler
});
node.addEventListener(type, handler, false);
}
function cloneNode(node, deep, withEvents) {
var clone = node.cloneNode(deep),
attached,
length,
evt,
i = 0;
if (withEvents) {
attached = getListeners(node);
if (attached) {
length = attached.length;
while (i < length) {
evt = attached[i];
addEventListener(clone, evt.type, evt.handler);
i += 1;
}
}
}
return clone;
}
addEventListener(document.getElementById("fileopen"), "change", function () {
alert("change");
});
addEventListener(document.getElementById("clear"), "click", function () {
var fileopen = document.getElementById("fileopen"),
clone = cloneNode(fileopen, true, true);
fileopen.parentNode.replaceChild(clone, fileopen);
});
}());
On jsfiddle
Of course jquery and other libraries have all the other support methods required for maintaining such a list, this is just a demonstration.
For obvious security reasons you can't set the value of a file input, even to an empty string.
All you have to do is reset the form where the field or if you only want to reset the file input of a form containing other fields, use this:
function reset_field (e) {
e.wrap('<form>').parent('form').trigger('reset');
e.unwrap();
}
Here is an exemple: http://jsfiddle.net/v2SZJ/1/
This works for me.
$("#file").replaceWith($("#file").clone());
http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie
Hope it helps.
In IE8 they made the File Upload field read-only for security. See the IE team blog post:
Historically, the HTML File Upload Control () has been the source of a significant number of information disclosure vulnerabilities. To resolve these issues, two changes were made to the behavior of the control.
To block attacks that rely on “stealing” keystrokes to surreptitiously trick the user into typing a local file path into the control, the File Path edit box is now read-only. The user must explicitly select a file for upload using the File Browse dialog.
Additionally, the “Include local directory path when uploading files” URLAction has been set to "Disable" for the Internet Zone. This change prevents leakage of potentially sensitive local file-system information to the Internet. For instance, rather than submitting the full path C:\users\ericlaw\documents\secret\image.png, Internet Explorer 8 will now submit only the filename image.png.
$("#control").val('') is all you need! Tested on Chrome using JQuery 1.11
Other users have tested in Firefox as well.
I got stuck with all the options here. Here's a hack that I made which worked:
<form>
<input type="file">
<button type="reset" id="file_reset" style="display:none">
</form>
and you can trigger the reset using jQuery with a code similar to this:
$('#file_reset').trigger('click');
(jsfiddle: http://jsfiddle.net/eCbd6/)
I ended up with this:
if($.browser.msie || $.browser.webkit){
// doesn't work with opera and FF
$(this).after($(this).clone(true)).remove();
}else{
this.setAttribute('type', 'text');
this.setAttribute('type', 'file');
}
may not be the most elegant solution, but it work as far as I can tell.
I have used https://github.com/malsup/form/blob/master/jquery.form.js, which has a function called clearInputs(), which is crossbrowser, well tested, easy to use and handles also IE issue and hidden fields clearing if needed. Maybe a little long solution to only clear file input, but if you are dealing with crossbrowser file uploads, then this solution is recommended.
The usage is easy:
// Clear all file fields:
$("input:file").clearInputs();
// Clear also hidden fields:
$("input:file").clearInputs(true);
// Clear specific fields:
$("#myfilefield1,#myfilefield2").clearInputs();
/**
* Clears the selected form elements.
*/
$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
return this.each(function() {
var t = this.type, tag = this.tagName.toLowerCase();
if (re.test(t) || tag == 'textarea') {
this.value = '';
}
else if (t == 'checkbox' || t == 'radio') {
this.checked = false;
}
else if (tag == 'select') {
this.selectedIndex = -1;
}
else if (t == "file") {
if (/MSIE/.test(navigator.userAgent)) {
$(this).replaceWith($(this).clone(true));
} else {
$(this).val('');
}
}
else if (includeHidden) {
// includeHidden can be the value true, or it can be a selector string
// indicating a special test; for example:
// $('#myForm').clearForm('.special:hidden')
// the above would clean hidden inputs that have the class of 'special'
if ( (includeHidden === true && /hidden/.test(t)) ||
(typeof includeHidden == 'string' && $(this).is(includeHidden)) )
this.value = '';
}
});
};
The value of file inputs is read only (for security reasons). You can't blank it programatically (other than by calling the reset() method of the form, which has a broader scope than just that field).
I was able to get mine working with the following code:
var input = $("#control");
input.replaceWith(input.val('').clone(true));
I have been looking for simple and clean way to clear HTML file input, the above answers are great, but none of them really answers what i'm looking for, until i came across on the web with simple an elegant way to do it :
var $input = $("#control");
$input.replaceWith($input.val('').clone(true));
all the credit go's to Chris Coyier.
// Referneces
var control = $("#control"),
clearBn = $("#clear");
// Setup the clear functionality
clearBn.on("click", function(){
control.replaceWith( control.val('').clone( true ) );
});
// Some bound handlers to preserve when cloning
control.on({
change: function(){ console.log( "Changed" ) },
focus: function(){ console.log( "Focus" ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="control">
<br><br>
Clear
The .clone() thing does not work in Opera (and possibly others). It keeps the content.
The closest method here for me was Jonathan's earlier, however ensuring that the field preserved its name, classes, etc made for messy code in my case.
Something like this might work well (thanks to Quentin too):
function clearInput($source) {
var $form = $('<form>')
var $targ = $source.clone().appendTo($form)
$form[0].reset()
$source.replaceWith($targ)
}
I have managed to get this to work using the following...
function resetFileElement(ele)
{
ele.val('');
ele.wrap('<form>').parent('form').trigger('reset');
ele.unwrap();
ele.prop('files')[0] = null;
ele.replaceWith(ele.clone());
}
This has been tested in IE10, FF, Chrome & Opera.
There are two caveats...
Still doesn't work properly in FF, if you refresh the page, the file element gets re-populated with the selected file. Where it is getting this info from is beyond me. What else related to a file input element could I possible try to clear?
Remember to use delegation on any events you had attached to the file input element, so they still work when the clone is made.
What I don't understand is who on earth thought not allowing you to clear an input field from an invalid unacceptable file selection was a good idea?
OK, don't let me dynamically set it with a value so I can't leach files from a user's OS, but let me clear an invalid selection without resetting an entire form.
It's not like 'accept' does anything other than a filter anyhow and in IE10, it doesn't even understand MS Word mime types, it's a joke!
On my Firefox 40.0.3 only work with this
$('input[type=file]').val('');
$('input[type=file]').replaceWith($('input[type=file]').clone(true));
its works for me in every browser.
var input = $(this);
var next = this.nextSibling;
var parent = input.parent();
var form = $("<form></form>");
form.append(input);
form[0].reset();
if (next) {
$(next).before(input);
} else {
parent.append(input);
}
I tried with the most of the techniques the users mentioned, but none of they worked in all browsers. i.e: clone() doesn't work in FF for file inputs.
I ended up copying manually the file input, and then replacing the original with the copied one. It works in all browsers.
<input type="file" id="fileID" class="aClass" name="aName"/>
var $fileInput=$("#fileID");
var $fileCopy=$("<input type='file' class='"+$fileInput.attr("class")+" id='fileID' name='"+$fileInput.attr("name")+"'/>");
$fileInput.replaceWith($fileCopy);
$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile' style='display:none'>"+$("#fileWrapper").html()+"</div>");
$("#fileWrapper").html($("#duplicateFile").html());
This works with Chrome, FF, and Safari
$("#control").val("")
May not work with IE or Opera
Make it asynchronous, and reset it after the button's desired actions have been done.
<!-- Html Markup --->
<input id="btn" type="file" value="Button" onchange="function()" />
<script>
//Function
function function(e) {
//input your coding here
//Reset
var controlInput = $("#btn");
controlInput.replaceWith(controlInput = controlInput.val('').clone(true));
}
</script>
function clear() {
var input = document.createElement("input");
input.setAttribute('type', 'file');
input.setAttribute('value', '');
input.setAttribute('id', 'email_attach');
$('#email_attach').replaceWith( input.cloneNode() );
}
it does not work for me:
$('#Attachment').replaceWith($(this).clone());
or
$('#Attachment').replaceWith($('#Attachment').clone());
so in asp mvc I use razor features for replacing file input.
at first create a variable for input string with Id and Name and then use it for showing in page and replacing on reset button click:
#{
var attachmentInput = Html.TextBoxFor(c => c.Attachment, new { type = "file" });
}
#attachmentInput
<button type="button" onclick="$('##(Html.IdFor(p => p.Attachment))').replaceWith('#(attachmentInput)');">--</button>
An easy way is changing the input type and change it back again.
Something like this:
var input = $('#attachments');
input.prop('type', 'text');
input.prop('type', 'file')
You can replace it with its clone like so
var clone = $('#control').clone();
$('#control').replacewith(clone);
But this clones with its value too so you had better like so
var emtyValue = $('#control').val('');
var clone = emptyValue.clone();
$('#control').replacewith(clone);
It's easy lol (works in all browsers [except opera]):
$('input[type=file]').each(function(){
$(this).after($(this).clone(true)).remove();
});
JS Fiddle: http://jsfiddle.net/cw84x/1/
What?
In your validation function, just put
document.onlyform.upload.value="";
Assuming upload is the name:
<input type="file" name="upload" id="csv_doc"/>
I'm using JSP, not sure if that makes a difference...
Works for me, and I think it's way easier.
Related
I want to clear the file input in my form.
I know about setting the sources to the same method... But that method wont erase the selected file path.
Note: I would like to avoid having to reload the page, reset the form or perform an AJAX call.
Is this possible?
There's 3 ways to clear file input with javascript:
set value property to empty or null.
Works for IE11+ and other modern browsers.
Create an new file input element and replace the old one.
The disadvantage is you will lose event listeners and expando properties.
Reset the owner form via form.reset() method.
To avoid affecting other input elements in the same owner form, we can create an new empty form and append the file input element to this new form and reset it. This way works for all browsers.
I wrote a javascript function. demo: http://jsbin.com/muhipoye/1/
function clearInputFile(f){
if(f.value){
try{
f.value = ''; //for IE11, latest Chrome/Firefox/Opera...
}catch(err){ }
if(f.value){ //for IE5 ~ IE10
var form = document.createElement('form'),
parentNode = f.parentNode, ref = f.nextSibling;
form.appendChild(f);
form.reset();
parentNode.insertBefore(f,ref);
}
}
}
tl;dr: For modern browsers, just use
input.value = '' or input.value = null;
Old answer:
How about:
input.type = "text";
input.type = "file";
I still have to understand why this does not work with webkit.
Anyway, this works with IE9>, Firefox and Opera.
The situation with webkit is that I seem to be unable to change it back to file.
With IE8, the situation is that it throws a security exception.
Edit:
For webkit, Opera and firefox this works, though:
input.value = '';
(check the above answer with this proposal)
I'll see if I can find a nice cleaner way of doing this cross-browser without the need of the GC.
Edit2:
try{
inputs[i].value = '';
if(inputs[i].value){
inputs[i].type = "text";
inputs[i].type = "file";
}
}catch(e){}
Works with most browsers. Does not work with IE < 9, that's all.
Tested on firefox 20, chrome 24, opera 12, IE7, IE8, IE9, and IE10.
Setting the value to '' does not work in all browsers.
Instead try setting the value to null like so:
document.getElementById('your_input_id').value= null;
EDIT:
I get the very valid security reasons for not allowing JS to set the file input, however it does seem reasonable to provide a simple mechanism for clearing already selecting output. I tried using an empty string but it did not work in all browsers, NULL worked in all the browsers I tried (Opera, Chrome, FF, IE11+ and Safari).
EDIT:
Please note that setting to NULL works on all browsers while setting to an empty string did not.
Unfortunately none of the above answers appear to cover all the bases - at least not with my testing with vanilla javascript.
.value = null appears to work on FireFox, Chome, Opera and IE11 (but not IE8/9/10)
.cloneNode (and .clone() in jQuery) on FireFox appears to copy the .value over, therefore making the clone pointless.
So here is the vanilla javascript function I have written that works on FireFox (27 and 28), Chrome (33), IE (8, 9, 10, 11), Opera (17)... these are the only browsers currently available to me to test with.
function clearFileInput(ctrl) {
try {
ctrl.value = null;
} catch(ex) { }
if (ctrl.value) {
ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);
}
}
The ctrl parameter is the file input itself, so the function would be called as...
clearFileInput(document.getElementById("myFileInput"));
SOLUTION
The following code worked for me with jQuery. It works in every browser and allows to preserve events and custom properties.
var $el = $('#your-input-id');
$el.wrap('<form>').closest('form').get(0).reset();
$el.unwrap();
DEMO
See this jsFiddle for code and demonstration.
LINKS
Clearing <input type='file' /> using jQuery
How to reset file input with JavaScript
document.getElementById('your_input_id').value=''
Edit:
This one doesn't work in IE and opera, but seems to work for firefox, safari and chrome.
U need replace it with new file input.
Here is how it can be done with jQuery:
var inputFile = $('input[type=field]');
inputFile.wrap('<div />');
and use this line when you need to clear input field (on some event for example):
inputFile.parent().html( inputFile.parent().html() );
Here are my two cents, the input files are stored as array so here is how to null it
document.getElementById('selector').value = []
this return an empty array and works on all browsers
the input.value = null is a working method, however it will only trigger input's change event if called from an onclick event.
Solution to that would be calling that onchange handler manually whenever you need to reset the input.
function reset_input(input) {
$(input)[0].value = null;
input_change_handler();
}
function input_change_handler() {
// this happens when there's been a change in file selection
if ($(input)[0].files.length) {
// file(s) selected
} else {
// nothing is selected
}
}
$(input).on('change', input_change_handler);
That's actually quite easy.
document.querySelector('#input-field').value = '';
I was having same problem and i came up with this.
var file = document.querySelector('input');
var emptyFile = document.createElement('input');
emptyFile.type = 'file';
document.querySelector('button').onclick = function(){
file.files = emptyFile.files;
}
<input type='file'>
<button>clear</button>
This worked for me.
const clear = (event) =>{event.target.value = [ ];}
clear("input_id");
I have been looking for simple and clean way to clear HTML file input, the above answers are great, but none of them really answers what i'm looking for, until i came across on the web with simple an elegant way to do it :
var $input = $("#control");
$input.replaceWith($input.val('').clone(true));
all the credit goes to Chris Coyier.
// Referneces
var control = $("#control"),
clearBn = $("#clear");
// Setup the clear functionality
clearBn.on("click", function(){
control.replaceWith( control.val('').clone( true ) );
});
// Some bound handlers to preserve when cloning
control.on({
change: function(){ console.log( "Changed" ) },
focus: function(){ console.log( "Focus" ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="control">
<br><br>
Clear
An - in my world easy an clean solution - is, to set the file inputs files to a clear FileList.
EDIT: as SteJ told - this ist not working with Safari.
Since we can not create a FileList directly - I user DataTransfer as "hack"
#$input[0].files=new DataTransfer().files
or
file_input_node.files=new DataTransfer().files
Try this easy and it works
let input = elem.querySelector('input[type="file"]');
input.outerHTML=input.outerHTML;
this will reset the input
The above answers offer somewhat clumsy solutions for the following reasons:
I don't like having to wrap the input first and then getting the html, it is very involved and dirty.
Cross browser JS is handy and it seems that in this case there are too many unknowns to reliably use type switching (which, again, is a bit dirty) and setting value to ''
So I offer you my jQuery based solution:
$('#myinput').replaceWith($('#myinput').clone())
It does what it says, it replaces the input with a clone of itself. The clone won't have the file selected.
Advantages:
Simple and understandable code
No clumsy wrapping or type switching
Cross browser compatibility (correct me if I am wrong here)
Result:
Happy programmer
I changed to type text and back to type to file using setAttribute
'<input file-model="thefilePic" style="width:95%;" type="file" name="file" id="filepicture" accept="image/jpeg" />'
'var input=document.querySelector('#filepicture');'
if(input != null)
{
input.setAttribute("type", "text");
input.setAttribute("type", "file");
}
What helped me is, I tried to fetch and upload the last selected file using a loop, instead of clearing out the queue, and it worked. Here is the code.
for (int i = 0; i <= Request.Files.Count-1; i++)
{
HttpPostedFileBase uploadfile = files[i];
Stream fs = uploadfile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] imageBytes = br.ReadBytes((Int32)fs.Length);
}
Hope this might help some.
Make the value null or empty string like this `` in order to clear value of a single input element
You can easily reset all form values using the HTML button using the <input type=”reset”> attribute.
The HTMLFormElement.reset() method restores a form element's default values. This method does the same thing as clicking the form's control.
To clear the entire input field without having to delete the whole thing manually Or what if there is already a pre-suggested input present in the input field, that the user doesn’t want. There could be many scenarios.
You can try this as a live example
const fileInputElement = document.getElementById('file-input');
const formElement = document.getElementById('input-form');
// Method-1: Clear files
// fileInputElement.value = '';
// Method-2: Clear files
// fileInputElement.value = null;
// Method-3: Clear files - on event listener
fileInputElement.addEventListener('change', (event)=>{
// If the file did not meet certain condition
event.target.value = '';
});
// Method-4: Clear or reset whole form
formElement.addEventListener('submit', (event)=>{
// If ajax call is failed to make request
event.target.reset();
// or
// formElement.reset()
});
.form{
display: flex;
flex-direction: column;
width: 80%;
margin-left: 10%;
}
#file-input, .form-control{
margin-top: 1rem;
}
.form-control{
padding: 1em 0;
}
#file-input{
background: #ccccff;
}
#file-input::-webkit-file-upload-button {
background: #000033;
color: white;
padding: 1em;
}
.button-group{
display: flex;
justify-content: start;
}
.btn{
background: #004d4d;
color: white;
width: 4rem !important;
margin-right: 10px;
}
<form id='input-form' class='form' >
<input type='file' id='file-input' />
<input type='text' class='form-control' id='text-input' placeholder='your name' />
<div class='button-group'>
<button type='reset' class='form-control btn' id='reset-form'>Reset</button>
<button type='submit' class='form-control btn' id='submit-form'>Submit</button>
</div>
</form>
I tried most of solutions but did not seem anyone to work. However I found a walk around for it below.
The structure of the form is: form => label, input and submit button. After we choose a file, the filename will be shown by the label by doing so manually in JavaScript.
So my strategy is: initially the submit button is disabled, after a file is chosen, the submit button disabled attribute will be removed such that I can submit file. After I submit, I clear the label which makes it look like I clear the file input but actually not. Then I will disable the submit button again to prevent from submitting the form.
By setting the submit button disable or not, I stop the file from submitted many times unless I choose another file.
I want to clear the file input in my form.
I know about setting the sources to the same method... But that method wont erase the selected file path.
Note: I would like to avoid having to reload the page, reset the form or perform an AJAX call.
Is this possible?
There's 3 ways to clear file input with javascript:
set value property to empty or null.
Works for IE11+ and other modern browsers.
Create an new file input element and replace the old one.
The disadvantage is you will lose event listeners and expando properties.
Reset the owner form via form.reset() method.
To avoid affecting other input elements in the same owner form, we can create an new empty form and append the file input element to this new form and reset it. This way works for all browsers.
I wrote a javascript function. demo: http://jsbin.com/muhipoye/1/
function clearInputFile(f){
if(f.value){
try{
f.value = ''; //for IE11, latest Chrome/Firefox/Opera...
}catch(err){ }
if(f.value){ //for IE5 ~ IE10
var form = document.createElement('form'),
parentNode = f.parentNode, ref = f.nextSibling;
form.appendChild(f);
form.reset();
parentNode.insertBefore(f,ref);
}
}
}
tl;dr: For modern browsers, just use
input.value = '' or input.value = null;
Old answer:
How about:
input.type = "text";
input.type = "file";
I still have to understand why this does not work with webkit.
Anyway, this works with IE9>, Firefox and Opera.
The situation with webkit is that I seem to be unable to change it back to file.
With IE8, the situation is that it throws a security exception.
Edit:
For webkit, Opera and firefox this works, though:
input.value = '';
(check the above answer with this proposal)
I'll see if I can find a nice cleaner way of doing this cross-browser without the need of the GC.
Edit2:
try{
inputs[i].value = '';
if(inputs[i].value){
inputs[i].type = "text";
inputs[i].type = "file";
}
}catch(e){}
Works with most browsers. Does not work with IE < 9, that's all.
Tested on firefox 20, chrome 24, opera 12, IE7, IE8, IE9, and IE10.
Setting the value to '' does not work in all browsers.
Instead try setting the value to null like so:
document.getElementById('your_input_id').value= null;
EDIT:
I get the very valid security reasons for not allowing JS to set the file input, however it does seem reasonable to provide a simple mechanism for clearing already selecting output. I tried using an empty string but it did not work in all browsers, NULL worked in all the browsers I tried (Opera, Chrome, FF, IE11+ and Safari).
EDIT:
Please note that setting to NULL works on all browsers while setting to an empty string did not.
Unfortunately none of the above answers appear to cover all the bases - at least not with my testing with vanilla javascript.
.value = null appears to work on FireFox, Chome, Opera and IE11 (but not IE8/9/10)
.cloneNode (and .clone() in jQuery) on FireFox appears to copy the .value over, therefore making the clone pointless.
So here is the vanilla javascript function I have written that works on FireFox (27 and 28), Chrome (33), IE (8, 9, 10, 11), Opera (17)... these are the only browsers currently available to me to test with.
function clearFileInput(ctrl) {
try {
ctrl.value = null;
} catch(ex) { }
if (ctrl.value) {
ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);
}
}
The ctrl parameter is the file input itself, so the function would be called as...
clearFileInput(document.getElementById("myFileInput"));
SOLUTION
The following code worked for me with jQuery. It works in every browser and allows to preserve events and custom properties.
var $el = $('#your-input-id');
$el.wrap('<form>').closest('form').get(0).reset();
$el.unwrap();
DEMO
See this jsFiddle for code and demonstration.
LINKS
Clearing <input type='file' /> using jQuery
How to reset file input with JavaScript
document.getElementById('your_input_id').value=''
Edit:
This one doesn't work in IE and opera, but seems to work for firefox, safari and chrome.
U need replace it with new file input.
Here is how it can be done with jQuery:
var inputFile = $('input[type=field]');
inputFile.wrap('<div />');
and use this line when you need to clear input field (on some event for example):
inputFile.parent().html( inputFile.parent().html() );
Here are my two cents, the input files are stored as array so here is how to null it
document.getElementById('selector').value = []
this return an empty array and works on all browsers
the input.value = null is a working method, however it will only trigger input's change event if called from an onclick event.
Solution to that would be calling that onchange handler manually whenever you need to reset the input.
function reset_input(input) {
$(input)[0].value = null;
input_change_handler();
}
function input_change_handler() {
// this happens when there's been a change in file selection
if ($(input)[0].files.length) {
// file(s) selected
} else {
// nothing is selected
}
}
$(input).on('change', input_change_handler);
That's actually quite easy.
document.querySelector('#input-field').value = '';
I was having same problem and i came up with this.
var file = document.querySelector('input');
var emptyFile = document.createElement('input');
emptyFile.type = 'file';
document.querySelector('button').onclick = function(){
file.files = emptyFile.files;
}
<input type='file'>
<button>clear</button>
This worked for me.
const clear = (event) =>{event.target.value = [ ];}
clear("input_id");
I have been looking for simple and clean way to clear HTML file input, the above answers are great, but none of them really answers what i'm looking for, until i came across on the web with simple an elegant way to do it :
var $input = $("#control");
$input.replaceWith($input.val('').clone(true));
all the credit goes to Chris Coyier.
// Referneces
var control = $("#control"),
clearBn = $("#clear");
// Setup the clear functionality
clearBn.on("click", function(){
control.replaceWith( control.val('').clone( true ) );
});
// Some bound handlers to preserve when cloning
control.on({
change: function(){ console.log( "Changed" ) },
focus: function(){ console.log( "Focus" ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="control">
<br><br>
Clear
An - in my world easy an clean solution - is, to set the file inputs files to a clear FileList.
EDIT: as SteJ told - this ist not working with Safari.
Since we can not create a FileList directly - I user DataTransfer as "hack"
#$input[0].files=new DataTransfer().files
or
file_input_node.files=new DataTransfer().files
Try this easy and it works
let input = elem.querySelector('input[type="file"]');
input.outerHTML=input.outerHTML;
this will reset the input
The above answers offer somewhat clumsy solutions for the following reasons:
I don't like having to wrap the input first and then getting the html, it is very involved and dirty.
Cross browser JS is handy and it seems that in this case there are too many unknowns to reliably use type switching (which, again, is a bit dirty) and setting value to ''
So I offer you my jQuery based solution:
$('#myinput').replaceWith($('#myinput').clone())
It does what it says, it replaces the input with a clone of itself. The clone won't have the file selected.
Advantages:
Simple and understandable code
No clumsy wrapping or type switching
Cross browser compatibility (correct me if I am wrong here)
Result:
Happy programmer
I changed to type text and back to type to file using setAttribute
'<input file-model="thefilePic" style="width:95%;" type="file" name="file" id="filepicture" accept="image/jpeg" />'
'var input=document.querySelector('#filepicture');'
if(input != null)
{
input.setAttribute("type", "text");
input.setAttribute("type", "file");
}
What helped me is, I tried to fetch and upload the last selected file using a loop, instead of clearing out the queue, and it worked. Here is the code.
for (int i = 0; i <= Request.Files.Count-1; i++)
{
HttpPostedFileBase uploadfile = files[i];
Stream fs = uploadfile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] imageBytes = br.ReadBytes((Int32)fs.Length);
}
Hope this might help some.
Make the value null or empty string like this `` in order to clear value of a single input element
You can easily reset all form values using the HTML button using the <input type=”reset”> attribute.
The HTMLFormElement.reset() method restores a form element's default values. This method does the same thing as clicking the form's control.
To clear the entire input field without having to delete the whole thing manually Or what if there is already a pre-suggested input present in the input field, that the user doesn’t want. There could be many scenarios.
You can try this as a live example
const fileInputElement = document.getElementById('file-input');
const formElement = document.getElementById('input-form');
// Method-1: Clear files
// fileInputElement.value = '';
// Method-2: Clear files
// fileInputElement.value = null;
// Method-3: Clear files - on event listener
fileInputElement.addEventListener('change', (event)=>{
// If the file did not meet certain condition
event.target.value = '';
});
// Method-4: Clear or reset whole form
formElement.addEventListener('submit', (event)=>{
// If ajax call is failed to make request
event.target.reset();
// or
// formElement.reset()
});
.form{
display: flex;
flex-direction: column;
width: 80%;
margin-left: 10%;
}
#file-input, .form-control{
margin-top: 1rem;
}
.form-control{
padding: 1em 0;
}
#file-input{
background: #ccccff;
}
#file-input::-webkit-file-upload-button {
background: #000033;
color: white;
padding: 1em;
}
.button-group{
display: flex;
justify-content: start;
}
.btn{
background: #004d4d;
color: white;
width: 4rem !important;
margin-right: 10px;
}
<form id='input-form' class='form' >
<input type='file' id='file-input' />
<input type='text' class='form-control' id='text-input' placeholder='your name' />
<div class='button-group'>
<button type='reset' class='form-control btn' id='reset-form'>Reset</button>
<button type='submit' class='form-control btn' id='submit-form'>Submit</button>
</div>
</form>
I tried most of solutions but did not seem anyone to work. However I found a walk around for it below.
The structure of the form is: form => label, input and submit button. After we choose a file, the filename will be shown by the label by doing so manually in JavaScript.
So my strategy is: initially the submit button is disabled, after a file is chosen, the submit button disabled attribute will be removed such that I can submit file. After I submit, I clear the label which makes it look like I clear the file input but actually not. Then I will disable the submit button again to prevent from submitting the form.
By setting the submit button disable or not, I stop the file from submitted many times unless I choose another file.
Can we detect whether a browser supports dropping a file over an <input type="file" />?
For example, this is possible in Chrome but not in IE8.
Modernizr.draganddrop is a possibility but is it the right choice? I'm not adding any custom drag/drop event handlers.
Update
To verify Joe's answer here's a jQuery example that should stop the file drop. Verified in Chrome and Firefox.
$yourFileInput.on('drop', function() {
return false; // if Joe's explanation was right, file will not be dropped
});
I think the answer to Detecting support for a given JavaScript event? may help you. Adjusting the code to test against Input instead of Div, and testing for the "Drop" event seems to work fine for me.
Reproduced here so you don't have to click through (and adjusted slightly, since it seems you only need to detect this one feature):
function isEventSupported(eventName) {
var el = document.createElement('input');
eventName = 'on' + eventName;
var isSupported = (eventName in el);
if (!isSupported) {
el.setAttribute(eventName, 'return;');
isSupported = typeof el[eventName] == 'function';
}
el = null;
return isSupported;
}
if(isEventSupported('drop')){
//Browser supports dropping a file onto Input
} else {
//Fall back, men!
}
I can't seem to get the currently focused/active element as a jQuery object in Firefox, if it is an <input type="file" />. It works on other input types (text, password, submit, others) and on other element types (<select>, <textarea>, others).
HTML
<input type="file" />
Javascript
// Cannot find input type file elements with :focus,
// $focused.length is always 0 in Firefox (tested using FF 10.0.1)
var $focusedTest1 = $(':focus');
// This line throws for Firefox (tested using FF 10.0.1)
// Permission denied to access property 'nodeType'
// # http://code.jquery.com/jquery-1.7.1.js:108
// in jQuery.fn.init, below "Handle $(DOMElement)"
var $focusedTest2 = $(document.activeElement);
Steps to reproduce
Use Firefox.
Focus the file box:
press tab until you reach it
or click in it.
While focusing the file box, try to get a result from $(':focus').
See jsFiddle demonstration of getting the id of the focused element - test it with Firefox.
Does anyone have a solution for getting the focused/active element as a jQuery object that works for <input type="file" />?
The solution needs to be fully generic as the functionality is part of a plugin. I will not have control over the page the script will run on.
Edit: This solution has been implemented where the problem was first found, in EmulateTab. See getFocusedElement().
Found a solution myself, after a break from coding - but it is not a very clean solution. It is basically the same solution suggested by #Neil while I first wrote this post.
Try the updated jsFiddle version with focus listeners and try-catch logic in Firefox. It combines :focus, document.activeElement and document level focus listeners that keep track of the last "known" focused element.
Function to find focused element
// Comined function to get the focused element trying as long as possible.
// Extra work done trying to avoid problems with security features around
// <input type="file" /> in Firefox (tested using 10.0.1).
function getFocused() {
// Try the well-known, recommended method first.
var $focused = $(':focus');
if ($focused.size() === 0) {
try {
// Fall back to a fast method that might fail.
// Known to fail for Firefox (tested using 10.0.1) with
// Permission denied to access property 'nodeType'.
$focused = $(document.activeElement)
}
catch (error1) {
warnToConsole("Could not use document.activeElement", document.activeElement, error1);
if (lastFocusedElement !== null) {
try {
// As a last resort, use the last known focused element.
// Has not been tested enough to be sure it works as expected.
$focused = $(lastFocusedElement);
} catch (error3) {
warnToConsole("Could not use lastFocusedElement ", lastFocusedElement, error3);
}
}
}
}
return $focused;
}
Focus listeners
// Keep a reference to the last focused element, use as a last resort.
var lastFocusedElement = null;
function focusInElement(event) {
lastFocusedElement = event.target;
}
function focusOutElement(event) {
lastFocusedElement = null;
}
// Start listeners.
$(function() {
// Start listeners that keep track of the last focused element.
$(document).on("focusin", focusInElement);
$(document).on("focusout", focusOutElement);
});
I don't like this solution very much, as it is far from as clean as just a one-line $(':focus'). Other answers are welcome!
The only way I can think of is to add a capturing focus listener at the window level in which you update a global variable with the event target. (In Firefox, the event target for a focus event in a file input is the file input itself even though document.activeElement returns the "anonymous" button.)
Try this - tested in Firefox 10.0.1
$(document).ready(function () {
var crtFocus;
$("#id1").focus(function () {
crtFocus = $(this);
});
$("#id2").focus(function () {
crtFocus = $(this);
});
$("#id3").focus(function () {
crtFocus = $(this);
});
$("#click").click(function () {
// $(crtFocus) contains the currently focused element
//alert($(crtFocus));
});
});
...
<input type="file" id="id1" />
<input type="file" id="id2" />
<input type="file" id="id3" />
<input type="button" id="click"/>
EDIT - we can use only one selector for all input[type=file] elements instead of one selector per element
$(':input[type=file]').focus(function () {
crtFocus = $(this);
});
I want to clear the file input in my form.
I know about setting the sources to the same method... But that method wont erase the selected file path.
Note: I would like to avoid having to reload the page, reset the form or perform an AJAX call.
Is this possible?
There's 3 ways to clear file input with javascript:
set value property to empty or null.
Works for IE11+ and other modern browsers.
Create an new file input element and replace the old one.
The disadvantage is you will lose event listeners and expando properties.
Reset the owner form via form.reset() method.
To avoid affecting other input elements in the same owner form, we can create an new empty form and append the file input element to this new form and reset it. This way works for all browsers.
I wrote a javascript function. demo: http://jsbin.com/muhipoye/1/
function clearInputFile(f){
if(f.value){
try{
f.value = ''; //for IE11, latest Chrome/Firefox/Opera...
}catch(err){ }
if(f.value){ //for IE5 ~ IE10
var form = document.createElement('form'),
parentNode = f.parentNode, ref = f.nextSibling;
form.appendChild(f);
form.reset();
parentNode.insertBefore(f,ref);
}
}
}
tl;dr: For modern browsers, just use
input.value = '' or input.value = null;
Old answer:
How about:
input.type = "text";
input.type = "file";
I still have to understand why this does not work with webkit.
Anyway, this works with IE9>, Firefox and Opera.
The situation with webkit is that I seem to be unable to change it back to file.
With IE8, the situation is that it throws a security exception.
Edit:
For webkit, Opera and firefox this works, though:
input.value = '';
(check the above answer with this proposal)
I'll see if I can find a nice cleaner way of doing this cross-browser without the need of the GC.
Edit2:
try{
inputs[i].value = '';
if(inputs[i].value){
inputs[i].type = "text";
inputs[i].type = "file";
}
}catch(e){}
Works with most browsers. Does not work with IE < 9, that's all.
Tested on firefox 20, chrome 24, opera 12, IE7, IE8, IE9, and IE10.
Setting the value to '' does not work in all browsers.
Instead try setting the value to null like so:
document.getElementById('your_input_id').value= null;
EDIT:
I get the very valid security reasons for not allowing JS to set the file input, however it does seem reasonable to provide a simple mechanism for clearing already selecting output. I tried using an empty string but it did not work in all browsers, NULL worked in all the browsers I tried (Opera, Chrome, FF, IE11+ and Safari).
EDIT:
Please note that setting to NULL works on all browsers while setting to an empty string did not.
Unfortunately none of the above answers appear to cover all the bases - at least not with my testing with vanilla javascript.
.value = null appears to work on FireFox, Chome, Opera and IE11 (but not IE8/9/10)
.cloneNode (and .clone() in jQuery) on FireFox appears to copy the .value over, therefore making the clone pointless.
So here is the vanilla javascript function I have written that works on FireFox (27 and 28), Chrome (33), IE (8, 9, 10, 11), Opera (17)... these are the only browsers currently available to me to test with.
function clearFileInput(ctrl) {
try {
ctrl.value = null;
} catch(ex) { }
if (ctrl.value) {
ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);
}
}
The ctrl parameter is the file input itself, so the function would be called as...
clearFileInput(document.getElementById("myFileInput"));
SOLUTION
The following code worked for me with jQuery. It works in every browser and allows to preserve events and custom properties.
var $el = $('#your-input-id');
$el.wrap('<form>').closest('form').get(0).reset();
$el.unwrap();
DEMO
See this jsFiddle for code and demonstration.
LINKS
Clearing <input type='file' /> using jQuery
How to reset file input with JavaScript
document.getElementById('your_input_id').value=''
Edit:
This one doesn't work in IE and opera, but seems to work for firefox, safari and chrome.
U need replace it with new file input.
Here is how it can be done with jQuery:
var inputFile = $('input[type=field]');
inputFile.wrap('<div />');
and use this line when you need to clear input field (on some event for example):
inputFile.parent().html( inputFile.parent().html() );
Here are my two cents, the input files are stored as array so here is how to null it
document.getElementById('selector').value = []
this return an empty array and works on all browsers
the input.value = null is a working method, however it will only trigger input's change event if called from an onclick event.
Solution to that would be calling that onchange handler manually whenever you need to reset the input.
function reset_input(input) {
$(input)[0].value = null;
input_change_handler();
}
function input_change_handler() {
// this happens when there's been a change in file selection
if ($(input)[0].files.length) {
// file(s) selected
} else {
// nothing is selected
}
}
$(input).on('change', input_change_handler);
That's actually quite easy.
document.querySelector('#input-field').value = '';
I was having same problem and i came up with this.
var file = document.querySelector('input');
var emptyFile = document.createElement('input');
emptyFile.type = 'file';
document.querySelector('button').onclick = function(){
file.files = emptyFile.files;
}
<input type='file'>
<button>clear</button>
This worked for me.
const clear = (event) =>{event.target.value = [ ];}
clear("input_id");
I have been looking for simple and clean way to clear HTML file input, the above answers are great, but none of them really answers what i'm looking for, until i came across on the web with simple an elegant way to do it :
var $input = $("#control");
$input.replaceWith($input.val('').clone(true));
all the credit goes to Chris Coyier.
// Referneces
var control = $("#control"),
clearBn = $("#clear");
// Setup the clear functionality
clearBn.on("click", function(){
control.replaceWith( control.val('').clone( true ) );
});
// Some bound handlers to preserve when cloning
control.on({
change: function(){ console.log( "Changed" ) },
focus: function(){ console.log( "Focus" ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="control">
<br><br>
Clear
An - in my world easy an clean solution - is, to set the file inputs files to a clear FileList.
EDIT: as SteJ told - this ist not working with Safari.
Since we can not create a FileList directly - I user DataTransfer as "hack"
#$input[0].files=new DataTransfer().files
or
file_input_node.files=new DataTransfer().files
Try this easy and it works
let input = elem.querySelector('input[type="file"]');
input.outerHTML=input.outerHTML;
this will reset the input
The above answers offer somewhat clumsy solutions for the following reasons:
I don't like having to wrap the input first and then getting the html, it is very involved and dirty.
Cross browser JS is handy and it seems that in this case there are too many unknowns to reliably use type switching (which, again, is a bit dirty) and setting value to ''
So I offer you my jQuery based solution:
$('#myinput').replaceWith($('#myinput').clone())
It does what it says, it replaces the input with a clone of itself. The clone won't have the file selected.
Advantages:
Simple and understandable code
No clumsy wrapping or type switching
Cross browser compatibility (correct me if I am wrong here)
Result:
Happy programmer
I changed to type text and back to type to file using setAttribute
'<input file-model="thefilePic" style="width:95%;" type="file" name="file" id="filepicture" accept="image/jpeg" />'
'var input=document.querySelector('#filepicture');'
if(input != null)
{
input.setAttribute("type", "text");
input.setAttribute("type", "file");
}
What helped me is, I tried to fetch and upload the last selected file using a loop, instead of clearing out the queue, and it worked. Here is the code.
for (int i = 0; i <= Request.Files.Count-1; i++)
{
HttpPostedFileBase uploadfile = files[i];
Stream fs = uploadfile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] imageBytes = br.ReadBytes((Int32)fs.Length);
}
Hope this might help some.
Make the value null or empty string like this `` in order to clear value of a single input element
You can easily reset all form values using the HTML button using the <input type=”reset”> attribute.
The HTMLFormElement.reset() method restores a form element's default values. This method does the same thing as clicking the form's control.
To clear the entire input field without having to delete the whole thing manually Or what if there is already a pre-suggested input present in the input field, that the user doesn’t want. There could be many scenarios.
You can try this as a live example
const fileInputElement = document.getElementById('file-input');
const formElement = document.getElementById('input-form');
// Method-1: Clear files
// fileInputElement.value = '';
// Method-2: Clear files
// fileInputElement.value = null;
// Method-3: Clear files - on event listener
fileInputElement.addEventListener('change', (event)=>{
// If the file did not meet certain condition
event.target.value = '';
});
// Method-4: Clear or reset whole form
formElement.addEventListener('submit', (event)=>{
// If ajax call is failed to make request
event.target.reset();
// or
// formElement.reset()
});
.form{
display: flex;
flex-direction: column;
width: 80%;
margin-left: 10%;
}
#file-input, .form-control{
margin-top: 1rem;
}
.form-control{
padding: 1em 0;
}
#file-input{
background: #ccccff;
}
#file-input::-webkit-file-upload-button {
background: #000033;
color: white;
padding: 1em;
}
.button-group{
display: flex;
justify-content: start;
}
.btn{
background: #004d4d;
color: white;
width: 4rem !important;
margin-right: 10px;
}
<form id='input-form' class='form' >
<input type='file' id='file-input' />
<input type='text' class='form-control' id='text-input' placeholder='your name' />
<div class='button-group'>
<button type='reset' class='form-control btn' id='reset-form'>Reset</button>
<button type='submit' class='form-control btn' id='submit-form'>Submit</button>
</div>
</form>
I tried most of solutions but did not seem anyone to work. However I found a walk around for it below.
The structure of the form is: form => label, input and submit button. After we choose a file, the filename will be shown by the label by doing so manually in JavaScript.
So my strategy is: initially the submit button is disabled, after a file is chosen, the submit button disabled attribute will be removed such that I can submit file. After I submit, I clear the label which makes it look like I clear the file input but actually not. Then I will disable the submit button again to prevent from submitting the form.
By setting the submit button disable or not, I stop the file from submitted many times unless I choose another file.