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

1 Answer 1

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)

Sign up to request clarification or add additional context in comments.

5 Comments

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.
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
I got it, thanks to your help. I updated the question to give the answer. Expect your bounty in 2 days time :-)
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.
If you are going to give great help like that, then you will be a great asset to the community :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.