Upload files with progress bar
<p>I am making a small practical system to upload files to the server, I am using <strong>Jquery, Jquery Ajax, PHP, Bootstrap 3, Fontawesome</strong> y <strong>Formvalidation.io</strong>.</p>

<p>And I need collaboration to complete and add some features; so far I have managed to make the progress bar, and see the remaining amount of MB in real time;</p>

<p><strong>I want to do the following:</strong></p>

<ol>
<li>Calculate in real time the amount of time remaining to upload the files or.</li>
<li>Where I can find information about events that are obtained from <strong>addEventListener('progress', function(e){});</strong> for example <strong>e.loaded, e.total</strong> etc...</li>
<li>Functionality that have <strong>e.total</strong> and  <strong>e.loaded</strong> events, and other events which may recommend them useful..</li>
<li>It is possible to obtain speed broadband user and based on that, establish an estimate for uploading files time default always put ten twenty seconds; for example, if a user is uploading a file but 2MB broadband speed is 56KB, it would take a long time to upload all files, and do not want to set default much for loading files.</li>
<li>You can speed up the response time of the server, after rising a file, because this doing several tests, and there are times that the server takes to give the answer, after the rise was completed, I tried other plugins, by example <strong>Dropzone</strong>, <strong>Jquery file upload</strong> y <strong>Mini upload form</strong>, and the response times are immediate, they seem to be much more efficient, if this be so, it is advisable to use a system to upload files to custom server as I am doing, or is it better to use some of these plugins I have named.</li>
</ol>

<p><strong>Nota:</strong> I copy the entire code in the HTML this all-inclusive code AJAX, linkable, no need to download libraries, only the path and file PHP, should create a folder and a PHP file with the code and change the path in the AJAX.</p>

<p><strong>AJAX code:</strong></p>

<p><strong>Note:</strong> This code is already included in the HTML.</p>

<pre><code>$.ajax({
    beforeSend: function () {
        // Show modal
        $("#modal_system").modal('show');       
    },
    url: 'ajax/1.4_ajax.php',
    type: 'POST',
    data: formData,
    cache: false,
    contentType: false,
    processData: false,
    dataType: "json",
    timeout: 120000,
    xhr: function() {
        myXhr = $.ajaxSettings.xhr();

        console.log('XHR: ', myXhr);

        if (myXhr.upload) {                     
            myXhr.upload.addEventListener('progress', function(e){

                    var loaded = e.loaded;
                    var total = e.total;
                    var percentComplete = Math.round((e.loaded / e.total) * 100);

                    // Quantity of bytes per second
                    var leftover_bytes =   total - loaded;
                    var leftover_bytes =   leftover_bytes / 1048576;
                    $('.modal-body #dataResponse').html( leftover_bytes.toFixed(2) + ' MB' );

                    // Progress bar function
                    $('.progress .progress-bar').css('width', percentComplete + '%');
                    $('.progress .progress-bar').html( percentComplete + '%');

            }, false);
            myXhr.upload.addEventListener('load', function(e){
                // After upload cant reset progrees bar
                //$('.progress .progress-bar').css('width', '0%');
                //$('.progress .progress-bar').html( '');
            }, false);
        }
        return myXhr;
    }

})
</code></pre>

