Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying DropZone bootstrap example under React JS

I am trying to apply Dropzone bootstrap example under ReactJS as shown in the code below.

But for some reason, the Start Upload / Cancel Upload and progress bars are behaving in an inconsistent way.

Example 1: Progress bar shows endless progress even if I cancelled all files to be uploaded. Example 2: Start upload single file won't do anything.

Can someone please tell me what I am doing wrong/missing here and how can I make this work just like the example?

Note: Based on first reply if possible using Refs

import React from 'react';
import { connect } from 'react-redux';

@connect((state) => state)
export default class DZUploader extends React.Component {

  componentDidMount() {

  let previewNode = document.querySelector("#template");
  previewNode.id = "";

  let previewTemplate = previewNode.parentNode.innerHTML;
  previewNode.parentNode.removeChild(previewNode);

  let myDropzone = new Dropzone(document.body, {
    url: "/target-url", // Set the url
    paramName: "file", // The name that will be used to transfer the file
    maxFilesize: 2, // MB
    thumbnailWidth: 80,
    thumbnailHeight: 80,
    parallelUploads: 20,
    previewTemplate: previewTemplate,
    autoQueue: false,
    previewsContainer: "#previews",
    clickable: ".fileinput-button",
  });

  myDropzone.on('addedfile', function(file){
    console.log(file);
    file.previewElement.querySelector(".start").onclick = function() { myDropzone.enqueueFile(file); };
  });

  myDropzone.on('totaluploadprogress', function(progress){
    console.log(progress);
    document.querySelector("#total-progress .progress-bar").style.width = progress + "%";
  });

  myDropzone.on('sending', function(file){
    // Show the total progress bar when upload starts
    document.querySelector("#total-progress").style.opacity = "1";
    // And disable the start button
    file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
  });

  myDropzone.on('queuecomplete', function(progress){
    document.querySelector("#total-progress").style.opacity = "0";
  });

  document.querySelector("#actions .start").onclick = function() {
    myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
  };
  document.querySelector("#actions .cancel").onclick = function() {
    myDropzone.removeAllFiles(true);
  };


  }

  render() {
    return (
      <div>

          <div id="actions" className="row">

              <div className="col-lg-7">
                <span className="btn btn-success fileinput-button dz-clickable">
                    <i className="glyphicon glyphicon-plus"></i>
                    <span>Add files...</span>
                </span>
                <button type="submit" className="btn btn-primary start">
                    <i className="glyphicon glyphicon-upload"></i>
                    <span>Start upload</span>
                </button>
                <button type="reset" className="btn btn-warning cancel">
                    <i className="glyphicon glyphicon-ban-circle"></i>
                    <span>Cancel upload</span>
                </button>
              </div>
              <div className="col-lg-5">
                <span className="fileupload-process">
                  <div id="total-progress" className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
                    <div className="progress-bar progress-bar-success" data-dz-uploadprogress=""></div>
                  </div>
                </span>
              </div>

          </div>

          <div className="table table-striped" className="files" id="previews">
            <div id="template" className="file-row">
              <div>
                  <span className="preview"><img data-dz-thumbnail /></span>
              </div>
              <div>
                  <p className="name" data-dz-name></p>
                  <strong className="error text-danger" data-dz-errormessage></strong>
              </div>
              <div>
                  <p className="size" data-dz-size></p>
                  <div className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
                    <div className="progress-bar progress-bar-success" data-dz-uploadprogress></div>
                  </div>
              </div>
              <div>
                <button className="btn btn-primary start">
                    <i className="glyphicon glyphicon-upload"></i>
                    <span>Start</span>
                </button>
                <button data-dz-remove className="btn btn-warning cancel">
                    <i className="glyphicon glyphicon-ban-circle"></i>
                    <span>Cancel</span>
                </button>
                <button data-dz-remove className="btn btn-danger delete">
                  <i className="glyphicon glyphicon-trash"></i>
                  <span>Delete</span>
                </button>
              </div>
            </div>
          </div>

      </div>
    );
  }
}
like image 900
MChan Avatar asked Feb 02 '17 14:02

MChan


1 Answers

3 things:

  1. By using componentDidMount lifecycle method doesn't mean that both $(JQuery) and dropzone are already loaded in the DOM

  2. Use React Refs instead of selectors so your components are consistent

  3. You should import the dropzone object with the import key and avoid the jquery dependency (import dropzone from 'dropzone').

Conclusion:

Avoid using Jquery when you don't need it, at least in this case.

As a conclusion to my suggestions your component should look like this:

