diff --git a/src/components/inputfile.component.ts b/src/components/inputfile.component.ts
index d575bb2..9aae309 100644
--- a/src/components/inputfile.component.ts
+++ b/src/components/inputfile.component.ts
@@ -1,4 +1,4 @@
-import { Component, Injector, OnInit, Optional, Renderer2, ViewChild } from '@angular/core';
+import { AfterViewInit, Component, Injector, Optional, Renderer2, ViewChild } from '@angular/core';
import { FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
import { HttpClientUploadService } from '../';
import { InputFileOptions } from '../utils/configuration.model';
@@ -8,14 +8,15 @@ import { InputFileOptions } from '../utils/configuration.model';
selector: 'ngx-upload-inputfile',
template: `
`,
styles: ['input[type="file"] { display: none; } .input-file { width: 100%; }']
})
-export class InputfileComponent implements OnInit {
+export class InputfileComponent implements AfterViewInit {
- @ViewChild('file') file;
+ @ViewChild('file', {static: false}) file;
files: Set = new Set();
@@ -24,6 +25,8 @@ export class InputfileComponent implements OnInit {
private formGroup: FormGroup | null;
+ folder: boolean = false;
+
constructor(private injector: Injector, private uploader: HttpClientUploadService, private renderer: Renderer2,
@Optional() private ngForm: NgForm, @Optional() private formGroupDirective: FormGroupDirective) {
if (this.ngForm) {
@@ -39,7 +42,7 @@ export class InputfileComponent implements OnInit {
this.uploader.addToQueue(this.file.nativeElement.files, this.formGroup);
}
- ngOnInit() {
+ ngAfterViewInit() {
if (this.options.multiple !== false) this.renderer.setProperty(this.file.nativeElement, 'multiple', 'multiple');
if (this.options.accept) this.renderer.setProperty(this.file.nativeElement, 'accept', this.options.accept.join());
if (this.options.capture) this.renderer.setProperty(this.file.nativeElement, 'capture', this.options.capture);
diff --git a/src/directives/dropzone.directive.ts b/src/directives/dropzone.directive.ts
index 9526b7a..c7c9634 100644
--- a/src/directives/dropzone.directive.ts
+++ b/src/directives/dropzone.directive.ts
@@ -78,9 +78,27 @@ export class NgxDragAndDropDirective implements OnInit {
if (!transfer) {
return;
}
+ // Not support IE (folder upload)
+ if (this.dropOptions.folderAccept == true && NgxDragAndDropDirective.getVersionOfIE() == -1)
+ {
+ this.getFilesWebkitDataTransferItems(transfer.items).then(
+ (data : File[])=>{
+ this.uploader.addToQueue(data, this.formGroup, this.dropOptions);
+ }
+ )
+ }
+ else
+ {
+ var files = transfer.files;
+ var filelist: File[] = [];
+ for(var i = 0;i < files.length;i++)
+ {
+ filelist.push(files.item(i));
+ }
+ this.uploader.addToQueue(filelist, this.formGroup, this.dropOptions);
+ }
transfer.dropEffect = 'copy';
this.stopAndPrevent(event);
- this.uploader.addToQueue(transfer.files, this.formGroup, this.dropOptions);
}
@@ -119,4 +137,66 @@ export class NgxDragAndDropDirective implements OnInit {
}
}
+
+ private static getVersionOfIE() {
+ var word;
+ var agent = navigator.userAgent.toLowerCase();
+
+ // IE old version ( IE 10 or Lower )
+ if ( navigator.appName == "Microsoft Internet Explorer" ) word = "msie ";
+
+ // IE 11
+ else if ( agent.search( "trident" ) > -1 ) word = "trident/.*rv:";
+
+ // Microsoft Edge
+ else if ( agent.search( "edge/" ) > -1 ) word = "edge/";
+
+ else return -1;
+
+ var reg = new RegExp( word + "([0-9]{1,})(\\.{0,}[0-9]{0,1})" );
+ if (reg.exec( agent ) != null)
+ return parseFloat( RegExp.$1 + RegExp.$2 );
+ return -1;
+ }
+
+ private getFilesWebkitDataTransferItems(dataTransferItems) {
+ function traverseFileTreePromise(item, path='') {
+ return new Promise(
+ resolve => {
+ if (item.isFile) {
+ item.file(
+ file => {
+ file.filePath = path + file.name; //save full path
+ files.push(file);
+ resolve(file);
+ }
+ );
+ } else if (item.isDirectory) {
+ let dirReader = item.createReader();
+ dirReader.readEntries(entries => {
+ let entriesPromises = [];
+ entries.forEach(element => {
+ entriesPromises.push(traverseFileTreePromise(element, path + item.name + "/"))
+ });
+ resolve(Promise.all(entriesPromises))
+ })
+ }
+ })
+ }
+
+ let files = [];
+ return new Promise((resolve) => {
+ let entriesPromises = [];
+
+ for (let it of dataTransferItems)
+ entriesPromises.push(traverseFileTreePromise(it.webkitGetAsEntry()));
+
+ Promise.all(entriesPromises).then(entries => {
+ resolve(files)
+ });
+ });
+ }
+
+
+
}
diff --git a/src/directives/inputfile.directive.ts b/src/directives/inputfile.directive.ts
index fd0e9a4..c65ffaf 100644
--- a/src/directives/inputfile.directive.ts
+++ b/src/directives/inputfile.directive.ts
@@ -13,6 +13,9 @@ export class NgxInputFileDirective implements OnInit {
@Input()
ngxInputFile: InputFileOptions;
+ @Input()
+ folder: boolean = false;
+
constructor(private resolver: ComponentFactoryResolver, private injector: Injector,
private vcRef: ViewContainerRef, private templateRef: TemplateRef) {
}
@@ -22,6 +25,7 @@ export class NgxInputFileDirective implements OnInit {
const factory = this.resolver.resolveComponentFactory(InputfileComponent);
const component: ComponentRef = this.vcRef.createComponent(factory, 0, this.injector, [_contentViewRef.rootNodes]);
component.instance.options = (this.ngxInputFile) ? this.ngxInputFile : ngxInputFileOptions;
+ component.instance.folder = this.folder;
_contentViewRef.detectChanges();
}
}
diff --git a/src/index.ts b/src/index.ts
index 8cf7d8e..77b19c8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -15,6 +15,7 @@ import { HttpClientUploadService } from './services/httpClientUpload.service';
import { NgxThumbnailDirective } from './directives/thumbnail.directive';
import { NgxInputFileDirective } from './directives/inputfile.directive';
import { InputfileComponent } from './components/inputfile.component';
+import { CommonModule } from '@angular/common';
export { DropTargetOptions, UploadEndPoint, LoggerOptions, InputFileOptions } from './utils/configuration.model';
export { MineTypeEnum } from './utils/mimetype.model';
export { FileItem } from './services/fileItem.model';
@@ -43,6 +44,8 @@ export function _loggerFactory(options: LoggerOptions): NgxUploadLogger {
}
@NgModule({
+
+ imports: [CommonModule],
declarations: [
...ngxDeclarations
],
diff --git a/src/services/abstractUpload.service.ts b/src/services/abstractUpload.service.ts
index 8da6223..461ff99 100644
--- a/src/services/abstractUpload.service.ts
+++ b/src/services/abstractUpload.service.ts
@@ -33,7 +33,7 @@ export abstract class AbstractUploadService {
/**
* Adds files to the queue
*/
- addToQueue(files: FileList, formGroup: FormGroup | null, dropOptions?: DropTargetOptions) {
+ addToQueue(files: File[], formGroup: FormGroup | null, dropOptions?: DropTargetOptions) {
this.logger.info('add to queue');
@@ -46,8 +46,8 @@ export abstract class AbstractUploadService {
}
for (let i = 0; i < files.length; i++) {
- const file = files.item(i)!;
- this.logger.debug(files.item(i));
+ const file = files[i]!;
+ this.logger.debug(files[i]);
if (dropOptions && dropOptions.accept) {
const accepted = dropOptions.accept.some((type: string) => type === file.type);
diff --git a/src/services/fileItem.model.ts b/src/services/fileItem.model.ts
index 5a5ffdf..75b8dc7 100644
--- a/src/services/fileItem.model.ts
+++ b/src/services/fileItem.model.ts
@@ -21,6 +21,20 @@ export class FileItem {
constructor(public file: File, private uploadService: AbstractUploadService, protected logger: NgxUploadLogger) {
}
+ public get filePath() : string
+ {
+ var file : any = this.file;
+ if (file.webkitRelativePath != undefined && file.webkitRelativePath != "")
+ {
+ return file.webkitRelativePath;
+ }
+
+ if (file.filePath != undefined)
+ return file.filePath;
+
+ return file.name;
+ }
+
upload(endpoint: UploadEndPoint, options?: any) {
if (endpoint) {
this.uploadService.uploadFileItem(this, endpoint, options);
diff --git a/src/utils/configuration.model.ts b/src/utils/configuration.model.ts
index 46b48da..cc75763 100644
--- a/src/utils/configuration.model.ts
+++ b/src/utils/configuration.model.ts
@@ -13,7 +13,8 @@ export interface DropTargetOptions {
colorDrop: string,
accept?: MineTypeEnum[],
capture?: 'user' | 'environment',
- multiple?: boolean
+ multiple?: boolean,
+ folderAccept?: boolean
}
export interface LoggerOptions {