Sibiraj
Sibiraj

Reputation: 4756

How to fire ng-change with fileModel || input type="file"

How to fire ng-change when there is a change with `'

I use custom file directive for this

Directive:

app.directive('ngFileModel', ['$parse', function($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.ngFileModel);
            var isMultiple = attrs.multiple;
            var modelSetter = model.assign;
            element.bind('change', function() {
                var values = [];
                angular.forEach(element[0].files, function(item) {
                    var value = {
                        // File Name 
                        name: item.name,
                        //File Size 
                        size: item.size,
                        //File URL to view 
                        url: URL.createObjectURL(item),
                        // File Input Value 
                        _file: item
                    };
                    values.push(value);
                });
                scope.$apply(function() {
                    if (isMultiple) {
                        modelSetter(scope, values);
                    } else {
                        modelSetter(scope, values[0]);
                    }
                });
            });
        }
    };
}]);

How to use ng-change with this without the use of ng-model

HTML:

 <input type="file" name="" ng-file-model="uploadThisImage" ng-change="onFileSelect($index)">

Upvotes: 0

Views: 3909

Answers (1)

georgeawg
georgeawg

Reputation: 48948

Directive to get files input with ng-model

This directive enables <input type=file> to automatically work with the ng-change and ng-form directives.

The AngularJS built-in <input> directive does not handle <input type=file>. One needs a custom directive for that.

<input type="file" files-input ng-model="fileArray"
       ng-change="onFileSelect()" multiple />

The files-input directive:

angular.module("app").directive("filesInput", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
})

The above directive adds a change listener that updates the model with the files property of the input element.

The DEMO on PLNKR


Inline Demo of files-input Directive

angular.module("app",[]);

angular.module("app").directive("filesInput", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <h1>AngularJS Input `type=file` Demo</h1>
    
    <input type="file" files-input ng-model="fileArray" multiple>
    
    <h2>Files</h2>
    <div ng-repeat="file in fileArray">
      {{file.name}}
    </div>
  </body>

Upvotes: 3

Related Questions