Angular.js: support input[type=file] binding

Created on 18 Sep 2012  ·  145Comments  ·  Source: angular/angular.js

hi trying to do a simple file upload :) but the input of type=file dont seem to bind ive tried hg-model-instant but get nothing, even upgraded to 1.0.2 and nothing

forms moderate not core feature

Most helpful comment

This solution depends on filereader being implemented:

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

You then have to do some xhr stuff yourself but I believe that this is outside the gui binding and more processing logic.

and if you lack imagination:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

This works because of xhr2 (http://www.html5rocks.com/en/tutorials/file/xhr2) and please excuse the long example upload url, its a couchdb document endpoint (attachment).

All 145 comments

There is no default binding provided by angular to input type=file.

But then, file input is real-only to javascript, the only benefit such a binding could help is on clearing the fileinput. (Angular also doesn't provide framework support to ajax upload of file right now I believe)

@coli : thats not the whole truth.

It would make sense to be able to catch the onchange event on input[file].

At https://github.com/lgersman/jquery.orangevolt-ampere we have exactly that scenario : file uploads via XMLHTTPRequest V2.
Therefore we implemented our own directive to catch input[file] change events to get fileuploads done without page reloading.

I would love to see that feature in angularjs !

Has there been any progress made with binding to an input of type file? I have been searching for a solution and can't seem to find one that works...

my solution was just Ajax instead of request or http.post

Sent from my iPad

On Mar 1, 2013, at 7:16 PM, "jgoldber" <[email protected]notifications@github.com> wrote:

Has there been any progress made with binding to an input of type file? I have been searching for a solution and can't seem to find one.


Reply to this email directly or view it on GitHubhttps://github.com/angular/angular.js/issues/1375#issuecomment-14321221.

Best solution I found: http://jsfiddle.net/marcenuc/ADukg/49/. Please share if you come across a better solution.

Yeah, this really needs looking at; being able to select & upload a file is fairly crucial to most web applications, so supporting this input is a pretty obvious missing feature.

Bump. This needs to be added to a milestone.

Another shout out in support of this.

ng-model file could set value to a file from HTML5 File API, there are Flash and Silverlight polyfills for IE8/IE9

Yeah, either set the value to the file or to the input element (containing reference to the file)

This solution depends on filereader being implemented:

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

You then have to do some xhr stuff yourself but I believe that this is outside the gui binding and more processing logic.

and if you lack imagination:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

This works because of xhr2 (http://www.html5rocks.com/en/tutorials/file/xhr2) and please excuse the long example upload url, its a couchdb document endpoint (attachment).

It is possible to make this work in IE8/9 by combining this flash-based FileReader Polyfill https://github.com/Jahdrien/FileReader and this pure js FormData polyfill that relies on FileReader https://github.com/francois2metz/html5-formdata. _update_ Moxie is a better polyfill

My solution was pretty sketchy, at least as sketchy as the jsfiddle above where the controller prototype is diddled with...

In the controller:

    $scope.updateImage = '(' + function () {
      alert('moo');
    }.toString() + ')();';

Stringify my desired onchange callback and wrap it in a closure.

   <input type="file" name="image" onchange="{{updateImage}}" ng-model="image">

Insert it into the DOM using Angular

Not exactly pretty but it works in Webkit. I didn't do any cross browser testing.

I'm on 1.0.5 and it's still broken. We used Jgoldber's example and tweaked it a bit:
http://jsfiddle.net/ADukg/2589/

This example will only work for one controller, so if you have multiple controllers, each with file inputs you'll need to make some changes.

Haven't tested it on IE yet, but my guess (knowing IE) is that it won't work.

Assuming that you just want to call a function in your scope that takes the input element as an argument, this is pretty straightforward to implement in a directive:

http://jsfiddle.net/neilsarkar/vQzKJ/

(modified from the above jsfiddle, thanks @programmist)

'use strict';

function filesModelDirective(){
  return {
    controller: function($parse, $element, $attrs, $scope){
      var exp = $parse($attrs.filesModel);

      $element.on('change', function(){
        exp.assign($scope, this.files);
        $scope.$apply();
      });
    }
  };
}

configuration:

angular.module(...).directive('filesModel', filesModelDirective)

usage:

<input type="file" files-model="someObject.files" multiple>

Please do fix this soon.

Still having problems.. in some versions it works but is anyway not supported

Since 1.5.0 $digest has to be called if you're using onchange workaround:

<input type="file" onchange="angular.element(this).scope().myController.uploadFile(this.files[0]); angular.element(this).scope().$digest();">

+1 for better support on the ng-change and the input/file. Use case: as an uploader of an image, I would like to be able to edit that image (resize and crop) prior to uploading for optimal display. Implementation: browse to image (using input/file) and on the onchange event move the file to the canvas and edit with fabricjs. I can;t think of a non-on change implementation.

cztomsik - I am on 1.0.7 and I cannot get your solution to work - the scope(this) function resolves fine, but the controller cannot be found, uploadFile function is listed as a member of the scope(this).

Messing about, I have a slight modification on the technique, which seems to be working for me (i still don't know why I had the :

< input type="file" name="file" ng-model="file" onchange="invokeUploadFile(this)"/ >

var invokeUploadFile = function(that) {
angular.element(that).scope().uploadFile(that)
angular.element(that).scope().$digest();
}

Could you provide jsfiddle/plunker?
Thx


    1. 2013 v 18:17, tb01923 [email protected]:

+1 for better support on the ng-change and the input/file. Use case: as an uploader of an image, I would like to be able to edit that image (resize and crop) prior to uploading for optimal display. Implementation: browse to image (using input/file) and on the onchange event move the file to the canvas and edit with fabricjs. I can;t think of a non-on change implementation.

cztomsik - I am on 1.0.7 and I cannot get your solution to work - the scope(this) function resolves fine, but the controller cannot be found, uploadFile function is listed as a member of the scope(this) object but when I remove the controller I get

Uncaught ReferenceError: uploadFile is not defined blah.js:15
$scope.uploadFile blah.js:15
invokeScope blah.js:4
onchange


Reply to this email directly or view it on GitHub.

+1. Need it for initiating an HTML5 file upload when a user picks a file. It's easy to work around, but I'd expect this to work.

+1. please implement, not implementing it is totally not intuitive.

+1

+1

Come on guys.. it's been more than a year and angular 1.2.0 stil doesn't have input file bindings... I don't understand why the feature is not being added? There have been some good solutions to the implementation. I would like an angular team member response on the issue please.

Just to cite one of the best solutions (I know it's one way data binding but still better than nothing, validation and model update works even in IE7):

Definition

  /**
   * @ngdoc inputType
   * @name angular.module.ng.$compileProvider.directive.input.file
   *
   * @description
   * HTML file input field.
   *
   * @param {string} ngModel Assignable angular expression to data-bind to.
   * @param {string} multiple Allows multiple files selection.
   * @param {string=} name Property name of the form under which the 
                                control is published.
   *
   * @example
      <doc:example>
        <doc:source>
         <script>
           function Ctrl($scope) {
           }
         </script>
         <form name="myForm" ng-controller="Ctrl">
           file: <input type="file" ng-model="file"> single file selection.<br/>
           files: <input type="file" ng-model="files" multiple> multi-file selection.<br/>
           <tt>file.name = {{file.name}}</tt><br/>
           <tt>files.length = {{files.length}}</tt><br/>
          </form>
        </doc:source>
        <doc:scenario>
          it('should change state', function() {
            expect(binding('file.name')).toBeUndefined();

            input('file').select('a file name');
            expect(binding('file.name')).toEqual('a file name');
          });
        </doc:scenario>
      </doc:example>
   */
  'file': fileInputType,

Function

function fileInputType(scope, element, attr, ctrl) {
  element.bind('change', function() {
    scope.$apply(function() {
      var files = element[0].files,
          isValid = true;

      if (msie < 10) {
        files = [element[0].value];
      }

      if (attr.accept) {
        var i, j, acceptType, fileType,
            types = map(attr.accept.split(','), function(t) { return trim(t).split('/'); });
        for (i = 0; i < files.length && isValid; ++i) {
          fileType = files[i].type.split('/');
          isValid = false;
          for (j = 0; j < types.length && !isValid; ++j) {
            acceptType = types[j];
            isValid = acceptType[0] === fileType[0] && (acceptType[1] === '*' || acceptType[1] === fileType[1]);
          }
        }
      }
      ctrl.$setValidity('file', isValid);

      var viewValue;
      if (isValid) viewValue = attr.multiple ? files : files[0];
      ctrl.$setViewValue(viewValue);
    });
  });
}

+1

+1

@ntrp Why don't you PR this change?

That change needs to be elaborated a bit and tested, I have no time at the moment to do so.

+1

+1

-1:trollface:

Kidding +1

+1

+1

+1

+1

+1

input[type=file] is not really a 2-way binding thing, unless we explicitly use the File API, which is not available on all target browsers. Adding this to ng-model does not make a lot of sense, but there are plenty of plugins supporting some variation of this functionality. Are we not okay to just delegate this to plugins for a while?

http://caniuse.com/fileapi

@caitp Right, but it does make sense to be able to bind to the change event, via ng-change, which does not work.

Another thing that doesn't work is form validation. I think file support should be implemented for new browsers with oneway databinding fallback for old ones. If this solution is not viable then, in my opinion, it should be clearly stated on the wiki why the functionality isn't implemented and how to solve the problems that this lack of support causes. I remember loosing a lot of time before solving my input file needs when I first used them.

The thing is, filenames aren't bound to a model, and it wouldn't really make sense to bind them to a model. Every property of the File interface is readonly, and the FileList interface is only a collection of Files. There is no capacity for 2-way binding, so there is no real reason to use ng-model for these in the first place. It's simple enough to bind to the change event instead, and you can easily write a directive to add that functionality so that you can use it declaratively if you need it.

But how does it make sense to make this a part of ng-model when it does not have the capacity to follow the ng-model behaviour?

There's no reason one can't create a custom interface for files, and angular may do this at some point, but it doesn't really make sense with ng-model in my opinion. I don't know what the other developers think about this, they may agree or they may not. But from my perspective, a separate directive would make more sense, because input[type=file] just does not fit into ng-model

  • Nothing about the value of a file input is writable from a script context
  • We have no real way of performing validation here without the File API (which is not supported in several target browsers), the browser does this for us, essentially. --- with the exception of ngRequired validation

The only thing we could really do for input[type=file] is $setViewValue when the value changes (which doesn't really make sense), and somehow change ngModel to ignore changes to the model value caused by a script change (or basically just disable the $watch entirely). As for validation, all we can really support is ng-required, I mean what else can we do there?

I'd like to be able to support a file input with ngModel too, but I don't see how it would work, it just doesn't fit into the ngModel interface.

I agree with this statement but then, as I said before, we need more emphasis on this in the wiki or generally in the documentation so developers know what they need to do in order to achieve the functionality they need.

@ntrp well docs patches are more than welcome, and I'll be happy to review if you submit one :)

Can adding a specific directive in angular itself be a solution?

I agree to the previous statement, but seems at least a bit strange that a
framework like angular does not have a clear and clean way to achieve
this...
This probably was the most disorienting thing I had to face when trying to
upload a file...

Ah ok @caitp, I read some time ago that wiki pull request wasn't really being actively evalutated so I didn't bothered contributing. If I get some free time soon I will gladly contribute then :) thanks.

I didn't realize that the ngChange directive required ngModel to be present as well, which I guess is why there is so much discussion of ngModel here (and which is why I get this error). I agree that 2-way binding on an input[type=file] does not make sense.

But what is the exact reason that ngModel is required by ngChange? In my mind, it makes total sense to be able to bind to the change event of an input[type=file] field, say if you wanted to autosubmit the form once a file is chosen. In such a case, I don't really care what the value of the field is. I only care that it changed. The best way I have found to handle such a thing is through the workaround above mentioned by @cztomsik :

onchange="angular.element(this).scope().fileChangedHandler()"

And that doesn't really feel like the best solution.

ng-change, despite being named similarly to the other event handler directives, is not actually a handler for the change event. It just adds a $viewChangeListener to the ngModelController, which gets triggered whenever $setViewValue is called.

I agree it is an unfortunate name

This is a dupe of #1236 which was closed with this comment: https://github.com/angular/angular.js/issues/1236#issuecomment-29115377

unless we see a proposal on how to implement this so that it's lightweight, yet functional and doesn't require force a ux style onto framewok users, we'll consider it. But right now, we think that file upload issues is complex enough that it warrants to be solved as a seoarate module, likely outside of the core.

+1

@IgorMinar take a look here, a bit dirty, but very interesting example of implementation: https://github.com/danialfarid/angular-file-upload. @danialfarid is making great progress with this.

Check how it is a problem for all, several issues opened with several comments. You must provide an ngUpload module for us :smile:. Maybe you can provide an html5 implementation and append examples of use with https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills#file-api to http://docs.angularjs.org/guide/ie.

How are you thinking to solve?

+1

+1

+1

+1

+1

+1

+1

+1

Wow, it's a bit embarrassing at this stage.

+1

It's not really possible to have 2-way bindings for file inputs, certainly when target browsers don't all support the File API (http://caniuse.com/fileapi) --- But even when they can, input[type=file] doesn't really fit into that anyways. 2-way binding there is really impossible

I'm sorry but this is morre of a problem/security feature of the web platform than anything else. If it were doable, it would be done

@caitp I totally get what you are saying but "this is morre of a problem/security feature of the web platform than anything else" is a bit of a ridiculous statement. The point of frameworks are to facilitate the shortcomings of browsers, web spec, and various inconsistencies. This is certainly one place where a caveat for fileAPI is adequate. There are solutions now, why not fold them in?

Something as simple as a wrapper for this for example would be a start.

Given the direction that Angular 2.0 is headed (transpiling angular-only, non-ECMA idioms), I don't think the limitations of the "web platform" should be a concern.

@everyone else: What's Ember do in this case?

Edit: removing "required" from transpiling statement.

_Just a quick clarification._ Building Angular 2.0 apps does not require a transpiled language or non-ECMA idioms. You can use plain ES5 code just fine. If you want to build the Angular 2.0 source, then you need to use traceur to compile. Naturally, you can use traceur to build your own apps and take advantage of the same features we are using inside Angular, but that is entirely optional. Sorry if there has been some confusion on that point in our announcements.

@EisenbergEffect My bad. I knew that and should have proofread better. No coffee!

Frameworks can't really get around the limitations of the web platform. Like, we can't force the browser to let us write to readonly IDL attributes (which really breaks 2-way binding for files), and we can't force the browser to expose the filesystem to us, which really prevents us from doing anything interesting with it

@caitp I've been following this issue for some time now. I think there appears to be enough community desire for Angular to support a simple file selection input. Presently (unless I am mistaken), building a trivial app that accepts a file and uploads it via XHR using Angular has no recommended pattern to follow? That sounds like a feature that deserves at least some attention other than, "sorry can't do it because two-way binding doesn't make sense here."

Perhaps we can reorient this conversation to, "How could angular support this?" instead of, "It won't fit into our current patterns."

Binding to file input is definitely possible, I've done it at a previous project for AngularJS in fact.

The fact that you can't two-way bind with file inputs is a security feature, and that makes sense. Authors will never be able to set the file path via script, but why not just one-way bind it?

Sure it breaks the paradigm, but who really cares if it means you get an ng-change and ability to access files via file API without hacks? jQuery can bind to a change event on file inputs, is the Angular way so sacred that we can't just bind it within a controller? Is it a technical limitation with the architecture or just an ideological barrier?

Agreed, I was less concerned with 2 way binding. I simply wanted to post the file with the rest of my document without jumping through hoops.

On May 20, 2014, at 7:53 AM, Justin Arruda <[email protected]notifications@github.com> wrote:

@caitphttps://github.com/caitp I've been following this issue for some time now. I think there appears to be enough community desire for Angular to support a simple file selection input. Presently (unless I am mistaken), building a trivial app that accepts a file and uploads it via XHR using Angular has no official pattern to follow? Does that not sound like a feature that deserves at least some attention other than, "sorry can't do it because two-way binding doesn't make sense here."

Perhaps we can reorient this conversation to, "How could angular support this?" instead of, "It won't fit into our current patterns."


Reply to this email directly or view it on GitHubhttps://github.com/angular/angular.js/issues/1375#issuecomment-43636326.

Then you have one case where ng-model behaves wildly differently for one particular form control, and then you have people filing bugs like "how come the form control sends the wrong file when I change the value to "foobarblah.txt" or whatever. Inconsistent API -> bad.

ngModel isn't totally ideal for this stuff specifically because it means we have a specific pattern to fit into, and it's very difficult for application authors to turn off. There are solutions for this in angular.dart and the v2.0.0 prototype, though, so this will be better in the future. But we really can't add another ng-model behaviour which ignores everything ng-model currently does, it wouldn't make sense

accepts a file and uploads it via XHR using Angular

@guruward we can't support this on all of our target browsers for 1.x without forcing people to use shockwave polyfills or similar. There are third party modules which do allow this, and they can be used instead. angular-file-upload ships the shockwave polyfill and html5 native versions simultaneously, and picks the right one. So it's not a bad solution, strongly recommended if you want to do this.

But I'm not sure it's something we can put in core, you'd have to ask Igor what he thinks of shipping a shockwave polyfill in core.

I'm not saying it's a use case that people will never want to do, I can understand wanting to do this, I'm simply saying it does not fit into the ngModel pattern, and requires us to add some extra cruft in order to support all target browsers, so it breaks the framework that way.

What's the harm in using third party modules for this?

This polyfill doesn't require flash.

@jreading that's not a polyfill, and it used to ship with a flash uploader, it probably still has it somewhere.

What it's doing is relying on the File API, which is not available in all target browsers, and is therefore problematic for angular 1.x core.

Without that API, you have no way of getting at the file blob without something like shockwave.

It uses iframes instead of flash, you may be thinking of this. Instead of arguing semantics, how about a roadmap? Let's start with ng-change on file input for file api capable browsers.

@jreading unfortunately this doesn't help browsers which are not api capable, which includes IE9, which is still supported. We can't ship an API which works on supported browser A but not supported browser B in core without any work around for people who depend on IE9 support. And no, an iframe does not expose the contents of a file as a blob and make it uploadable. Hnnggggg.

There are solutions for this in third-party modules, which applications can use if they feel they're suitable. Putting this in core A) gives those third-party modules a harder time, and B) fails to support all target browsers, so this is a problem.

This is just my opinion, maybe Igor or someone else will disagree, but I don't think it's the right approach here.

What is the harm in using third party modules if they work for you, and you need them?

Never really implied that a blob needed to be available to the controller. I'm going out on a limb, but the biggest use case I see is the ability to know when the file input has changed and the ability to send it to a rest endpoint, which is available with this iframe solution or file API and angular hacks.

3rd party modules are the only way or aggressive enhancements like my blog post (no upload for you!!), but I could just turn around the question and ask "what is harm in having a better api for modern browsers?"

"what is harm in having a better api for modern browsers?"

This argument is weak because it doesn't take into account opportunity cost; there are plenty of other things for us (the core team) to work on.

Fair enough. Just feels like a huge gap and low hanging fruit.

The issue here is not about how to make this work with ngModel. I think ngModel could expose the FileList from the input field onto the scope, but in the other direction, we'd allow only setting the model to null/undefined to be supported. parsers/formatters would likely not do anything and validators would just do simple stuff like check for file presence or absence.

The issue is (as was mentioned before) that without the file api support doing this properly is unfeasible for the core given our baseline being IE9 and polyfilling this stuff is out of the question for core.

Additionally trying to handle this input in a way that is not cross-browser compatible only makes it harder for 3rd party solutions, which now have to fight/disable/workaround the core solution.

non-core solutions that handle this already exist and they were mentioned in this issue discussion as well as in the previous issue

There are many other things that have a bigger impact that we want to get done. I understand that this is a relatively common case, but I still haven't heard why the existing solutions are not sufficient?

Could some of the energy being put into this discussion be redirected into improving existing solutions if they need it, or creating a new solution that is superior to the existing ones?

I'm going to close this just as we closed #1236. Angular 2 is being build to support modern browsers and with that file support will easily available.

I simply want to know when the change event happens so I can access the element directly and grab the file info and upload via AJAJ.

@bjoshuanoah then what do you need ngModel for? Just bind an event listener to the input =p

@caitp I want to control everything in the controller and not with a directive.

If I put ng-change="uploadFile({$event: $event})"

I can have $scope.uploadFile(event) in my controller. and handle it there.

My specific use case is this: upload file to s3, apply the url to my model.

instead I have to break into the scope to do the same thing. Very annoying:

<input name="highRes" scope="{{contentOptions.currentValue}}" key="value" type="file" onchange="angular.element(this).scope().setFile(this)">

I wish someone would kill this issue. so we can all move on :)

On Jul 25, 2014, at 9:22 AM, Brian <[email protected]notifications@github.com> wrote:

I simply want to know when the change event happens so I can access the element directly and grab the file info and upload via AJAJ.


Reply to this email directly or view it on GitHubhttps://github.com/angular/angular.js/issues/1375#issuecomment-50171714.

+1

+1

+1000000000000000

+1

+1

+1

+1

+100500

+1
I'm not sure why Ajax is an issue. One may want to load data from a csv file on the local machine into an Angular model. If ng-change worked in file input within Angular this would be easy, currently it is not. This scenario does not require Ajax or a server API at all. I'm also not sure why this is closed?

My current workaround is to do the following

 input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

and in my controller just have something like

$scope.onFileSet = function(files) { 
// work your magic here 
}

Pretty much stinks tho, I feel like I am bastardizing angular as a tool. Any insight into how to do this in a more angular way would be very much appreciated.

:heart: :heart:

Here's a sailboat: :sailboat:

@samccone Isn't scope() unavailable when debug mode is switched off ?

@geetsce That is correct (in 1.3.x and later)

welp, in 1.2 land all is well.

@Narretz do you have a better solution tho?

This works for me, it is inspired by https://jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop

<input type="file" multiple="multiple" data-dbinf-on-files-selected="chooseAFunctionName(selectedFileList)">
<script>
/**Directive to propagate selected files from an HTML input element with type="file"
 * to the surrounding AngularJS controller.
 */
myApp.directive('dbinfOnFilesSelected', [function() {
    return {
        restrict: 'A',
        scope: {
              //attribute data-dbinf-on-files-selected (normalized to dbinfOnFilesSelected) identifies the action
              //to take when file(s) are selected. The '&' says to  execute the expression for attribute
              //data-dbinf-on-files-selected in the context of the parent scope. Note though that this '&'
              //concerns visibility of the properties and functions of the parent scope, it does not
              //fire the parent scope's $digest (dirty checking): use $scope.$apply() to update views
              //(calling scope.$apply() here in the directive had no visible effect for me).
            dbinfOnFilesSelected: '&'
        },
        link: function(scope, element, attr, ctrl) {
            element.bind("change", function()
            {  //match the selected files to the name 'selectedFileList', and
               //execute the code in the data-dbinf-on-files-selected attribute
             scope.dbinfOnFilesSelected({selectedFileList : element[0].files});
            });
        }
    }
}]);

myApp.controller('myController', ['$scope', function($scope) {
    $scope.chooseAFunctionName = function (filelist) {
        for (var i = 0; i < filelist.length; ++i) {
            var file = filelist.item(i);
            //do something with file; remember to call $scope.$apply() to trigger $digest (dirty checking)
            alert(file.name);
           }
    };
}]);
</script>

+1

+1

It will not happen... Let it go, let it go...

+1

As @samccone said,

input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

This is not the Angular way of doing things. It's odd.

+1

+1

+1

hey @caitp @Narretz if you guys would like I can work up a PR for this for the 1.2x branch, let me know if this is something that you want to add or not. I understand the security concerns and lack of cross browser support as far as gaining access to the actual file object goes, however it seems like basic support for detecting when a file input has changed (passing in the original event) would provide enough of a hook for people to work their magic.

Thanks again for all you do :palm_tree:

+1

+1

+1

+1

+1

ng-file-upload is working great.

+1 for @neokyol!! It does work great!

this common feature must be by default in framework

helpful

+1

+1

+1

+1

+1

this worked for me, may help

angular.module('app', [])
  .controller('MainCtrl', MainCtrl)
  .directive('fileChange', fileChange);

  function MainCtrl($scope) {
    $scope.upload = function () {
      // do something with the file
      alert($scope.file.name);
    };
  }

  function fileChange() {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: {
        fileChange: '&'
      },
      link: function link(scope, element, attrs, ctrl) {
        element.on('change', onChange);

        scope.$on('destroy', function () {
          element.off('change', onChange);
        });

        function onChange() {
          ctrl.$setViewValue(element[0].files[0]);
          scope.fileChange();
        }
      }
    };
  }
<div ng-app="app" ng-controller="MainCtrl">
  <input type="file" file-change="upload()" ng-model="file">
</div>

http://plnkr.co/edit/JYX3Pcq18gH3ol5XSizw?p=preview

+1

+1

+1

+1

+1000000000000000000000000

+1

+1

@dciccale can you please provide plunker example.

+1

+1

+1 There should be a directive built into the core library for this. Its pretty ridiculous

+1

+1
is the feature scheduled for one of the next releases?

+1

+1

How to this in projects where $scope is never being injected into the controller. I am using laravel angular which uses GULP and ES6 way of declaring controllers.

i.e.

class TestController{
    constructor(API){
        'ngInject';
        this.API = API
    }

    $onInit(){
        this.file = null;
    }
    upload() {
        console.log(this.file)
    }
    fileChanged(elm) {
        console.log('hey')
        this.file = elm.file;
        this.$apply();
    }
}

export const TestComponent = {
    templateUrl: './views/app/components/test/test.component.html',
    controller: TestController,
    controllerAs: 'vm',
    bindings: {}
}

I found a work around I believe. http://stackoverflow.com/questions/38449126/how-to-set-up-ng-file-upload-in-laravel-angular-project/38486379#38486379

+1

@ntrp @guruward @coli @lgersman @jgoldber @Siyfion
How did you fix validtion for
My Validation:
this.catalougeForm = this.catalougeFormBuilder.group({
catalougeIconName: ['',Validators.required]
});
Html:
(change)="changeListener($event)">

My validator is considering catalougeIconName value as empty/null after i upload.
Image is being sent ,but validator is not working

Any updates on this?

Any updates ?

Was this page helpful?
0 / 5 - 0 ratings