IAM

ARTICLE

Minimal but Elegant File Upload Button in Twitter Bootstrap

While using Twitter Bootstrap for a web application I am working on, I came across the (still) very ugly default file upload form element. After doing some research and setting up a demo, I wrote a tiny plugin for simple but pretty, cross-browser (including Internet Explorer 7,8 and 9) file upload form elements with Twitter Bootstrap.

Recently, I came across the (ugly) default file upload form element when building a web application using Twitter Bootstrap. Naively adding a class="btn btn-primary" did not really help. Therefore, after doing some research and writing a bit of jQuery, I came up with a simple but pretty-looking solution which I will present in the following.

The code is available as Twitter Bootstrap plugin:

GitHub RepositoryExample

Example

The plugin consists of dist/js/file-upload.js and dist/css/file-upload.css (and the corresponding LESS file) and is easy to use:

<link rel="stylesheet" type="text/css" href="css/file-upload.css" />
<script src="js/file-upload.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $('.file-upload').file_upload();
    });
</script>
<form class="form-horizontal">
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <label class="file-upload btn btn-primary">
                Browse for file ... <input type="file" />
            </label>
        </div>
    </div>
</form>

A comparison with the default file upload form element in shown in Figure 1 and available in the documentation.

Figure 1 (click to enlarge): Comparison of default file upload form element in Twitter Bootstrap and the overhauled, simple and elegant file upload form element.

Background

The underlying code is quite simple, but has potential for many user-friendly improvements. The LESS takes care of styling the element accordingly — with cross-browser support including Internet Explorer 7, 8 and 9:

label.file-upload {
    position: relative;
    overflow: hidden;

    input[type="file"] {
        position: absolute;
        top: 0;
        right: 0;
        min-width: 100%;
        min-height: 100%;
        font-size: 100px;
        text-align: right;
        filter: alpha(opacity=0);
        opacity: 0;
        outline: none;
        background: white;
        cursor: inherit;
        display: block;
    }
}

The corresponding JavaScript/jQuery only takes care of displaying the file name as button text whenever a new file is chosen:

// this.element corresponds to the file upload form element.
this.element.on('change', ':file', function() {
    var input = $(this);
    var label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
            
    $('.file-upload-text', $(this).parent('label')).text(label);
});

So the JavaScript/jQuery plugin itself is quite simple. However, it also allows to easily extend it to get more user-friendly and include more functionality. Some of the features I am thinking about include a reset button as well as options for truncating the file name, extracting the file extension for validation and also displaying the full path to the selected file.

What is your opinion on this article? Let me know your thoughts on Twitter @davidstutz92 or LinkedIn in/davidstutz92.