Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/components/inputfile.component.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -8,14 +8,15 @@ import { InputFileOptions } from '../utils/configuration.model';
selector: 'ngx-upload-inputfile',
template: `
<label class="input-file">
<input type="file" #file (change)="onFilesAdded()">
<input *ngIf="!folder" type="file" #file (change)="onFilesAdded()">
<input *ngIf="folder" type="file" #file (change)="onFilesAdded()" webkitDirectory>
<ng-content></ng-content>
</label>`,
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<File> = new Set();

Expand All @@ -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) {
Expand All @@ -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);
Expand Down
82 changes: 81 additions & 1 deletion src/directives/dropzone.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand Down Expand Up @@ -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)
});
});
}



}
4 changes: 4 additions & 0 deletions src/directives/inputfile.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<any>) {
}
Expand All @@ -22,6 +25,7 @@ export class NgxInputFileDirective implements OnInit {
const factory = this.resolver.resolveComponentFactory(InputfileComponent);
const component: ComponentRef<InputfileComponent> = this.vcRef.createComponent(factory, 0, this.injector, [_contentViewRef.rootNodes]);
component.instance.options = (this.ngxInputFile) ? this.ngxInputFile : ngxInputFileOptions;
component.instance.folder = this.folder;
_contentViewRef.detectChanges();
}
}
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -43,6 +44,8 @@ export function _loggerFactory(options: LoggerOptions): NgxUploadLogger {
}

@NgModule({

imports: [CommonModule],
declarations: [
...ngxDeclarations
],
Expand Down
6 changes: 3 additions & 3 deletions src/services/abstractUpload.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand All @@ -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);
Expand Down
14 changes: 14 additions & 0 deletions src/services/fileItem.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/utils/configuration.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export interface DropTargetOptions {
colorDrop: string,
accept?: MineTypeEnum[],
capture?: 'user' | 'environment',
multiple?: boolean
multiple?: boolean,
folderAccept?: boolean
}

export interface LoggerOptions {
Expand Down