import React from 'react';
import { connect } from 'react-redux';
import Dropzone from 'dropzone';

@connect((state) => state)
export default class DZUploader extends React.Component {

  constructor(props) {
    super(props);

    this.focus = this.focus.bind(this);
    this.onAddedfile = this.onAddedfile.bind(this);
    this.onTotaluploadprogress = this.onTotaluploadprogress.bind(this);
    this.onSending = this.onSending.bind(this);
    this.onQueuecomplete = this.onQueuecomplete.bind(this);
    this.onActionStartClick = this.onActionStartClick.bind(this);
    this.onActionCancelClick = this.onActionCancelClick.bind(this);
  }

  componentDidMount() {
    const previewNode = this.divTemplate;
    previewNode.id = "";

    const previewTemplate = previewNode.parentNode.innerHTML;
    previewNode.parentNode.removeChild(previewNode);

    const myDropzone = new Dropzone(document.body, {
      url: "/target-url", // Set the url
      paramName: "file", // The name that will be used to transfer the file
      maxFilesize: 2, // MB
      thumbnailWidth: 80,
      thumbnailHeight: 80,
      parallelUploads: 20,
      previewTemplate: previewTemplate,
      autoQueue: false,
      previewsContainer: "#previews",
      clickable: ".fileinput-button",
    });

    myDropzone.on('addedfile', onAddedfile);
    myDropzone.on('totaluploadprogress', onTotaluploadprogress);
    myDropzone.on('sending', onSending);
    myDropzone.on('queuecomplete', onQueuecomplete);

    this.actionStart.onclick = onActionStartClick;
    this.actionStart.onclick = onActionCancelClick;
  }

  onAddedfile(file) {
    console.log(file);
    file.previewElement.querySelector(".start").onclick = function() { myDropzone.enqueueFile(file); };
  }

  onTotaluploadprogress(progress) {
    console.log(progress);
    this.progressBar.style.width = progress + "%";
  }

  onSending(file) {
    // Show the total progress bar when upload starts
    this.totalProgress.style.opacity = "1";
    // And disable the start button
    file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
  }

  onQueuecomplete(progress) {
    this.totalProgress.style.opacity = "0";
  }

  onActionStartClick() {
    myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
  }

  onActionCancelClick() {
    myDropzone.removeAllFiles(true);
  }
  render() {
    return (
      <div>

          <div id="actions" className="row">

              <div className="col-lg-7">
                <span className="btn btn-success fileinput-button dz-clickable">
                    <i className="glyphicon glyphicon-plus"></i>
                    <span>Add files...</span>
                </span>
                <button type="submit" className="btn btn-primary start" ref={(button) => { this.actionStart = button; }}>
                    <i className="glyphicon glyphicon-upload"></i>
                    <span>Start upload</span>
                </button>
                <button type="reset" className="btn btn-warning cancel" ref={(button) => { this.actionCancel = button; }}>
                    <i className="glyphicon glyphicon-ban-circle"></i>
                    <span>Cancel upload</span>
                </button>
              </div>
              <div className="col-lg-5">
                <span className="fileupload-process">
                  <div id="total-progress" ref={(div) => { this.totalProgress = div; }} className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
                    <div className="progress-bar progress-bar-success" ref={(div) => { this.progressBar = div; }} data-dz-uploadprogress=""></div>
                  </div>
                </span>
              </div>

          </div>

          <div className="table table-striped" className="files" id="previews">
            <div id="template" ref={(div) => { this.divTemplate = div; }} className="file-row">
              <div>
                  <span className="preview"><img data-dz-thumbnail /></span>
              </div>
              <div>
                  <p className="name" data-dz-name></p>
                  <strong className="error text-danger" data-dz-errormessage></strong>
              </div>
              <div>
                  <p className="size" data-dz-size></p>
                  <div className="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
                    <div className="progress-bar progress-bar-success" data-dz-uploadprogress></div>
                  </div>
              </div>
              <div>
                <button className="btn btn-primary start">
                    <i className="glyphicon glyphicon-upload"></i>
                    <span>Start</span>
                </button>
                <button data-dz-remove className="btn btn-warning cancel">
                    <i className="glyphicon glyphicon-ban-circle"></i>
                    <span>Cancel</span>
                </button>
                <button data-dz-remove className="btn btn-danger delete">
                  <i className="glyphicon glyphicon-trash"></i>
                  <span>Delete</span>
                </button>
              </div>
            </div>
          </div>

      </div>
    );
  }
}
like image 57
Jose Paredes Avatar answered Sep 28 '22 02:09

Jose Paredes