In this post we will discuss input type = “file” and learn to style it in our own way. This input filed is displayed as a text_filed followed by browse button. The html markup for a File Uploader is as below.
<input id="loan_attachments_file" type="file" name="loan[attachments][file]" />
The problem, with this default approach is that it is rendered by different browser in different way.
For example : this is how it looks in Mozilla and Chrome .
File Uploader display in chrome
NOTE : the complete HTML structure for the images below is given in step 4 towards the end
File Uploader display in Firefox.
So, you can see that the look and feel of uploader is different in different browser. We will now customize the uploader, with our own css, so that it look consistent in all the browser. We will follow the below approach.
STEP 1: Hide the default File Uploader
<input type="file" style="display:none;" name="loan[attachments][file]" id="loan_attachments_file" />
STEP 2: Create HTML structure similar to default one
create a text field followed by browse button or link. Obviously, you can apply any css look to the text-filed or the browse button.
I have used below HTML structure. showing only the customized uploader code
<div>
<div>
<input type="text" value="Please select a file" id="filename" />
<label id="upload_doc_label" for="loan_attachments_file">Browse</label>
<input type="file" style="display:none;" name="loan[attachments][file]" id="loan_attachments_file" />
</div>
</div>
So here we have provided our own custom uploader and hidden the default uploader. But I have found that, in IE8 clicking on the browse label do not trigger the default file input we have marked as hidden as IE8 do not recognize element with display:none . since, our aim is to do not show the default file uploader, we can achieve it with setting its absolute position outside the view. The correct markup working in all IE version and browser is as below.
<div>
<div>
<input type="text" value="Please select a file" id="filename" />
<label id="upload_doc_label" for="loan_attachments_file">Browse</label>
<input type="file" style="display:none;" name="loan[attachments][file]" id="loan_attachments_file"
style= "-moz-opacity:0;filter:alpha(opacity:0);opacity:0; position:absolute; top:-50px"/>
</div>
</div>
It look as below in all the browser
STEP 3: Trigger click event on the hidden file input
Here You should remember that, the default file input type do below two things.
=> on clicking browse button open up file navigation window for selecting file
=>on selecting a file, it populate the text filed with path of the selected file
Now, we will control these two aspect, with JavaScript code .
=> when user click custom browse button, we will trigger click event on the hidden field input
if($.browser.mozilla) {
$( "#upload_doc_label" ).on( "click", function(e) {
e.preventDefault();
$('#loan_attachments_file').trigger('click');
});
}
Here come the tricky part. You can see that, I have triggered the click event only when browser is mozilla. This is because, mozilla do not support for tag on lable while chrome and IE support it. Since we have made the browse button as label, whose for attribute have id of the hidden file type, when ever user click the browse lable, the hidden file input field automatically get selected and click event get fired on it. This do not happen in case of mozila, so we have explicitly triggered it.
Now, the question arise what is wrong if we allow it for IE and chrome also. Well if you do that, you have to search in google “Custom File Uploader not working in IE” . I mean the uploader not at all work in IE , though it will work in chrome and Firefox . The issue is discussed in depth here on the stackoverflow.
NOTE : browse button is designed as lable so that IE trigger click event on the file input itself rather then explicitly through the code.
=> Populate the custom text field with the file path of the selected file.
$( "#loan_attachments_file" ).on( "change", function(e) {
var temp = $(this).val().split('\\').length;
var filename = $(this).val().split('\\')[temp - 1];
$('#filename').val(filename);
});
STEP 4 : click the upload button to upload the file
Below is the code having file field within a form with a upload and a cancel button
<form method="post" id="edit_loan_349" enctype="multipart/form-data" action="/loan_documents">
<div>
<div>
<input type="text" value="Please select a file" id="filename" />
<label id="upload_doc_label" for="loan_attachments_file">Browse</label>
</div>
</div>
<input type="file" style="display:none;" name="loan[attachments][file]" id="loan_attachments_file"
style= "-moz-opacity:0;filter:alpha(opacity:0);opacity:0; position:absolute; top:-50px"/>
<div>
<div>
<input type="submit" value="Upload" name="commit" id="upload_doc" />
<a href="/loan_documents/document_listing">Cancel</a>
</div>
</div>
</form>