codedecoder

breaking into the unknown…

custom file uploader

Leave a comment

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_chrome

file_uploader_chrome

File Uploader display in Firefox.

firefox_file_uploader

firefox_file_uploader

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

customized_file_uploader

customized_file_uploader

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>
Advertisements

Author: arunyadav4u

over 7 years experience in web development with Ruby on Rails.Involved in all stage of development lifecycle : requirement gathering, planing, coding, deployment & Knowledge transfer. I can adept to any situation, mixup very easily with people & can be a great friend.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s