0

How is it possible to allow only to drag and drop only file? With the normal upload button it's restricted but drag and drop does not work.

My only known workaround would be a dialog now that shows the user all his selected files and forces him to choose one of them.

CptDayDreamer
  • 1,526
  • 6
  • 25
  • 61

1 Answers1

3

in general, you has an input type file and a dragable zone see a stackblitz example

<div draggable="true" ngClass="{{dragAreaClass}}">
    <div class="row">
        <div class="col-md-12 text-center">
            Drag files here
            <a href="javascript:void(0)" (click)="file.click()">
                or click to open
            </a>
            <input type="file"
                   #file
                   [multiple]="false"
                   (change)="onFileChange($event)"
                   style="display:none" />
        </div>
        </div>
    </div>
    <div class="error" *ngIf="error">
        Only one file at time allow
    </div>

Where you defined the .css

.error {
    color: #f00;
}

.dragarea {
    font-size: 1.5rem;
    border: 3px solid #bbb;
    padding: 1.5rem;
    background-color: #fff;
    color: #bbb;
}

.droparea {
  font-size: 1.5rem;
  border: 3px dashed #bbb;
  padding: 1.5rem;
  background-color: #eff;
  color: #aaa;
}

And create a component

  error: string;
  dragAreaClass: string;
  onFileChange(event: any) {
    let files: FileList = event.target.files;
    this.saveFiles(files);
  }
  ngOnInit() {
    this.dragAreaClass = "dragarea";
  }
  @HostListener("dragover", ["$event"]) onDragOver(event: any) {
    this.dragAreaClass = "droparea";
    event.preventDefault();
  }
  @HostListener("dragenter", ["$event"]) onDragEnter(event: any) {
    this.dragAreaClass = "droparea";
    event.preventDefault();
  }
  @HostListener("dragend", ["$event"]) onDragEnd(event: any) {
    this.dragAreaClass = "dragarea";
    event.preventDefault();
  }
  @HostListener("dragleave", ["$event"]) onDragLeave(event: any) {
    this.dragAreaClass = "dragarea";
    event.preventDefault();
  }
  @HostListener("drop", ["$event"]) onDrop(event: any) {
    this.dragAreaClass = "dragarea";
    event.preventDefault();
    event.stopPropagation();
    if (event.dataTransfer.files) {
      let files: FileList = event.dataTransfer.files;
      this.saveFiles(files);
    }
  }

  saveFiles(files: FileList) {
    if (files.length > 1) this.error = "Only one file at time allow";
    else {
      this.error = "";
      console.log(files[0].size,files[0].name,files[0].type);

      ..use a sevice to upload file...
    }
  }

See that in the function saveFiles you can check the length of "files", other things that you can check is the extension, the size....

Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • I did it a bit different now but it helped me a lot. Thank you for that.Do you know why or how i change that the accept variable of the input gets ignored with drag and drop? – CptDayDreamer Nov 18 '19 at 18:38
  • Sorry, what do you want to say with "the accept variable of the input"? – Eliseo Nov 18 '19 at 20:04
  • I found out myself that I can just check it when the files are already dropped. I meant the filetype. Like I just want that the user is only able to drop/upload csv files. – CptDayDreamer Nov 18 '19 at 20:06
  • you can check the extension using `ext = files[0].name.toUpperCase().split('.').pop() || files[i].name` and compare with one array of strings, but this only check the extension of the file, the files[0].type don't help so much as this SO link say https://stackoverflow.com/questions/11832930/html-input-file-accept-attribute-file-type-csv – Eliseo Nov 18 '19 at 20:23
  • I know and I'm using this but i mean when I drag the file over the field without even dropping. But anyway I implemented what I wanted – CptDayDreamer Nov 18 '19 at 20:55
  • Thanks for the completely understandable code. It really helped @Eliseo – Panchakshari Puranmatt Feb 18 '22 at 09:31
  • I tried to drag & drop multiple files. On the first run, it works fine. On the second run, it clears out the object ('files' object). If I try to push the object on every drag & drop I'm getting an error. How can I continuously drag and drop or select multiple files and show them all on UI? – Panchakshari Puranmatt Feb 18 '22 at 12:21