Ajax progress bar

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Generate 32 char random uuid 
function gen_uuid() {
    var uuid = ""
    for (var i=0; i < 32; i++) {
        uuid += Math.floor(Math.random() * 16).toString(16); 
    }
    return uuid
}

// Add upload progress for multipart forms.
$(function() {
    $('form[@enctype=multipart/form-data]').submit(function(){ 
        // Prevent multiple submits
        if ($.data(this, 'submitted')) return false;

        var freq = 1000; // freqency of update in ms
        var uuid = gen_uuid(); // id for this upload so we can fetch progress info.
        var progress_url = '/admin/upload_progress/'; // ajax view serving progress info

        // Append X-Progress-ID uuid form action
        this.action += (this.action.indexOf('?') == -1 ? '?' : '&') + 'X-Progress-ID=' + uuid;
        
        var $progress = $('<div id="upload-progress" class="upload-progress"></div>').
            appendTo(document.body).append('<div class="progress-container"><span class="progress-info">uploading 0%</span><div class="progress-bar"></div></div>');
        
        // progress bar position
        $progress.css({
            position: ($.browser.msie && $.browser.version < 7 )? 'absolute' : 'fixed',  
            left: '50%', marginLeft: 0-($progress.width()/2), bottom: '20%'
        }).show();

        // Update progress bar
        function update_progress_info() {
            $progress.show();
            $.getJSON(progress_url, {'X-Progress-ID': uuid}, function(data, status){
                if (data) {
                    var progress = parseInt(data.uploaded) / parseInt(data.length);
                    var width = $progress.find('.progress-container').width()
                    var progress_width = width * progress;
                    $progress.find('.progress-bar').width(progress_width);
                    $progress.find('.progress-info').text('uploading ' + parseInt(progress*100) + '%');
                }
                window.setTimeout(update_progress_info, freq);
            });
        };
        window.setTimeout(update_progress_info, freq);

        $.data(this, 'submitted', true); // mark form as submitted.
    });
});

More like this

  1. Improve ajax progress bar by jquery extensions by williamcai 3 years, 4 months ago
  2. Upload progress handler using cache framework by ebartels 6 years ago
  3. Upload, Progressbar with sessions by revolunet 5 years, 8 months ago
  4. @url decorator improvements by davepeck 4 years, 8 months ago
  5. Django-Celery Progress Bar backend by fsfsfs 1 year, 1 month ago

Comments

stopNsee (on July 22, 2008):

Thanks for django file upload snippets.

However, I must say I do not know how to write the template page. Please show me a sample template page...

Thanks a lot!

#

tuttle (on July 26, 2008):

Thanks for this snippet!

Anyway, I think it is worth mentioning that this will

1) NOT currently work with Django devel webserver (cannot serve multiple requests at once),

2) NOT work with a cache not sharing data between processes such as locmem://.

Finally I made this to work on prefork Apache with memcached://.

#

t3mp0 (on August 29, 2010):

To get this work with more recent versions of jquery, I had to remove the '@' in line 12.

#

a141890 (on January 8, 2013):

After spending hours, I got it worked well.

but it has some problems..

when I upload a big movie file (more than 2Gbytes size of file), the progress bar does not work until uploading the video file finish.

so.. the progress bar works after completing upload of the video file.

Here is what I think.

File Handler works after Django finishes receiving and saving the whole data of the file on temporary directory.

That is, Progress bar will not work until the uploaded data will be saved onto temporary directory.

  1. An user uploads a video file
  2. Browser uploads the video file to Server
  3. the progress bar will not work until the upload finishes.
  4. after django stores the video file onto temporary directory, File Handler will start to work.
  5. now, the progress bar work (that is, the progress bar represents the progress of transforming the uploaded video file on temporary directory to somewhere like Database or file storage system, not the whole progress of uploading the video file)

Is there someone who can detect the progress status of the whole process?

I think using File Handler is not sufficient.

#

(Forgotten your password?)