1

I'm a little bit lost with SystemJS and NGModules (I just follow instructions and get it working).

In the case of dropzone, I've tried to add dropzone.js/css as a script in my head and added the class dropzone in my form but it doesn't work, the dropzone is not created...

Anyone can show me how to implement Dropzone in Angular 2 (final version)?

Nate
  • 7,606
  • 23
  • 72
  • 124

4 Answers4

3

Here is a little Component i wrapped Dropzone.js in:

first run

npm install --save dropzone

import { Component, AfterViewInit, EventEmitter, OnDestroy } from '@angular/core';
import { Output } from '@angular/core/src/metadata/directives';

let Dropzone = require('../../../node_modules/dropzone/dist/dropzone-amd-module');

@Component({
  selector: 'hsr-dropzone',
  templateUrl: 'dropzone.component.html',
  styleUrls: ['dropzone.component.scss']
})
export class DropzoneComponent implements AfterViewInit, OnDestroy {
  @Output() filesUploading: EventEmitter<File[]> = new EventEmitter<File[]>();
  // TODO: acceptedFiles option as input

  dropzone;

  constructor() {
  }

  get fileDropped(): boolean {
    if (this.dropzone) {
      return this.dropzone.files.length > 0;
    }
    return false;
  }

  ngAfterViewInit() {
    this.dropzone = new Dropzone('div#my_dropzone', {
      url: (files) => {
        this.filesUploading.emit(files);
      },
      autoProcessQueue: false,
      uploadMultiple: true,
      parallelUploads: 20,
      hiddenInputContainer: '#dropzone-drop-area',
      dictDefaultMessage: '',
      maxFiles: 20,
      acceptedFiles: 'image/*',
      clickable: '#dropzone-drop-area',
      previewsContainer: '#dropzone-drop-area',
      previewTemplate: `
<div class="dz-preview dz-file-preview">
  <div class="dz-details">
    <img data-dz-thumbnail/>
  </div>
</div>
`
    });
    this.dropzone.autoDiscover = false;

    this.dropzone.on('addedfile', (file) => {
      /*file.previewElement.addEventListener('click', () => {
       this.dropzone.removeFile(file);
       });*/
    });
    this.dropzone.on('completemultiple', (files) => {
      this.dropzone.removeAllFiles();
    });
    // Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
    // of the sending event because uploadMultiple is set to true.
    this.dropzone.on('sendingmultiple', () => {
      console.log('sending!!!!!!!');
    });
  }

  ngOnDestroy() {
    this.dropzone.disable();
  }

  upload() {
    this.dropzone.processQueue();
  }
}

TEMPLATE:

<div class="dropzone-container" id="my_dropzone">
  <div id="dropzone-drop-area" class="dropzone-drop-area">
    <div *ngIf="!fileDropped" class="centered noselect clickthrough">
      <ng-content></ng-content>
    </div>
  </div>
</div>

<button md-raised-button style="float: right;" *ngIf="fileDropped" (click)="upload()">
  <i class="fa fa-upload fa-lg"></i>
</button>

STYLES:

.dropzone-container {
  width: 100%;
}

.dropzone-drop-area {
  border: dashed 3px grey;
  width: 100%;
  min-height: 120px;
  box-sizing: border-box;
  padding: 6px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  cursor: pointer;
  position: relative;
  &:hover {
    color: darkorange;
    border-color: darkorange;
  }
}

I really hope that helps.

  • I'm having trouble with the event emitter stating that traceur.js and jquery are required. I also looked up usage for event emitter and what you have is not recommended: http://stackoverflow.com/questions/36076700/what-is-the-proper-use-of-an-eventemitter – Bhetzie Nov 02 '16 at 03:47
2

If you're not bound to dropzone.js I might suggest the following library to you.

I've written a highly customizable Angular component which implements the correct Drag'n'Drop behavior so I don't need to copy it over and over again. It returns a list of the dropped files as an output event.
This can be found here.

After you imported the module you have access to the component:

<ngx-dropzone [multiple]="false" [maxFileSize]="2000"></ngx-dropzone>

You have some options to set and it comes with a decent default styling (screenshots can be found in the GitHub repo). If you want to, you can even take your own div container with your custom styles and hover effects and put it in the dropzone. Details on this can be found in the API description.

<ngx-dropzone [customContent]="customDropzone" (filesDropped)="onFilesDropped($event)">
<ng-template #customDropzone>
    <div class="custom-dropzone">
        This is my custom content
    </div>
</ng-template>

Peter Freeman
  • 81
  • 1
  • 3
1

might I suggest this instead :

https://github.com/zefoy/ngx-dropzone-wrapper

let Dropzone = require is no longer deemed cannon in Angular 2+ (we're up to 5 and nearly version 6 now)

tatsu
  • 2,316
  • 7
  • 43
  • 87
1

Steps to work Dropzone with Angular 6 (angular version: 6.1.8)

1. Create angular project using angular CLI and download dropzone dist folder from dropzonejs.com site.

2. Put dropzone.css (from downloaded dist folder) in projects ../src/assets/css folder (if not exists, then create) and import it in styles.css file like following

styles.css
----------

@import "../src/assets/css/dropzone.css";

3. Put dropzone.js (from downloaded dist folder) file in projects ../src/assets/js folder (if not exists, then create) and put the following value in the scripts option of angular.json file:

angular.json
------------

    "scripts": [
        "src/assets/js/lib/dropzone.js"
    ]

4. Now, in you component ts file (for example, app.component.ts), define your Dropzone and its options like the following way:

app.component.ts
----------------

    import { Component, OnInit } from '@angular/core';

    declare var Dropzone: any;

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {

      ngOnInit(): void {

        Dropzone.options.pdfDropzone = {
          paramName: 'file',
          maxFilesize: 5, // MB
          uploadMultiple: true,
          autoProcessQueue: true,
          init: function () {
              this.on('addedfile', function (file) {
                  const removeButton = Dropzone.createElement('<button class=\'btn btn-sm btn-block\'>Remove file</button>');
                  const _this = this;
                  removeButton.addEventListener('click', function (e) {
                      e.preventDefault();
                      e.stopPropagation();
                      _this.removeFile(file);
                  });

                  file.previewElement.appendChild(removeButton);
              });
          }
      };
      }
    }

5. Now, add the following div in the html file:

app.component.html
------------------

    <div>
        <form action="http://localhost:8080/api/upload/file"
              class="dropzone dz-clickable"
              id="pdf-dropzone">
        </form>
    </div>

Action attribute of form element is the url where dropzone will upload the file.

It works for me. Cheers!!

arifng
  • 726
  • 1
  • 12
  • 22