<!DOCTYPE html>

<html>
  <head>
    <link rel="stylesheet" href="lib/style.css" />
    <script src="lib/script.js"></script>
  </head>

  <body ng-app="plunker" ng-cloak>
    <div ng-controller="MainCtrl">
      <h1>AngularJS file upload example {{name}}</h1>
      <form name="myForm" >
          <button  ng-click="addFile()"> + Choose file[s] to add</button>
          <button  ng-click="uploadFile()">Start upload all files</button>
          <input
                style="visibility: hidden"
                ng-model="fileSelected"
                ng-change="changeFile()"
                multiple="multiple"
                name="fileInput"
                id="fileInput"
                type="file" />
      </form>
    <h3>File list</h3>
    <ul>
      <li ng-repeat="file in fileQueue">
        {{file.name}} 
        | 
        size: {{file.size | filesize}} 
        |
        <a ng-click="downloadFile(file)" ng-href="{{url}}">[Download]</a>
        |
        <button ng-click="cancelFile(file)">Cancel</button>
        | 
        {{file.progress}}
      </li>
    </ul>

    <br/>
    </div>
  </body>
</html>
import angular from 'angular';
/**
 * Credits: 
 * filter filesize from https://gist.github.com/yrezgui/5653591#gistcomment-1226799
 * directive from: https://embed.plnkr.co/plunk/wyWwWt
 * 
 */


angular.module('plunker', [])
.directive('input', function () {
  return {
    scope: {
      ngModel: '=',
      ngChange: '&',
      type: '@'
    },
    restrict: 'E',
    link: function (scope, element, attrs) {
      if(scope.type.toLowerCase()!=='file'){
        return;
      }
      element.bind('change', function(){
        let files =  element[0].files;
        scope.ngModel = files;
        // scope.$apply();
        setTimeout(function(){ 
          scope.$apply();
          scope.ngChange();
        });
      });
    }
  };
})
.filter('filesize', function() {
  var units = [
    'bytes',
    'KB',
    'MB',
    'GB',
    'TB',
    'PB'
  ];

  return function( bytes, precision ) {
    if ( isNaN( parseFloat( bytes )) || ! isFinite( bytes ) ) {
      return '?';
    }

    var unit = 0;

    while ( bytes >= 1024 ) {
      bytes /= 1024;
      unit ++;
    }

    return bytes.toFixed( + precision ) + ' ' + units[ unit ];
  };
})
.controller('MainCtrl', function($scope, $http) {
  $scope.name = 'Plunker';
  $scope.fileSelected = {};
  $scope.fileQueue = [];
  $scope.uploadUrl = 'http://speedtest.tele2.net/upload.php';

  $scope.changeFile = function() {
    for (var i=0; i< $scope.fileSelected.length; i++) {
      let item = $scope.fileSelected[i];
      console.log(item.data);
      item.progress = 0;
      $scope.fileQueue.push(item);
    }
    setTimeout(function(){ $scope.$apply(); });
  };

  $scope.addFile = function() {
    document.getElementById('fileInput').click();
  }

  $scope.downloadFile = function(file) {
    console.log("download file ", file );
    if (!file) {
      console.log('No file to download');
    }
    var blob = new Blob([file], { type: file.type });
    var downloadLink = angular.element('<a></a>');
    downloadLink.attr('href',window.URL.createObjectURL(blob));
    downloadLink.attr('download', file.name);
    downloadLink[0].click();
  }

  $scope.cancelFile = function(file) {
    $scope.fileQueue = $scope.fileQueue.filter(function(item) { return item !== file;});
  }

  $scope.uploadFile = function() {
    for (var i=0; i< $scope.fileQueue.length; i++) {
      let item = $scope.fileQueue[i];
      item.progress = 0;
      $http({
        url: $scope.uploadUrl,
        data: item.data,
        eventHandlers: {
          readystatechange: function(event) {
            console.log(item.name, event.currentTarget.readystate);
          }
        },
        uploadEventHandlers: {
           progress: function(e) {
            if (e.lengthComputable) {
                progress = Math.round(e.loaded * 100 / e.total);
                file.progress = progress;
                console.log(file.name + "progress: " + progress + "%");
                if (e.loaded == e.total) {
                  console.log("File upload finished!");
                  console.log("Server will perform extra work now...");
                }
            }
           }
        }
      }).then(
        function(response) {
          console.log('File uploaded');
        },
        function(response) {
          console.log('Upload failed ', response);
        }
      );
    }
  }
});
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
  display: none !important;
}

h1,
p {
  font-family: sans-serif;
}
{
  "name": "@plnkr/starter-angularjs",
  "version": "1.0.1",
  "description": "AngularJS starter template",
  "dependencies": {
    "angular": "^1.6.9"
  },
  "plnkr": {
    "runtime": "system",
    "useHotReload": false
  }
}