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>
);
}
}
3 things:
By using componentDidMount lifecycle method doesn't mean that both $
(JQuery) and dropzone
are already loaded in the DOM
Use React Refs
instead of selectors so your components are consistent
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>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With