Looking for the [changelog](https://github.com/jwelker110/file-input-accessor/blob/master/CHANGELOG.md)?

# FileInputAccessor

Adds Reactive and Template behavior you're used to using with Angular Forms, but for `<input type="file">`. Check out the [demo](https://jwelker110.github.io/file-input-accessor/) to see it in action. 

Sample code for sending the files from Angular to your backend is [further down](#uploading-the-files) this page. 

Provides [NG_VALUE_ACCESSOR](https://angular.dev/api/forms/NG_VALUE_ACCESSOR#) implementing the [ControlValueAccessor](https://angular.dev/api/forms/ControlValueAccessor)
interface. For more info, refer to [this stack overflow answer](https://stackoverflow.com/questions/41889384/angular2-validation-for-input-type-file-wont-trigger-when-changing-the-fi/41938495#41938495)
linked on [this issue](https://github.com/angular/angular/issues/7341).

- [Which version should I use?](#which-version-should-i-use)
- [Using with your forms](#using-with-your-forms)
- [Validation](#validation)
- [Accessor Inputs](#accessor-inputs)
- [ICustomFile](#icustomfile)

## Which version should I use?

**Version 1.x.x uses [Rxjs](https://github.com/ReactiveX/rxjs/releases) v5.5.x.** Rxjs v6 underwent some changes that include adjustments to the way operators are imported along with other breaking changes. 

**Version 2.x.x uses Rxjs v6.** If you're interested in updating your projects, [a package](https://www.npmjs.com/package/rxjs-compat) has been created for that very purpose by the Rxjs team.

As a general rule:

- For Angular 4 and 5, use version 1.x.x.
- For Angular 6 use version 2.x.x.
- Angular 7 and above aligns with the Angular version, so for Angular 7, use 7.x.x, Angular 8, use 8.x.x, etc..

#### RxJS

- RxJS [docs](https://rxjs.dev/). 
- [Learn RxJS](https://www.learnrxjs.io/learn-rxjs/operators) - very helpful resource to familiarize yourself with Rxjs by providing a list of commonly used operators with examples.

## Using with your forms

1. Install package from npm 
   
   ```npm i file-input-accessor```

2. Import the FileInputAccessorModule.
    
   ```typescript
    import {BrowserModule} from '@angular/platform-browser';
    import {FileInputAccessorModule} from "file-input-accessor";

    @NgModule({
        declarations: [
            AppComponent
        ],
        imports: [
            BrowserModule,
            FileInputAccessorModule
        ],
        providers: [],
        bootstrap: [AppComponent]
    })
    export class AppModule {}
   ```

3. That's it. You can use FormControl and NgModel with your file input.

   ```angular2html
    <!--file-upload.component.html-->

    <form>
      <!--Reactive form control-->
      <input type="file" multiple [formControl]="fileControl">
    </form>

    <form>
      <!--Template form control, using model changes to trigger upload-->
      <input type="file" multiple name="templateFileUploadControl" [ngModel]="modelChangesFiles" (ngModelChange)="onFileInputChange($event)">
    </form>

    <form>
      <!--Template form control, upload is manually triggered-->
      <input type="file" multiple [(ngModel)]="manualChangesFiles" name="templateFileUploadControl2">
      <button type="button" (click)="submitFiles()">Click to upload</button>
    </form>
   ```

## Validation
An async validator is included and only runs if sync validation passes and values are provided to the accessor inputs. The following errors may be set `true` on the control if at least one file fails validation:

* fileSize - File size is too large.
* fileType - File **type** failed to match.
* fileExt - File **extension** failed to match.
* The image validation requires `withMeta` set to `true`.
    * imageWidth - Image does not meet width requirement.
    * imageHeight - Image does not meet height requirement.
    * (>= 8.1.0) maxHeight - Image is too tall.
    * (>= 8.1.0) maxWidth - Image is too wide.
    * (>= 8.1.0) minHeight - Image is not tall enough.
    * (>= 8.1.0) minWidth - Image is not wide enough

## Accessor Inputs

All inputs are optional.

* `[allowedExt]` - Used to validate each file's **extension**. Accepts the following:
    - A [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) instance.
    - A String that will be used to create a new RegExp.
    - An array of strings that will be joined into a single capture group and used to create a new RegExp.
* `[allowedTypes]` - Accepts the same as allowedExt but will be used to validate the file's **type**.
* `[size]` - Used to verify each file's size (bytes) is <= the provided value.
* `[withMeta]` - If `true`, each file will receive additional properties adhering to the ICustomFile interface. If you plan to validate maxHeight and maxWidth, `true` **is required**.
* `[maxHeight]` - The largest acceptable height, in pixels, for image files.
* `[maxWidth]` - The largest acceptable width, in pixels, for image files.
* `[minHeight]` - The smallest acceptable height, in pixels, for image files.
* `[minWidth]` - The smallest acceptable width, in pixels, for image files.

## ICustomFile

An interface implemented by the Files added to the control. All properties are 
optional and only present if `withMeta` input is set to `true`.

* If the file's **type** is image:
    - `imgSrc` - Contains a data: URL representing the file data.
    - `imgHeight` - The height of the image, in pixels.
    - `imgWidth` - The width of the image, in pixels.
    - `isImg` - `true`.
* If the file's **type** is text:
    - `textContent` - The text content of the file.
* Each file contains an `errors` property that contains an errors
object. The following errors will be set `true` if the file has 
failed that validation check.
    - fileSize - File size is too large.
    - fileType - File **type** failed to match.
    - fileExt - File **extension** failed to match.
    - imageWidth - Image does not meet width requirement.
    - imageHeight - Image does not meet height requirement.
        #### version >= 8.1.0
        - maxHeight - Image is too tall.
        - maxWidth - Image is too wide.
        - minHeight - Image is not tall enough.
        - minWidth - Image is not wide enough.
