Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

support input[type=file] binding #1375

Closed
guruward opened this issue Sep 18, 2012 · 145 comments
Closed

support input[type=file] binding #1375

guruward opened this issue Sep 18, 2012 · 145 comments

Comments

@guruward
Copy link

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

@coli
Copy link

coli commented Sep 18, 2012

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)

@lgersman
Copy link

@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 !

@jgoldber
Copy link

jgoldber commented Mar 2, 2013

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...

@guruward
Copy link
Author

guruward commented Mar 2, 2013

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

Sent from my iPad

On Mar 1, 2013, at 7:16 PM, "jgoldber" <notifications@github.commailto: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//issues/1375#issuecomment-14321221.

@jgoldber
Copy link

jgoldber commented Mar 2, 2013

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

@Siyfion
Copy link

Siyfion commented Mar 13, 2013

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.

@andrewrk
Copy link

Bump. This needs to be added to a milestone.

@aravinda0
Copy link

Another shout out in support of this.

@glebm
Copy link

glebm commented Mar 29, 2013

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

@coli
Copy link

coli commented Mar 29, 2013

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

@bjconlan
Copy link

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).

@glebm
Copy link

glebm commented Mar 31, 2013

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

@jvanalst
Copy link

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.

@programmist
Copy link

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.

@neilsarkar
Copy link

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)

@cztomsik
Copy link

cztomsik commented Aug 1, 2013

'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>

@mbana
Copy link

mbana commented Aug 14, 2013

Please do fix this soon.

@ntrp
Copy link

ntrp commented Aug 14, 2013

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

@cztomsik
Copy link

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();">

@tb01923
Copy link

tb01923 commented Aug 29, 2013

+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();
}

@cztomsik
Copy link

Could you provide jsfiddle/plunker?
Thx

    1. 2013 v 18:17, tb01923 notifications@github.com:

+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.

@blaise-io
Copy link
Contributor

+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.

@edwardrf
Copy link

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

@noducks
Copy link

noducks commented Nov 15, 2013

+1

@gjlaubenstein
Copy link

+1

1 similar comment
@mattdisipio
Copy link

+1

@dciccale
Copy link

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

@grzhan
Copy link

grzhan commented Oct 1, 2015

+1

3 similar comments
@wal0x
Copy link

wal0x commented Oct 6, 2015

+1

@xujun1986
Copy link

+1

@ghadeer-rahhal
Copy link

+1

@shakhrillo
Copy link

+1000000000000000000000000

@jsanchezs
Copy link

+1

1 similar comment
@w00t3n4t0r
Copy link

+1

@santhosh77h
Copy link

@dciccale can you please provide plunker example.

@dciccale
Copy link

@lovasoa
Copy link

lovasoa commented Feb 21, 2016

+1

1 similar comment
@renanleme
Copy link

+1

@westonganger
Copy link

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

@robinswaylu
Copy link

+1

@bogomips
Copy link

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

@MadJlzz
Copy link

MadJlzz commented Apr 29, 2016

+1

1 similar comment
@nadeemkhan
Copy link

+1

@matt-catellier
Copy link

matt-catellier commented Jul 20, 2016

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

@flexchar
Copy link

flexchar commented Aug 8, 2016

+1

@NabinKhatiwada
Copy link

@ntrp @guruward @coli @lgersman @jgoldber @Siyfion
How did you fix validtion for
My Validation:
this.catalougeForm = this.catalougeFormBuilder.group({
catalougeIconName: ['',Validators.required]
});
Html:
<input type="file" accept="image/*" class="form-control" formControlName="catalougeIconName"
(change)="changeListener($event)">

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

@neha-s16
Copy link

Any updates on this?

@zios07
Copy link

zios07 commented Dec 22, 2017

Any updates ?

@petebacondarwin
Copy link
Contributor

See #1375 (comment)

@angular angular locked as resolved and limited conversation to collaborators Dec 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests