Build Status
Master Branch
Develop Branch
Overview
An Angular module for simple desktop file drag and drop with automatic file validation and dynamic style adjustment.
Dependancies
Currently built against Angular ^5.2.3 and Typescript ^2.6.2
ng2-file-drop has the following additional dependancies
- TsLerp: Typescript library for lerping single and multi-sample data sets over time
Installation
- Add the package to your 'dependencies' list in
package.json
and run npm install
"ng2-file-drop": "^5.0.0"
Optionally, you can manually install the package using the npm command line
npm install ng2-file-drop --save
- Add ng2-file-drop to both your
map
and packages
structures in systemjs.config.js
var map = {
...
'tslerp': 'node_modules/tslerp',
'ng2-file-drop': 'node_modules/ng2-file-drop'
};
var packages = {
...
'tslerp': { main: 'index.js', defaultExtension: 'js' },
'ng2-file-drop': { main: 'index.js', defaultExtension: 'js' },
};
- Optionally, add the
rootDir
option to tsconfig.json
to make sure TypeScript's default root path algorithm doesn't pull in the node_modules
folder
Usage
All the examples shown below are taken from the samples application.
Building and Running the Sample Application
Check out the repository, browse to the './samples' folder and run npm install
to install all the required dependancies.
Note: Running npm install
on the sample project requires that Python 2.7.x is available on the command line as it runs a couple of Python scripts to correctly set up the npm_modules folder.
ng2-file-drop is developed in Visual Studio Code so once npm install
has finished you should be able to open the './samples' folder in VS Code and it will run out of the box (by default it uses lite-server which is installed as part of npm install
).
If you are not using Visual Studio Code, browse to the './samples' folder and run tsc
to build the application. Then open your local server of choice pointing to ./samples as the root directory.
Importing The 'ng2-file-drop' Module
To use ng2-file-drop, you need to import the Ng2FileDropModule into the relevent module in your application. In the sample application this is done in the entry module - app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { Ng2FileDropModule } from 'ng2-file-drop';
@NgModule({
imports: [
BrowserModule,
Ng2FileDropModule,
],
bootstrap: [
AppComponent,
],
})
export class AppModule { }
Enabling File Drag
Enabling File Drag on an element is remarkably simple and can see seen in image-validation.
import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'my-custom-component',
template: `<div ng2FileDrop class="custom-component-drop-zone"></div>`
styles: [`
.custom-component-drop-zone {
width: 300px;
height: 300px;
}
`]
})
export class MyCustomComponent {
}
If you want to enable dropping multiple files are once, when defining ng2FileDrop, define ng2FileDropAcceptMultiple as an input parameter
<div ng2FileDrop ... [ng2FileDropAcceptMultiple]="true"></div>
Responding To Events
You can specify a set of callbacks that will trigger when a drag event happens, which can be seen in size-validation.
The available callbacks are
- When one or more files are initially dragged into the target space
- When one or more files are dragged out of the target space
- When a file is dropped and it is accepted by 'ng2-file-drop' (when ng2FileDropAcceptMultiple = false)
- When a file is dropped and it is rejected by 'ng2-file-drop' (when ng2FileDropAcceptMultiple = false)
- When one or more files are dropped (when ng2FileDropAcceptMultiple = true)
import { Component } from '@angular/core';
import { Ng2FileDropAcceptedFile, Ng2FileDropRejectedFile } from 'ng2-file-drop';
@Component({
moduleId: module.id,
selector: 'my-custom-component',
template: `<!-- my_custom.component.html -->
<!-- Specify the callbacks in 'MyCustomComponent' for each event -->
<div ng2FileDrop class="custom-component-drop-zone"
(ng2FileDropHoverStart)="dragFileOverStart()" (ng2FileDropHoverEnd)="dragFileOverEnd()"
(ng2FileDropFileAccepted)="dragFileAccepted($event)" (ng2FileDropFileRejected)="dragFileRejected($event)"
</div>
<div ng2FileDrop class="custom-component-drop-zone"
[ng2FileDropAcceptMultiple]="true"
(ng2FileDropHoverStart)="dragFileOverStart()" (ng2FileDropHoverEnd)="dragFileOverEnd()"
(ng2FileDropFilesDropped)="dragFilesDropped($event)"
</div>`,
styles: [`
.custom-component-drop-zone {
width: 300px;
height: 300px;
}
`]
})
export class MyCustomComponent {
private dragFileOverStart() {
}
private dragFileOverEnd() {
}
private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) {
}
private dragFileRejected(rejectedFile: Ng2FileDropRejectedFile) {
}
private dragFilesDropped(droppedFile: Ng2FileDropFilesDropped) {
}
}
Responding to a Dropped File
Regardless of whether a file is accepted or rejected, you will be provided with a File object via either Ng2FileDropRejectedFile.file or Ng2FileDropAcceptedFile.file, which can be used to load, display, upload or otherwise interact with.
This can be seen in image-validation.component.ts which takes the dropped files and displays it in the browser.
import { Component } from '@angular/core';
import { Ng2FileDropAcceptedFile } from 'ng2-file-drop';
@Component({
...
})
export class ImageValidationComponent {
...
private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) {
let fileReader = new FileReader();
fileReader.onload = () => {
this.currentProfileImage = fileReader.result;
this.imageShown = true;
};
fileReader.readAsDataURL(acceptedFile.file);
}
}
Responding to Rejected Files
When a file is rejected you can identify the reason for it being rejected in Ng2FileDropRejectedFile.rejectionReason which can take one of the following values
- Ng2FileDropRejections.None
- Ng2FileDropRejections.FileType
- Ng2FileDropRejections.FileSize
- Ng2FileDropRejections.Unknown
import { Component } from '@angular/core';
import { Ng2FileDropRejectedFile, Ng2FileDropRejections } from 'ng2-file-drop';
@Component({
...
})
export class ImageValidationComponent {
...
private dragFileRejected(rejectedFile: Ng2FileDropRejectedFile) {
if (rejectedFilerejectionReason === Ng2FileDropRejections.FileType) {
} else if (rejectedFilerejectionReason === Ng2FileDropRejections.FileSize) {
} else {
}
}
}
Responding to multiple Dropped Files
When ng2FileDropAcceptMultiple is set to true the callbacks ng2FileDropFileAccepted and ng2FileDropFileRejected will not be emitted. Instead
ng2FileDropFilesDropped will be emitted when one or many files are dropped.
import { Component } from '@angular/core';
import { Ng2FileDropFilesDropped } from 'ng2-file-drop';
@Component({
...
})
export class ImageValidationComponent {
...
private dragFilesDropped(droppedFiles: Ng2FileDropFilesDropped) {
if (droppedFiles.accepted.length > 0) {
...
}
if (droppedFiles.rejected.length > 0) {
...
}
}
}
Defining Acceptance Criteria
It is possible to define a set of criteria for the file to meet before it can be accepted, and if the file doesn't match those criteria it will be returned to the client as a 'Ng2FileDropRejectedFile'.
It is possible to define the following requirements
import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'my-custom-component',
template: `<!-- my_custom.component.html -->
<!-- Set criteria for only image types under 1MB in size-->
<div ng2FileDrop class="custom-component-drop-zone"
[ng2FileDropSupportedFileTypes]="supportedFileTypes"
[ng2FileDropMaximumSizeBytes]="maximumFileSizeInBytes"
(ng2FileDropFileAccepted)="dragFileAccepted($event)"
</div>`
styles: [`
.custom-component-drop-zone {
width: 300px;
height: 300px;
}
`]
})
export class MyCustomComponent {
private supportedFileTypes: string[] = ['image/png', 'image/jpeg', 'image/gif'];
private maximumFileSizeInBytes: number = 1e+6;
private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) {
}
}
Disabling the Default Style
By default ng2-file-drop will automatically style the drop zone, highlighting it in blue when hovering, and flashing red when a file is rejected. You can disable this behaviour as done in disable-styles.
import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'my-custom-component',
template: `<div ng2FileDrop
class="custom-component-drop-zone
[ng2FileDropDisableStyles]="true"
</div>`
styles: [`
.custom-component-drop-zone {
width: 300px;
height: 300px;
}
`]
})
export class MyCustomComponent {
}
Change Log
5.0.0
- Added support for Angular 5 (built against 5.2.3)
4.0.0
- Increased to Version 4 to match the version of Angular this build supports
1.1.0
- Added peerDependancies to the npm package to support both npm2 and npm3
1.0.0
- Added support for dropping multiple files - #25
- Updated to Angular ^4.1.3 and Typescript ^2.3.2 - #26
- Altered used of moduleId for Webpack support - #27
0.2.2
0.2.1
- Support for Angular versions 2.0.0 - 2.4.7
0.2.0
0.1.1
- Updated package requirements to Typescript ^2.0.0 plus related package upgrades
0.1.0
- Updated Angular dependancy to 2.0.0
0.0.1