0

What my code does is bring up the "Browse" window so we can select a file. There are no issues bringing up the Browse window. The issue is after I select a file, it won't call $scope.manageFileSelect. The reason why I coded it that way is because I didn't want to use the standard browse button. I'm tricking it by sending a click even on the fileInput. So for example, I clicked on file cover.jpg, and clicked Ok button, it won't show "Did I get called? Sigh! :(" on the console. However, if I select cover.jpg again, it will work. It's weird.

Here is my code:

 $scope.manageFileSelect = function(evt) {
  console.log('Did I get called? Sigh! :(');
  var file = evt.currentTarget.files[0];
  $scope.selectedFilename = file.name;
  var reader = new FileReader();
  reader.onload = function (evt) {
    $scope.$apply(function($scope) {
      $scope.myImage = evt.target.result;
      $timeout($scope.openImageToThumbnail, 1500);
    });
  };
  reader.readAsDataURL(file);
};

$scope.button = document.getElementById('fileInput');
$scope.button.addEventListener('click', function() {
  console.log('creating listener for manageFileSelect');
  $scope.input = document.createElement('input');
  $scope.input.type = 'file';
  $scope.input.addEventListener('change', $scope.manageFileSelect);
  $scope.input.click();
  console.log('input clicked');
});
devwannabe
  • 3,160
  • 8
  • 42
  • 79
  • When you use angular, is recomendable to do everithing in the "angular way"... have you tried do a directive? like this: http://stackoverflow.com/questions/17063000/ng-model-for-input-type-file – Facundo Pedrazzini Jun 23 '15 at 16:52
  • don't use addEventListener. Use `ng-click` (https://docs.angularjs.org/api/ng/directive/ngClick) on your `fileInput` button – Ronnie Jun 23 '15 at 16:54
  • I'm so sorry guys. I was partly wrong with my post above. Correcting it now. – devwannabe Jun 23 '15 at 16:59
  • @FacundoPedrazzini I'm going to try it. I hope I'll be able to give a design to the button. I'm doing it that way so I can use a custom button. – devwannabe Jun 23 '15 at 17:05
  • @Ronnie I can't use ng-click on it because I need to use a custom style on input. I'll try it though. – devwannabe Jun 23 '15 at 17:06
  • I just tried using ng-click @Ronnie and it's calling the function I assigned. However, I am unable to style the button. This is why I coded it like how I showed above. – devwannabe Jun 23 '15 at 17:12
  • why are you not able to style the button? I don't get it – Ronnie Jun 23 '15 at 17:14
  • Looks like you haven't tried it. Most browsers won't allow you to style an input type file. – devwannabe Jun 23 '15 at 17:14
  • This is the code - – devwannabe Jun 23 '15 at 17:15
  • You can do this with a directive, take a look to this jsfiddle http://jsfiddle.net/qLujq10n/ – Facundo Pedrazzini Jun 23 '15 at 17:18
  • Cool. Checking it now – devwannabe Jun 23 '15 at 17:20
  • What you want is the combination of the 2 directives I give you, I do the same in my app and works perfect ;) – Facundo Pedrazzini Jun 23 '15 at 17:20
  • something important in angular is if you want to manipulate the DOM... use a directive – Facundo Pedrazzini Jun 23 '15 at 17:22
  • I tried the directive and was able to design the button. I now combined it with the other directive for fileread found here, http://stackoverflow.com/questions/17063000/ng-model-for-input-type-file and it's working. However, I'm back to my first original issue which is selecting the same file won't read it again(last weeks issue which the code above fixes it). The change event won't fire. – devwannabe Jun 23 '15 at 17:42
  • I just saw your message above @FacundoPedrazzini and yes, that's what I did. I combined the two. However, please read my last post before this one. – devwannabe Jun 23 '15 at 17:45
  • fyi, this is the exact code I have right now in my app - https://gist.github.com/c0debreaker/571e995bc313ba12b163 – devwannabe Jun 23 '15 at 17:46

1 Answers1

1

This is the way I do when I have to select a file and storage in a javascript variable, with a full customize button: (see the fix I do to select the same file)

http://jsfiddle.net/rh63dd9w/

First you have the input element:

<button click-target="#inputFile">Select File</button>
<input type="file" fileread="file" id="inputFile" />

The directive fileread (source):

myApp.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                var reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        scope.fileread = loadEvent.target.result;
                    });
                }
                reader.readAsDataURL(changeEvent.target.files[0]);
                // Thanks to this you can select the same file
                element.val('');
            });
        }
    }
}]);

The click-target directive:

myApp.directive('clickTarget', function () {
    return {
        restrict: 'A',
        scope: {
            target: '@clickTarget'
        },
        link: function (scope, elem, attr) {
            var input = $(scope.target);
            elem.on('click', function () {
                $(input).click();
            });
        }
    };
});

and the css:

#inputFile {
    /* dont use display none because input.click() doesn't work in hiddens elements on some explorers */
    position: absolute;
    left: -300px;
}
Community
  • 1
  • 1
Facundo Pedrazzini
  • 1,486
  • 14
  • 22
  • I tried your code and I added alert('read') inside scope.$apply and it works. I added alert codes to my own code and it only got fired once. I will now take a look at your code closely and compare what I missed. Thank you. – devwannabe Jun 23 '15 at 18:23
  • I only see one difference and it's this code - element.val(''); What does this do? Update; LOL, you wrote the comment there. Awesome! – devwannabe Jun 23 '15 at 18:25
  • It's working great. Let me do more test and verify again my newest issue I mentioned above. I'll keep you posted. – devwannabe Jun 23 '15 at 18:27
  • I have a follow up question @Facundo Pedrazzini. I can see the scope variable being populated which is really nice. I need to call modal window which I was doing on my code above. It's not good if I call modal inside the directive. I also don't want to use $watch in my controller since it might not see changes if I load the same filename. What is the ideal approach? – devwannabe Jun 23 '15 at 18:40
  • I got it now, I added a key and use callFn : '&' then also called scope.callFn() in the link. – devwannabe Jun 23 '15 at 18:58