To prevent answers like: 'is the JavaScript file loaded?' -> Yes, it is loaded, at the footer part of the page! I have checked that with a simple message to the console, which is displayed!
But:
I've got a page with a button:
<button id="portfolio-posts-btn">Load portfolio related blog posts</button>
And a file main.js:
var portfolioPostsBtn = document.getElementById('portfolio-posts-btn');
var portfolioPostsContainer = document.getElementById("portfolio-posts-container");
if (portfolioPostsBtn) {
portfolioPostsBtn.addEventListener("click", function () {
console.log("the button was clicked!");
});
}
The text the button was clicked! should be displayed in the console, but it stays empty!
Apparently, the button click is not recognized, and thus, the var portfolioPostsBtn is false, or NULL... -> the method addEventListener() is not fired ?
I don't see the cause for this; I checked the spelling, should I use single or double quotes? Please help?
Thank you!
I've had this happen to me before, since theres two ways to do this I just used the other.
The first is onclick="function()", this is used as an attribute inside the element. Ex:
function clicked(){
alert("button clicked");
}
<button onclick="clicked();">Press me</button>
exaplaination: When you add this attribute to this element and I do believe some others when the button is clicked the specified code inside the quotes of the attibute will run. It doesn't have to be a number, e.g. onclick="alert(12+4/2);". But this is more of HTML than JavaScript using this version
The other way is using what you've got which (to me) is a lot more difficult then it needs to be. Heres my example
var b = document.getElementById("btn");
b.addEventListener("click", blogged);
function blogged(){
alert("this post has been blogged");
}
<button id="btn">Blog it</button>
This side of things has more to do with JavaScript and Event listeners. But the problem with you're code is that you're putting the event listener after you call the if statement. Here's my solution
var portfolioPostsBtn = document.getElementById('portfolio-posts-btn');
portfolioPostsBtn.addEventListener("click", function(){
check();
});
function check(){
if(portfolioPostsBtn){
console.log("posted");
}
}
<button id="portfolio-posts-btn">press this to post<button>
Presumably you have made a decision not to use jQuery. You'll need to wrap your code in an event listener so that the code is executed when the DOM is ready.
document.addEventListener("DOMContentLoaded", function(event) {
var portfolioPostsBtn = document.getElementById("portfolio-posts-btn");
var portfolioPostsContainer = document.getElementById("portfolio-posts-container");
if (portfolioPostsBtn) {
portfolioPostsBtn.addEventListener("click", function () {
console.log("the button was clicked!");
});
}
});
The answer is found in the uploading of the file page-portfolio.php!
I found out that the id="portfolio-posts-btn", added later, was not updated - could be my mistake, or the SFTP upload extension in Brackets - I did not see an error message!
Anyway, the issue is solved!
One more question: "are there methods to check if an id exists?". That could make live easier!
All contributors, thank you for your answers!
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.