52

Hi I was wondering if there was a way to preview images before I upload them using angularjs? I am using the this library. https://github.com/danialfarid/angular-file-upload

Thanks. Here is my code:

template.html

 <div ng-controller="picUploadCtr">
<form>
        <input type="text" ng-model="myModelObj">
      <input type="file" ng-file-select="onFileSelect($files)" >
 <input type="file" ng-file-select="onFileSelect($files)" multiple>

 </form>
     </div>

controller.js

  .controller('picUploadCtr', function($scope, $http,$location, userSettingsService) {

 $scope.onFileSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) {
  var $file = $files[i];
  $http.uploadFile({
    url: 'server/upload/url', //upload.php script, node.js route, or servlet uplaod url)
    data: {myObj: $scope.myModelObj},
    file: $file
  }).then(function(data, status, headers, config) {
    // file is uploaded successfully
    console.log(data);
  }); 
}
}
user1424508
  • 3,231
  • 13
  • 40
  • 66

4 Answers4

53

OdeToCode posted great service for this stuff. So with this simple directive you can easily preview and even see the progress bar:

.directive("ngFileSelect",function(){    
  return {
    link: function($scope,el){          
      el.bind("change", function(e){          
        $scope.file = (e.srcElement || e.target).files[0];
        $scope.getFile();
      });          
    }        
  }

It is working in all modern browsers!

Example: http://plnkr.co/edit/y5n16v?p=preview

Ivan Chernykh
  • 41,617
  • 13
  • 134
  • 146
  • just a side note, this (excellent) solution based on the file reader api, which does not support ie9 and early versions of ie. – danikoren Mar 09 '14 at 15:21
  • 2
    @saniko yes. but thanks god that its global usage is only 2.99% (http://caniuse.com/#feat=filereader) – Ivan Chernykh Mar 09 '14 at 15:54
  • 7
    I updated this one to work with Angular 1.3 and organized the code a bit http://plnkr.co/edit/JSuY2j?p=preview – Michael J. Calkins Oct 27 '14 at 13:51
  • This solution is very good example how people are in their sand boxes and make an answers in stackoverflow. They just provide solution that work in current situation. For example this solution does not work absolutely if I want for example put two independent file choosers in one page. – yu.pitomets Nov 06 '14 at 02:22
  • 5
    @user1315599 you are definitely invited to give here your more generic answer, or even ask your more specific question! – Ivan Chernykh Nov 06 '14 at 06:05
  • you need to use the directive angular-file-model https://github.com/ghostbar/angular-file-model – Israel Barba Jul 31 '15 at 18:08
  • 1
    @osiris355 , try Michael J. Calkins solution above – Ivan Chernykh Oct 07 '15 at 19:20
36

JavaScript

 $scope.setFile = function(element) {
  $scope.currentFile = element.files[0];
   var reader = new FileReader();

  reader.onload = function(event) {
    $scope.image_source = event.target.result
    $scope.$apply()

  }
  // when the file is read it triggers the onload event above.
  reader.readAsDataURL(element.files[0]);
}

Html

<img ng-src="{{image_source}}">
<input type="file" id="trigger" class="ng-hide" onchange="angular.element(this).scope().setFile(this)" accept="image/*">

This worked for me.

Sourabh Agrawal
  • 856
  • 10
  • 22
9

See the Image Upload Widget from the Jasney extension of Bootstrap v3

Bart
  • 5,065
  • 1
  • 35
  • 43
Kirk Strobeck
  • 17,984
  • 20
  • 75
  • 114
  • I'm actually looking for an alternative to the Jasney Extension as you don't have control over the elements of the preview and buttons. I want my preview to be displayed away from the upload button but they are all contained in the same container. That being said this is a viable option for most people and for that reason I will upvote your answer. – dotnethaggis Feb 05 '16 at 10:16
5
  // start Picture Preview    
    $scope.imageUpload = function (event) {
        var files = event.target.files;

        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            var reader = new FileReader();
            reader.onload = $scope.imageIsLoaded;
            reader.readAsDataURL(file);
        }
    }

    $scope.imageIsLoaded = function (e) {
        $scope.$apply(function () {
            $scope.img = e.target.result;            
        });
    }


<input type='file' ng-model-instant onchange="angular.element(this).scope().imageUpload(event)" />
<img class="thumb" ng-src="{{img}}" />
Sangeet Shah
  • 3,079
  • 2
  • 22
  • 25