File upload

Simple AJAX file upload with Bootstrap styled progress bar

by Ea Bangalore

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<form>
    <span class="fileUpload btn btn-default">
        <span class="glyphicon glyphicon-upload"></span> Upload file
        <input type="file" id="uploadFile" />
    </span>
</form>
    
<p id="fileUploadError" class="text-danger hide"></p>

<div class="list-group" id="files"></div>

<script id="fileUploadProgressTemplate" type="text/x-jquery-tmpl">
    <div class="list-group-item">
        <div class="progress progress-striped active">
            <div class="progress-bar progress-bar-info" style="width: 0%;"></div>
        </div>
    </div>
</script>

<script id="fileUploadItemTemplate" type="text/x-jquery-tmpl">
    <div class="list-group-item">
        <button type="button" class="close">&times;</button>
        <span class="glyphicon glyphicon-file"></span> File name (type, date, etc)
    </div>
</script>

CSS

.fileUpload {
	position: relative;
	overflow: hidden;
}
.fileUpload input {
	position: absolute;
	top: 0;
	right: 0;
	margin: 0;
	padding: 0;
	cursor: pointer;
	opacity: 0;
}
.progress {
    margin-bottom: 0;
}

JavaScript

$("#uploadFile").change(function() {
    console.log(this.files[0]);
    var formData = new FormData();
    formData.append('file', this.files[0]);
    
    $("#files").append($("#fileUploadProgressTemplate").tmpl());
    $("#fileUploadError").addClass("hide");
    
    $.ajax({
        url: '/echo/json/',
        type: 'POST',
        xhr: function() {
            var xhr = $.ajaxSettings.xhr();
            if (xhr.upload) {
                xhr.upload.addEventListener('progress', function(evt) {
                    var percent = (evt.loaded / evt.total) * 100;
                    $("#files").find(".progress-bar").width(percent + "%");
                }, false);
            }
            return xhr;
        },
        success: function(data) {
            $("#files").children().last().remove();
            $("#files").append($("#fileUploadItemTemplate").tmpl(data));
            $("#uploadFile").closest("form").trigger("reset");
        },
        error: function() {
            $("#fileUploadError").removeClass("hide").text("An error occured!");
            $("#files").children().last().remove();
            $("#uploadFile").closest("form").trigger("reset");
        },
        data: formData,
        cache: false,
        contentType: false,
        processData: false
    }, 'json');
});