最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Track basic HTML form post progress - Stack Overflow

programmeradmin5浏览0评论

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 pleted 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 );

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 pleted 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 );
Share Improve this question edited Sep 4, 2014 at 18:15 jfreak53 asked Sep 4, 2014 at 14:58 jfreak53jfreak53 2,3697 gold badges38 silver badges56 bronze badges 1
  • You might try to google some library that does this upload with a progressbar, it'll be much less pain tna trying to roll your own. – MightyPork Commented Sep 4, 2014 at 18:18
Add a ment  | 

2 Answers 2

Reset to default 4

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));

    });

};

HTML:

<form method="post">
    <button type="submit">Submit</button>
</form>

JavaScript:

/*
Show a progress element for any form submission via POST.
Prevent the form element from being submitted twice.
*/
(function (win, doc) {
    'use strict';
    if (!doc.querySelectorAll || !win.addEventListener) {
        // doesn't cut the mustard.
        return;
    }
    var forms = doc.querySelectorAll('form[method="post"]'),
        formcount = forms.length,
        i,
        submitting = false,
        checkForm = function (ev) {
            if (submitting) {
                ev.preventDefault();
            } else {
                submitting = true;
                this.appendChild(doc.createElement('progress'));
            }
        };
    for (i = 0; i < formcount; i = i + 1) {
        forms[i].addEventListener('submit', checkForm, false);
    }
}(this, this.document));

Demo: http://jsfiddle/jsbo6yya/

Credit: https://gist.github./adactio/9315750

发布评论

评论列表(0)

  1. 暂无评论