<p><strong>HTML code:</strong></p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
    &lt;title&gt;Upload files Jquery Ajax - XHR2&lt;/title&gt;
    &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"&gt;
    &lt;link rel="stylesheet" href="https://cdn.rawgit.com/formvalidation/formvalidation.io/master/vendor/formvalidation/css/formValidation.min.css"&gt;
    &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css"&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;!-- Header --&gt;
    &lt;nav class="navbar navbar-inverse"&gt;
      &lt;div class="container"&gt;
        &lt;div class="navbar-header"&gt;
          &lt;button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"&gt;
            &lt;span class="sr-only"&gt;Toggle navigation&lt;/span&gt;
            &lt;span class="icon-bar"&gt;&lt;/span&gt;
            &lt;span class="icon-bar"&gt;&lt;/span&gt;
            &lt;span class="icon-bar"&gt;&lt;/span&gt;
          &lt;/button&gt;
          &lt;a class="navbar-brand" href="index.php"&gt;Main&lt;/a&gt;
        &lt;/div&gt;
        &lt;div id="navbar" class="navbar-collapse collapse"&gt;
          &lt;ul class="nav navbar-nav"&gt;
            &lt;li class="active"&gt;&lt;a href="#"&gt;Home&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;&lt;!--/.nav-collapse --&gt;
      &lt;/div&gt;
    &lt;/nav&gt;
    &lt;!--/ Header --&gt;


    &lt;!-- Upload file --&gt;
    &lt;div class="container"&gt;
        &lt;div class="row"&gt;
            &lt;div class="col-xs-12"&gt;
                &lt;form action="" method="post" name="form" id="form" enctype="multipart/form-data"&gt;
                    &lt;div class="row"&gt;

                        &lt;div class="col-xs-12"&gt;
                            &lt;h1&gt;Upload files&lt;/h1&gt;
                        &lt;/div&gt;

                        &lt;div class="col-xs-12"&gt;
                            &lt;div class="form-group"&gt;
                                &lt;input type="file" name="image" id="image" class="form-control" multiple&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;

                        &lt;div class="col-xs-12"&gt;
                            &lt;button type="submit" name="upload" class="btn btn-primary"&gt;Upload&lt;/button&gt;
                            &lt;p id="response"&gt;&lt;/p&gt;
                        &lt;/div&gt;

                    &lt;/div&gt;
                &lt;/form&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;!--/ Upload file --&gt;


    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"&gt;&lt;/script&gt;
    &lt;script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"&gt;&lt;/script&gt;
    &lt;script src="https://cdn.rawgit.com/formvalidation/formvalidation.io/master/vendor/formvalidation/js/formValidation.min.js"&gt;&lt;/script&gt;
    &lt;script src="https://cdn.rawgit.com/formvalidation/formvalidation.io/master/vendor/formvalidation/js/framework/bootstrap.min.js"&gt;&lt;/script&gt;

    &lt;script&gt;
    $(function() {

        $('#form').formValidation({
            framework: 'bootstrap',
            excluded: ':disabled',
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
               image: {
                    validators: {
                        notEmpty: {
                            message: 'Image field required.'
                        }
                    }
                }
            }
        })
        .on('success.form.fv', function(e) {
            // Prevent form submission
            e.preventDefault();

            var $form    = $(e.target),
                fv       = $form.data('formValidation');
                formData = new FormData(),
                params   = $form.serializeArray(),
                image    = $form.find('[name="image"]')[0].files;

            $.each(image, function(i, file) {
                // Prefix the name of uploaded files with "docs-"
                // Of course, you can change it to any string
                formData.append('image[]', file);
            });

            $.each(params, function(i, val) {
                formData.append(val.name, val.value);
            });

            // Info add send post
            formData.append('id', Math.random());

            $.ajax({
                beforeSend: function () {
                    // Show modal
                    $("#modal_system").modal('show');       
                },
                url: 'ajax/1.4_ajax.php',
                type: 'POST',
                data: formData,
                cache: false,
                contentType: false,
                processData: false,
                dataType: "json",
                timeout: 120000,
                xhr: function() {
                    myXhr = $.ajaxSettings.xhr();

                    console.log('XHR: ', myXhr);

                    if (myXhr.upload) {                     
                        myXhr.upload.addEventListener('progress', function(e){

                                var loaded = e.loaded;
                                var total = e.total;
                                var percentComplete = Math.round((e.loaded / e.total) * 100);

                                // Quantity of bytes per second
                                var leftover_bytes =   total - loaded;
                                var leftover_bytes =   leftover_bytes / 1048576;
                                $('.modal-body #dataResponse').html( leftover_bytes.toFixed(2) + ' MB' );

                                // Progress bar function
                                $('.progress .progress-bar').css('width', percentComplete + '%');
                                $('.progress .progress-bar').html( percentComplete + '%');

                        }, false);
                        myXhr.upload.addEventListener('load', function(e){
                            // After upload cant reset progrees bar
                            //$('.progress .progress-bar').css('width', '0%');
                            //$('.progress .progress-bar').html( '');
                        }, false);
                    }
                    return myXhr;
                }

            }).done( function(data, textStatus, jqXHR) { // Before success

              $('p#response').html( data.message );

            }).fail( function(jqXHR, textStatus, errorThrown) { // Before error

              switch(jqXHR.status) {
                case 0:
                  $('p#response').html( 'Timeout exceeded.' );
                break;

                case 403:
                  $('p#response').html( 'The session has expired.' );
                break;

                case 404:
                  $('p#response').html( 'The requested page does not exist.' );
                break;

                default:
                  if(jqXHR.status != 200) {
                    $('p#response').html( 'Error please try again has occurred.' );
                  }
                break;
              }

              console.log(jqXHR);
              //console.log('Estatus readyState:' + jqXHR.readyState);
              //console.log('Estatus status:' + jqXHR.status);
              //console.log('Estatus statusText:' + jqXHR.statusText);
              //console.log('Estatus responseText:' + jqXHR.responseText);
              //console.log('Estatus setRequestHeader:' + jqXHR.setRequestHeader);

            });
        });

    });
    &lt;/script&gt;



&lt;!-- Modal --&gt;
&lt;div class="modal fade" id="modal_system" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"&gt;
  &lt;div class="modal-dialog" role="document"&gt;
    &lt;div class="modal-content"&gt;
      &lt;div class="modal-header"&gt;
        &lt;button type="button" class="close" data-dismiss="modal" aria-label="Close"&gt;&lt;span aria-hidden="true"&gt;&amp;times;&lt;/span&gt;&lt;/button&gt;
        &lt;h4 class="modal-title" id="myModalLabel"&gt;Example&lt;/h4&gt;
      &lt;/div&gt;
      &lt;div class="modal-body"&gt;

        &lt;div class="progress"&gt;
          &lt;div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;div&gt;&lt;strong&gt;Quantity left: &lt;/strong&gt; &lt;span id="dataResponse"&gt;&lt;/span&gt;&lt;/div&gt;

      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p><strong>PHP code:</strong></p>

<pre><code>&lt;?php 

    /**
     * Function to organize uploaded files
     */     
    function organizeArray( $arr ){
        foreach( $arr as $key =&gt; $all ){
            foreach( $all as $i =&gt; $val ){
                $new[$i][$key] = $val;    
            }    
        }
        return $new;
    }

    // Array organized
    $image = organizeArray( $_FILES['image'] );

    // Configurations
    $document_root  = $_SERVER['DOCUMENT_ROOT'];
    $directory      = "../files/";

    // Browse array
    foreach ($image as $key =&gt; $value) {
        move_uploaded_file($value['tmp_name'], $directory . '1.2 -' . date('h-i-s') . $value['name']);
    }

    $data = array(
        'response' =&gt; true,
        'message' =&gt; 'Completed'
    );
    echo json_encode($data);
?&gt;
</code></pre>

<p>¡Much appreciate your support!!</p>

<p><em>Thank you very much</em></p>