0

Is there a way to access a file from a type="file" input in javascript?
The purpose is to send it with XHR afterwards.

Example :
<input type="file" id="myFile"/>

var file = $('#myFile');

With AngularJS :

<input type="file" file-changed/>

.directive('fileChanged', function(){
  return {
    link : function(scope, element){
        element.on('change', function(e){
           if(e.target.value != ""){
               scope.myCtrl.file = e.target;   
           }
        });
     }
  }
)

.controller('myCtrl', function(){

  var self = this;
  self.file;

  //self.file should be available here for XHR.

});

Global need :
Multiple input type files needs to be send to a REST api.
I need to keep track of the progress of each file upload, WITHOUT using an external libary.

gr3g
  • 2,866
  • 5
  • 28
  • 52
  • Maybe this helps for the first part: http://stackoverflow.com/questions/18571001/file-upload-using-angularjs (second answer) – juvian Oct 28 '15 at 17:08
  • Yes, it can be done with XHR2 and [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects) – Paolo Moretti Oct 28 '15 at 17:23

2 Answers2

2

This can be accomplished easily through FileReader

This is well supported these days http://caniuse.com/#feat=filereader

enter image description here

Here is a snippet of code from HTMLGoodies that will help you get started ::

function readSingleFile(evt) {
    //Retrieve the first (and only!) File from the FileList object
    var f = evt.target.files[0];

    if (f) {
        var r = new FileReader();
        r.onload = function(e) {
            var contents = e.target.result;
            alert("Got the file.n" + "name: " + f.name + "n" + "type: " + f.type + "n" + "size: " + f.size + " bytesn" + "starts with: " + contents.substr(1, contents.indexOf("n")));
        }
        r.readAsText(f);
    } else {
        alert("Failed to load file");
    }
}

document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
Jesse
  • 2,790
  • 1
  • 20
  • 36
  • Thank you! Any good information website to understand what is exactly happening with `type="file"` inputs in the browser? – gr3g Oct 28 '15 at 21:01
1

You can use this directive below to attach the file to some $scope variable:

HTML:

  <input type="file" file-model="myFile"/>
  <button ng-click="uploadFile()">Upload</button>

DIRECTIVE:

angular.module('yourApp').directive('fileModel', ['$parse', function ($parse) {
    "use strict";

    return {
        restrict: 'A',
        link: function (scope, element, attrs) {

            var model       = $parse(attrs.fileModel),
                modelSetter = model.assign;

            element.bind('change', function () {
                scope.$apply(function () {
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };

}]);

CONTROLLER:

 $scope.uploadFile = function () {
     var file      = $scope.myFile,
         uploadUrl = "URL://";

     fileUploadService.uploadFileToUrl(file, uploadUrl, function (err, data) {
         $scope.ret = err || data;
     });
 };
halfer
  • 19,824
  • 17
  • 99
  • 186
felipekm
  • 2,820
  • 5
  • 32
  • 42