Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File pick with Angular JS

Tags:

angularjs

I would like to pick up a file with AngularJS:

HTML:

<div ng-controller="TopMenuCtrl">
    <button class="btn" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
    <input type="file" ng-model="filepick" ng-change="pickimg()" multiple />
    <output id="list"></output> 
</div>

javascript:

angular.module('plunker', ['ui.bootstrap']);
function TopMenuCtrl($scope) {
    $scope.pickimg = function() {
        alert('a');
    };
}

How can I bind the input file onchange action on the AngularJS pickimg function? And how can i manipulate the files uploaded after?

like image 426
mcbjam Avatar asked May 19 '13 05:05

mcbjam


3 Answers

Angular doesn't yet support ng-change for input[type=file] so you have to roll onchange implementation yourself.

First, in the HTML, define Javascript for onchange as follows:

<input ng-model="photo"
       onchange="angular.element(this).scope().file_changed(this)"
       type="file" accept="image/*" />

And then in your Angular controller code, define the function:

$scope.file_changed = function(element) {

     $scope.$apply(function(scope) {
         var photofile = element.files[0];
         var reader = new FileReader();
         reader.onload = function(e) {
            // handle onload
         };
         reader.readAsDataURL(photofile);
     });
};
like image 91
Teemu Kurppa Avatar answered Oct 22 '22 08:10

Teemu Kurppa


I used above method trying to load a preview image when new file is selected, however it didnt work when I tried it like that:

$scope.file_changed = function(element, $scope) {

     $scope.$apply(function(scope) {
         var photofile = element.files[0];
         var reader = new FileReader();
         reader.onload = function(e) {
            $scope.prev_img = e.target.result;
         };
         reader.readAsDataURL(photofile);
     });
});

I digged more into it and found that the $scope.$apply should be inside the reader.onLoad otherwise changing a $scope variables wont work, so I did the following and it worked:

$scope.file_changed = function(element) {

        var photofile = element.files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
            $scope.$apply(function() {
                $scope.prev_img = e.target.result;
            });
        };
        reader.readAsDataURL(photofile);
 };
like image 17
2 revs, 2 users 70% Avatar answered Oct 22 '22 08:10

2 revs, 2 users 70%


Teemu solution will not work for IE9.

I have put together a simple angular directive with Flash polyfill for browsers not supporting HTML5 FormData, you can also listen to upload progress event.

https://github.com/danialfarid/ng-file-upload Demo: http://angular-file-upload.appspot.com/

<script src="angular.min.js"></script>
<script src="ng-file-upload.js"></script>

<div ng-controller="MyCtrl">
  <input type="text" ng-model="additionalData">
  <div ngf-select ng-model="files" >
</div>

controller:

Upload.upload({
    url: 'my/upload/url',
    data: additionalData,
    file: files
  }).then(success, error, progress); 
like image 6
danial Avatar answered Oct 22 '22 06:10

danial