Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Track basic HTML form post progress

I have a basic HTML form that submits normally, no ajax at all. This form submits to the same file using regular post. I don't use AJAX because the form has 12 text fields and a minimum of 1 image but possibility of up to 26 images and ajax can't do both forms and images at once, I have to save to a DB and it's a lot of extra work over AJAX.

The problem is I need to track form upload progress somehow. Most programmers know to look in the lower left or right corner of their browsers to see form submission progress. But most people don't know this.

So I want to display a progress bar. The problem is all progress bars I have found use XHR requests by ajax. Since the form isn't ajax I can't seem to find a way to track the progress.

So is there a way to intercept the browsers internal submission progress to see the percentage of upload completed for the form?

EDIT

I've tried the following code at the start of the page but it doesn't work. I guess because either XHR is for AJAX or the browser has it's own that needs Hijacking, but I have no clue what that would be called or how to get to it if so:

xhr = new XMLHttpRequest();
xhr.upload.addEventListener( "progress", function ( evt )
{
    if( evt.lengthComputable )
    {
        var progressPercent = ( evt.loaded / evt.total ) * 100;
        console.log( value );
    }
}, false );
like image 470
jfreak53 Avatar asked Sep 04 '14 14:09

jfreak53


1 Answers

This is some type of progressive enhancement i sometimes use. It will still make an ajax request but in the most transparent way as possible both for the user and the developer. The key is to post the exact same data as posted by a regular form thanks to FormData, and to replace the whole document when we receive the full page reponse form the server. This is an untested simplified version :

function enhanceFormWithUploadProgress(form, progress) {
//form : the HTML form element to enhance.
//progress : an HTML element that will display upload progress.

    //testing browser support. if no support for the required js APIs, the form will just be posted naturally with no progress showing.
    var xhr = new XMLHttpRequest();
    if (!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload)) || !window.FormData) {
        return;
    }

    form.addEventListener('submit', function(e) {
        //prevent regular form posting
        e.preventDefault();

        xhr.upload.addEventListener('loadstart', function(event) {
            //initializing the progress indicator (here we're displaying an element that was hidden)
            progress.style.display = 'block';
        }, false);

        xhr.upload.addEventListener('progress', function(event) {
            //displaying the progress value as text percentage, may instead update some CSS to show a bar
            var percent = (100 * event.loaded / event.total);
            progress.innerHTML = 'Progress: ' + percent.toFixed(2) + '%';
        }, false);

        xhr.upload.addEventListener('load', function(event) {
            //this will be displayed while the server is handling the response (all upload data has been transmitted by now)
            progress.innerHTML = 'Completed, waiting for response...';
        }, false);

        xhr.addEventListener('readystatechange', function(event) {
            if (event.target.readyState == 4 && event.target.responseText) {
                //we got a response from the server and we're replacing the whole current document content with it, simulating a page reload
                var newDocument = document.open('text/html', 'replace');
                newDocument.write(event.target.responseText);
                newDocument.close();
            } else {
                throw new Error('Error in the response.');
            }
        }, false);

        //posting the form with the same method and action as specified by the HTML markup
        xhr.open(this.getAttribute('method'), this.getAttribute('action'), true);
        xhr.send(new FormData(this));

    });

};
like image 120
darma Avatar answered Oct 16 '22 06:10

darma