File uploads: Percentage completed progress bar

henrywright picture henrywright · Feb 8, 2014 · Viewed 41.6k times · Source

I'm trying to add a 'percentage completed so far' progress bar to avatar uploads in BuddyPress. The aim is to stop users navigating away from the page before the upload is completed.

The upload process is handled in BuddyPress by bp_core_avatar_handle_upload() in file bp-core/bp-core-avatars.php. The function starts off by checking that the file has been uploaded properly using bp_core_check_avatar_upload(). It then checks that the file size is within limits, and that it has an accepted file extension (jpg, gif, png). If everything checks out, the user is allowed to crop the image (uses Jcrop) and then the image is moved to its real location.

The actual upload is handled by the WordPress function wp_handle_upload.

How can I create a 'percentage completed' progress bar and display it when the file is uploading?

Answer

Stumblor picture Stumblor · Feb 17, 2014

I'm not familiar with BuddyPress, but all upload handlers (including the HTML5 XHR one that androbin outlined) will have a file progress hook point that you can bind to.

I've used uploadify, uploadifive and swfupload, and they can all interact with the same progress function handler in order to acheive the same progress bar result.

// SWFUpload
$elem.bind('uploadProgress', function(event, file, bytesLoaded) { fnProgress(file, bytesLoaded); })

// Uploadify
$elem.uploadify({ onUploadProgress: function (file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) { fnProgress(file, bytesUploaded); });

// Uploadfive
$elem.uploadifive({ onProgress: function(file, e) { fn.onProgress(file, e.loaded); });

Uploadifive, being an HTML5 based uploader, simply binds to the XHR 'progress' event, so all these properties will be available to any HTML5 uploader.

As for the actual progress bar code..

HTML:

<div class='progressWrapper' style='float: left; width: 100%'>
    <div class='progress' style='float: left; width: 0%; color: red'></div>
    <div class='progressText' style='float: left;></div>
</div>

JS:

var fnProgress = function(file, bytes) {
    var percentage = (bytesLoaded / file.size) * 100;

    // Update DOM
    $('.progress').css({ 'width': percentage + '%' });
    $('.progressText').html(Math.round(percentage + "%");
}