1

I am happily using the file selector from solution @Snowman's answer to this question

Now, however, I want to use it in an ng-repeat loop, and am stuck.

I take the liberty of copying the solution from that question:

angular
  .module('app.services')
  .directive('fileChange', function() {
    return {
     restrict: 'A',
     scope: {
       handler: '&'
     },
     link: function (scope, element) {
      element.on('change', function (event) {
        scope.$apply(function(){
          scope.handler({files: event.target.files});
        });
      });
     }
    };
});

<input type="file" file-change handler="fileSelect(files)">

$scope.fileSelect = function(files) {
  var file = files[0];
  var reader = new FileReader();
  reader.onload = function(e) {
    console.log("on load", e.target.result);
  }
  reader.readAsText(file);
}

How do I indicate to the $scope.fileSelect() function which photo has just had its file selected?


[Update] Aargh! I just realized that I did not make the question clear enough. I need the file name, and some other data from the repeat. Let's say that I want a file name and a description of the image, entered by the user.

So, I have declared

$scope.image = {'fileName' : '',
                'description' : ''};

$scope.images = [];   // array of $scope.image

And, in the HTML, in the ng-repeat, I will have (pseudo code only)

<ng-repeat image in images>
   <input type="text" ng-model="image.description"/>
   <input type="file" file-change handler="fileSelect(files)">

It's the last <input> that I don't know how to code. Ideally, I want to pass the image object to the file-change handler function.

How can I do that?


[Final update] just in case anyone every reads this & finds it interesting.

<ng-repeat image in images>
   <input type="text" ng-model="image.description"/>
   <input type="file" file-change handler="fileSelect(image , files)">

added a image parameter, and also to $scope.fileSelect(image , files) in the controller. Note that no change was required on the directive.

Works like a charm

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551

1 Answers1

1

I tried right here with a few differences and it's working. The only thing I've changed was the controller that I added to test.

Check how I did it: (click on Run code snippet to see it in action)

angular
  .module('app.services', [])
  .controller('TestController', function($scope) {
    $scope.inputs = [1,2,3,4];
    
    $scope.fileSelect = function(files) {
      var file = files[0];
      var reader = new FileReader();
      
      reader.onload = function(e) {
        console.log("on load", e.target.result);
      }
      
      reader.readAsText(file);
    }
  })
  .directive('fileChange', function() {
    return {
     restrict: 'A',
     scope: {
       handler: '&'
     },
     link: function (scope, element) {
      element.on('change', function (event) {
        scope.$apply(function(){
          scope.handler({files: event.target.files});
        });
      });
     }
    };
});
  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Angular test</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body ng-app="app.services">

<div ng-controller="TestController as ctrl">
  <input type="file" 
         file-change 
         handler="fileSelect(files)"
         ng-repeat="input in inputs">
</div>

</body>
</html>

Just a quick note: depending on your machine, the console.log command that you are running can go pretty slow (because it's logging the content of the file)

Bruno Poeta
  • 521
  • 2
  • 9
  • It is not often that I see such a god and detailed answer from a new guy (welcome aboard), so I will award a 100 point bonus. Thanks. It certainly works just fine, so I will figure how to adapt it to my code. – Mawg says reinstate Monica Aug 30 '17 at 08:01
  • Aargh! I just realized that I did not make the question clear enough. Please see update. If it is easy, please let know; otherwise, I will post a new, clearer question. My apologies, and I will still give you the bonus in 2 days, when the system permits it – Mawg says reinstate Monica Aug 30 '17 at 08:41
  • I got it, thanks to your help. I updated the question to give the answer. Expect your bounty in 2 days time :-) – Mawg says reinstate Monica Aug 30 '17 at 12:34
  • 1
    Cool! I'm happy that I could help you, @Mawg! And thanks for the welcoming! I've been an avid reader of Stack Overflow, but I've never signed up. I thought that it would be cool to help some people here, as Stack Overflow helped me A LOT in the last years. – Bruno Poeta Aug 31 '17 at 01:40
  • If you are going to give great help like that, then you will be a great asset to the community :-) – Mawg says reinstate Monica Aug 31 '17 at 07:53