<commit_before>ng-file-upload
===================

Lightweight Angular JS directive to upload files.

**Here is the <a href="https://angular-file-upload.appspot.com/" target="_blank">DEMO</a> page**.<br/>

**Migration notes**: [version 3.0.0](https://github.com/danialfarid/ng-file-upload/releases/tag/3.0.0) [version 3.1.0](https://github.com/danialfarid/ng-file-upload/releases/tag/3.1.0) [version 3.2.0](https://github.com/danialfarid/ng-file-upload/releases/tag/3.2.3) [version 4.0.0](https://github.com/danialfarid/ng-file-upload/releases/tag/4.0.0) [version 5.0.0](https://github.com/danialfarid/ng-file-upload/releases/tag/5.0.0)

For questions, bug reports, and feature request please search through existing [issue](https://github.com/danialfarid/ng-file-upload/issues) first then open a new one  [here](https://github.com/danialfarid/ng-file-upload/issues/new). If you need support send me an [email](mailto:<EMAIL>) to set up sessions through [HackHands](https://hackhands.com/). You can also contact [me](https://github.com/danialfarid) for other concerns.
If you like this plugin give it a thumbs up at [ngmodules](http://ngmodules.org/modules/angular-file-upload) or get me a <a target="_blank" href="https://angular-file-upload.appspot.com/donate.html">cup of tea <img src="https://angular-file-upload.appspot.com/img/tea.png" width="40" height="24" title="Icon made by Freepik.com"></a>.


Table of Content:
* [Features](#features)
* [Usage](#usage)
* [Old Browsers](#old_browsers)
* [Server Side](#server) 
  * [Samples](#server) ([Java](#java), [Spring](#spring), [Node.js](#node), [Rails](#rails), [PHP](#php), [.Net](#net))
  * [Amazon S3 Upload](#s3)
  * [CORS](#cors)
* [Install](#install) ([Manual](#manual), [Bower](#bower), [Yeoman](#yeoman), [NuGet](#nuget), [npm](#npm))

##<a name="features"></a> Features
* Supports upload progress, cancel/abort upload while in progress, File drag and drop (html5), Directory drag and drop (webkit), CORS, `PUT(html5)`/`POST` methods, validation of file type and size, show preview of selected images/audio/videos.
* Cross browser file upload and FileReader (`HTML5` and `non-HTML5`) with Flash polyfill [FileAPI](https://github.com/mailru/FileAPI). Allows client side validation/modification before uploading the file
* Direct upload to db services CouchDB, imgur, etc... with file's content type using `Upload.http()`. This enables progress event for angular http `POST`/`PUT` requests.
* Seperate shim file, FileAPI files are loaded on demand for `non-HTML5` code meaning no extra load/code if you just need HTML5 support.
* Lightweight using regular `$http` to upload (with shim for non-HTML5 browsers) so all angular `$http` features are available

##<a name="usage"></a> Usage

###Sample:
[jsfiddle http://jsfiddle.net/18yao91v/](http://jsfiddle.net/18yao91v/)
```html
<script src="angular.min.js"></script>
<!-- shim is needed to support non-HTML5 FormData browsers (IE8-9)-->
<script src="ng-file-upload-shim.min.js"></script> 
<script src="ng-file-upload.min.js"></script> 

<div ng-app="fileUpload" ng-controller="MyCtrl">
    watching model:
    <div class="button" ngf-select ng-model="files">Upload using model $watch</div>
    <div class="button" ngf-select ngf-change="upload($files)">Upload on file change</div>
    Drop File:
    <div ngf-drop ng-model="files" class="drop-box" 
        ngf-drag-over-class="dragover" ngf-multiple="true" ngf-allow-dir="true"
        ngf-accept="'image/*,application/pdf'">Drop Images or PDFs files here</div>
    <div ngf-no-file-drop>File Drag/Drop is not supported for this browser</div>
    
    Image thumbnail: <img ngf-src="files[0]" ngf-default-src="'/thumb.jpg'" ngf-accept="'image/*'">
    Audio preview: <audio controls ngf-src="files[0]" ngf-accept="'audio/*'"></audio>
    Video preview: <video controls ngf-src="files[0]" ngf-accept="'video/*'"></video>
</div>
```
JS:
```js
//inject angular file upload directives and services.
var app = angular.module('fileUpload', ['ngFileUpload']);

app.controller('MyCtrl', ['$scope', 'Upload', function ($scope, Upload) {
    $scope.$watch('files', function () {
        $scope.upload($scope.files);
    });

    $scope.upload = function (files) {
        if (files && files.length) {
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                Upload.upload({
                    url: 'upload/url',
                    fields: {'username': $scope.username},
                    file: file
                }).progress(function (evt) {
                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                    console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
                }).success(function (data, status, headers, config) {
                    console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
                }).error(function (data, status, headers, config) {
                    console.log('error status: ' + status);
                })
            }
        }
    };
}]);
```

### Full reference

#### File select

```html
<button|div|input type="file"|ngf-select|...
    *ngf-select="true" or "false" // default true, enables file select directive on this element
    ng-model="myFiles" // binds the selected files to the scope model
    ng-model-rejected="rejFiles" // bind to dropped files that do not match the accept wildcard
    ng-disable="selectDisabled" // bind to a boolean value that triggers deactivation of the file select
    ngf-change="fileSelected($files, $event)" // called when files are selected or removed
    ngf-multiple="true" or "false" // default false, allows selecting multiple files
    ngf-capture="'camera'" or "'other'" // allows mobile devices to capture using camera
    accept="image/*" // see standard HTML file input accept attribute
    ngf-accept="'image/*'" or "validate($file)" // function or comma separated wildcard to filter files allowed
    ngf-min-size='10' // minimum acceptable file size in bytes
    ngf-max-size='10' // maximum acceptable file size in bytes
    ngf-keep="true" or "false" // default false, keep the previous ng-model files and append the new files
    ngf-keep-distinct="true" or "false" // default false, if ngf-keep is set, removes duplicate selected files
    ngf-reset-on-click="true" or "false" // default true, reset the model and input upon click. see note below.
    ngf-reset-model-on-click="true" or "false" // default true, reset the model upon click. see note below.
>Upload</button>
```
#### File drop
```html
All attributes are optional except ngf-drop and one of ng-model or ngf-change.
<div|button|ngf-drop|...
    *ngf-drop="true" or "false" // default true, enables file drop directive on this element 
    ng-model="myFiles" // binds the dropped files to the scope model
    ng-model-rejected="rejFiles" // bind to dropped files that do not match the accept wildcard
    ng-disable="dropDisabled" // bind to a boolean value that triggers deactivation of the file drop
    ngf-change="fileDropped($files, $event, $rejectedFiles)" //called when files being dropped
    ngf-multiple="true" or "false" // default false, allows selecting multiple files. 
    ngf-accept="'.pdf,.jpg'" or "validate($file)" // function or comma separated wildcard to filter files allowed
    ngf-allow-dir="true" or "false" // default true, allow dropping files only for Chrome webkit browser
    ngf-drag-over-class="{accept:'acceptClass', reject:'rejectClass', delay:100}" or "myDragOverClass" or
                    "calcDragOverClass($event)" 
              // drag over css class behaviour. could be a string, a function returning class name 
              // or a json object {accept: 'c1', reject: 'c2', delay:10}. default "dragover".
              // accept/reject class only works in Chrome and on the file mime type so ngf-accept
              // needs to check the file mime type for it to work.
    ngf-drop-available="dropSupported" // set the value of scope model to true or false based on file
                                  // drag&drop support for this browser
    ngf-stop-propagation="true" or "false" // default false, whether to propagate drag/drop events.
    ngf-hide-on-drop-not-available="true" or "false" // default false, hides element if file drag&drop is not supported
    ngf-min-size='10' // minimum acceptable file size in bytes
    ngf-max-size='10' // maximum acceptable file size in bytes<commit_msg>added fixed letter in 'disabled' word<commit_after>ng-file-upload
===================

Lightweight Angular JS directive to upload files.

**Here is the <a href="https://angular-file-upload.appspot.com/" target="_blank">DEMO</a> page**.<br/>

**Migration notes**: [version 3.0.0](https://github.com/danialfarid/ng-file-upload/releases/tag/3.0.0) [version 3.1.0](https://github.com/danialfarid/ng-file-upload/releases/tag/3.1.0) [version 3.2.0](https://github.com/danialfarid/ng-file-upload/releases/tag/3.2.3) [version 4.0.0](https://github.com/danialfarid/ng-file-upload/releases/tag/4.0.0) [version 5.0.0](https://github.com/danialfarid/ng-file-upload/releases/tag/5.0.0)

For questions, bug reports, and feature request please search through existing [issue](https://github.com/danialfarid/ng-file-upload/issues) first then open a new one  [here](https://github.com/danialfarid/ng-file-upload/issues/new). If you need support send me an [email](mailto:<EMAIL>) to set up sessions through [HackHands](https://hackhands.com/). You can also contact [me](https://github.com/danialfarid) for other concerns.
If you like this plugin give it a thumbs up at [ngmodules](http://ngmodules.org/modules/angular-file-upload) or get me a <a target="_blank" href="https://angular-file-upload.appspot.com/donate.html">cup of tea <img src="https://angular-file-upload.appspot.com/img/tea.png" width="40" height="24" title="Icon made by Freepik.com"></a>.


Table of Content:
* [Features](#features)
* [Usage](#usage)
* [Old Browsers](#old_browsers)
* [Server Side](#server) 
  * [Samples](#server) ([Java](#java), [Spring](#spring), [Node.js](#node), [Rails](#rails), [PHP](#php), [.Net](#net))
  * [Amazon S3 Upload](#s3)
  * [CORS](#cors)
* [Install](#install) ([Manual](#manual), [Bower](#bower), [Yeoman](#yeoman), [NuGet](#nuget), [npm](#npm))

##<a name="features"></a> Features
* Supports upload progress, cancel/abort upload while in progress, File drag and drop (html5), Directory drag and drop (webkit), CORS, `PUT(html5)`/`POST` methods, validation of file type and size, show preview of selected images/audio/videos.
* Cross browser file upload and FileReader (`HTML5` and `non-HTML5`) with Flash polyfill [FileAPI](https://github.com/mailru/FileAPI). Allows client side validation/modification before uploading the file
* Direct upload to db services CouchDB, imgur, etc... with file's content type using `Upload.http()`. This enables progress event for angular http `POST`/`PUT` requests.
* Seperate shim file, FileAPI files are loaded on demand for `non-HTML5` code meaning no extra load/code if you just need HTML5 support.
* Lightweight using regular `$http` to upload (with shim for non-HTML5 browsers) so all angular `$http` features are available

##<a name="usage"></a> Usage

###Sample:
[jsfiddle http://jsfiddle.net/18yao91v/](http://jsfiddle.net/18yao91v/)
```html
<script src="angular.min.js"></script>
<!-- shim is needed to support non-HTML5 FormData browsers (IE8-9)-->
<script src="ng-file-upload-shim.min.js"></script> 
<script src="ng-file-upload.min.js"></script> 

<div ng-app="fileUpload" ng-controller="MyCtrl">
    watching model:
    <div class="button" ngf-select ng-model="files">Upload using model $watch</div>
    <div class="button" ngf-select ngf-change="upload($files)">Upload on file change</div>
    Drop File:
    <div ngf-drop ng-model="files" class="drop-box" 
        ngf-drag-over-class="dragover" ngf-multiple="true" ngf-allow-dir="true"
        ngf-accept="'image/*,application/pdf'">Drop Images or PDFs files here</div>
    <div ngf-no-file-drop>File Drag/Drop is not supported for this browser</div>
    
    Image thumbnail: <img ngf-src="files[0]" ngf-default-src="'/thumb.jpg'" ngf-accept="'image/*'">
    Audio preview: <audio controls ngf-src="files[0]" ngf-accept="'audio/*'"></audio>
    Video preview: <video controls ngf-src="files[0]" ngf-accept="'video/*'"></video>
</div>
```
JS:
```js
//inject angular file upload directives and services.
var app = angular.module('fileUpload', ['ngFileUpload']);

app.controller('MyCtrl', ['$scope', 'Upload', function ($scope, Upload) {
    $scope.$watch('files', function () {
        $scope.upload($scope.files);
    });

    $scope.upload = function (files) {
        if (files && files.length) {
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                Upload.upload({
                    url: 'upload/url',
                    fields: {'username': $scope.username},
                    file: file
                }).progress(function (evt) {
                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                    console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
                }).success(function (data, status, headers, config) {
                    console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
                }).error(function (data, status, headers, config) {
                    console.log('error status: ' + status);
                })
            }
        }
    };
}]);
```

### Full reference

#### File select

```html
<button|div|input type="file"|ngf-select|...
    *ngf-select="true" or "false" // default true, enables file select directive on this element
    ng-model="myFiles" // binds the selected files to the scope model
    ng-model-rejected="rejFiles" // bind to dropped files that do not match the accept wildcard
    ng-disabled="selectDisabled" // bind to a boolean value that triggers deactivation of the file select
    ngf-change="fileSelected($files, $event)" // called when files are selected or removed
    ngf-multiple="true" or "false" // default false, allows selecting multiple files
    ngf-capture="'camera'" or "'other'" // allows mobile devices to capture using camera
    accept="image/*" // see standard HTML file input accept attribute
    ngf-accept="'image/*'" or "validate($file)" // function or comma separated wildcard to filter files allowed
    ngf-min-size='10' // minimum acceptable file size in bytes
    ngf-max-size='10' // maximum acceptable file size in bytes
    ngf-keep="true" or "false" // default false, keep the previous ng-model files and append the new files
    ngf-keep-distinct="true" or "false" // default false, if ngf-keep is set, removes duplicate selected files
    ngf-reset-on-click="true" or "false" // default true, reset the model and input upon click. see note below.
    ngf-reset-model-on-click="true" or "false" // default true, reset the model upon click. see note below.
>Upload</button>
```
#### File drop
```html
All attributes are optional except ngf-drop and one of ng-model or ngf-change.
<div|button|ngf-drop|...
    *ngf-drop="true" or "false" // default true, enables file drop directive on this element 
    ng-model="myFiles" // binds the dropped files to the scope model
    ng-model-rejected="rejFiles" // bind to dropped files that do not match the accept wildcard
    ng-disabled="dropDisabled" // bind to a boolean value that triggers deactivation of the file drop
    ngf-change="fileDropped($files, $event, $rejectedFiles)" //called when files being dropped
    ngf-multiple="true" or "false" // default false, allows selecting multiple files. 
    ngf-accept="'.pdf,.jpg'" or "validate($file)" // function or comma separated wildcard to filter files allowed
    ngf-allow-dir="true" or "false" // default true, allow dropping files only for Chrome webkit browser
    ngf-drag-over-class="{accept:'acceptClass', reject:'rejectClass', delay:100}" or "myDragOverClass" or
                    "calcDragOverClass($event)" 
              // drag over css class behaviour. could be a string, a function returning class name 
              // or a json object {accept: 'c1', reject: 'c2', delay:10}. default "dragover".
              // accept/reject class only works in Chrome and on the file mime type so ngf-accept
              // needs to check the file mime type for it to work.
    ngf-drop-available="dropSupported" // set the value of scope model to true or false based on file
                                  // drag&drop support for this browser
    ngf-stop-propagation="true" or "false" // default false, whether to propagate drag/drop events.
    ngf-hide-on-drop-not-available="true" or "false" // default false, hides element if file drag&drop is not supported
    ngf-min-size='10' // minimum acceptable file size in bytes
    ngf-max-size='10' // maximum acceptable file size in bytes
{'fraction_non_alphanumeric': 0.150217110667762, 'fraction_numerical': 0.009036498063607557, 'mean_word_length': 3.463855421686747, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 73, 'https://': 26, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3240069', 'n_tokens_mistral': 5264, 'n_tokens_neox': 4993, 'n_words': 1582}