While implementing one of my most used jQuery plugins, bootstrap-file-input, I ran into a browser specific niggle. Clearing HTML form inputs using javascript or a library like jQuery is usually considered trivial. You generally set the value
property (or val()
in jQuery) to an empty string. This works pretty much well for all input types across all browsers, with the exception if you are using a file input and a browser like Internet Explorer (versions 10 and below).
About File Input
For novices, we are talking about the HTML form input with file type i.e. <input type="file">
. This input allows you to select/pick files for upload from your client via the browser.
Clearing Input Values
In most modern browsers (as of 2014) e.g. Firefox, Chrome, Safari, Opera, and IE v11, this is pretty straightforward. The inputs can be cleared (including file inputs) in the following way:
// clearing value in javascript
var elem = document.getElementById("input-id");
elem.value = "";
// clearing value in jquery
$('#input-id').val('');
Internet Explorer (IE8 to IE10)
Unfortunately the above method will not work with Internet Explorer browsers (versions 8.x to 10.x). This is because file input values are considered READ ONLY as part of the browser security implementation. What are your solution options then to clear file inputs in these browsers? Well, if you do a search on the web, you will find some solutions that could be summarized into two different options:
Option 1: Cloning & replacing the input.
You could clone the input using jQuery clone method and replace your control.
<input type="file" id="fileInput"/>
<button id="clear" type="button">Clear</button>
<script>
$fileInput = $('#fileInput');
$("#clear").on("click", function () {
$fileInput.replaceWith( $fileInput = $fileInput.clone( true ) );
});
</script>
This works well for various use cases. There are however some drawbacks of the method.
- Note the
true
parameter in the clone is needed in order to clone the file input element preserving all event handlers. However, there could be duplicate undesired occurences which you need to handle by right event delegation to handle clicks in the parent element. - I personally found this method not so desirable, since it was creating a duplicate copy of my file input. This behavior was especially not desired in my file input plugin bootstrap-file-input.
Option 2: Resetting the parent form
You could reset the wrapping form to clear file values.
<form>
<input type="file" id="fileInput"/>
</form>
<script>
$("#fileInput").closest('form').trigger('reset');
</script>
This works well for various use cases. There are however some drawbacks of the method as well.
- It would reset all fields within the form, which you do not desire.
- To overcome that you could wrap the
input
in anotherform
element and try to reset it. This has been described in various articles online. However, you would run into a nested form issue, that hangs the IE browser on reset.
The solution below is what worked for me across the browser landscape.
The Solution
The following solution enabled me to build a function to clear file inputs across all browsers. It is used within my bootstrap-file-input plugin for people interested to look at the implementation. The example uses jQuery, but can be easily adapted for a normal javascript usage.
function clearFileInput($input) {
if ($input.val() == '') {
return;
}
// Fix for IE ver < 11, that does not clear file inputs
// Requires a sequence of steps to prevent IE crashing but
// still allow clearing of the file input.
if (/MSIE/.test(navigator.userAgent)) {
var $frm1 = $input.closest('form');
if ($frm1.length) { // check if the input is already wrapped in a form
$input.wrap('<form>');
var $frm2 = $input.closest('form'), // the wrapper form
$tmpEl = $(document.createElement('div')); // a temporary placeholder element
$frm2.before($tmpEl).after($frm1).trigger('reset');
$input.unwrap().appendTo($tmpEl).unwrap();
} else { // no parent form exists - just wrap a form element
$input.wrap('<form>').closest('form').trigger('reset').unwrap();
}
} else { // normal reset behavior for other sane browsers
$input.val('');
}
},
So you can call the above method wherever you want to clear your file input. For example:
<input type="file" id="fileInput"/>
<button id="clear" type="button">Clear</button>
<script>
$fileInput = $('#fileInput');
$("#clear").on("click", function () {
clearFileInput($fileInput);
});
</script>
The post Clear HTML file input value in IE using javascript appeared first on Krajee Web Tips.