diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-02-13 19:24:36 -0500 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-02-13 19:24:36 -0500 |
commit | 738b6ae5832fb7c2992ec0dc52399e4dbf3d096d (patch) | |
tree | 25ebca2f9d6dd6ba8f5431644fdc6b8ff91ac34d /assets/js/src | |
parent | 6161eaef9e107ddbfc104753eb5d48434de3b824 (diff) |
Add file drag and drop and asynchronous upload
Diffstat (limited to 'assets/js/src')
-rw-r--r-- | assets/js/src/App.js | 2 | ||||
-rw-r--r-- | assets/js/src/FileUpload.js | 124 |
2 files changed, 126 insertions, 0 deletions
diff --git a/assets/js/src/App.js b/assets/js/src/App.js index d44d9f81..33b3c6b1 100644 --- a/assets/js/src/App.js +++ b/assets/js/src/App.js @@ -9,6 +9,7 @@ function App() { this.task = new Task(); this.project = new Project(); this.subtask = new Subtask(); + this.file = new FileUpload(this); this.keyboardShortcuts(); this.chosen(); this.poll(); @@ -39,6 +40,7 @@ App.prototype.listen = function() { this.task.listen(); this.swimlane.listen(); this.subtask.listen(); + this.file.listen(); this.search.focus(); this.autoComplete(); this.datePicker(); diff --git a/assets/js/src/FileUpload.js b/assets/js/src/FileUpload.js new file mode 100644 index 00000000..a8816bcd --- /dev/null +++ b/assets/js/src/FileUpload.js @@ -0,0 +1,124 @@ +function FileUpload(app) { + this.app = app; + this.files = []; + this.currentFile = 0; +} + +FileUpload.prototype.listen = function() { + var dropzone = document.getElementById("file-dropzone"); + var self = this; + + if (dropzone) { + dropzone.ondragover = dropzone.ondragenter = function(e) { + e.stopPropagation(); + e.preventDefault(); + } + + dropzone.ondrop = function(e) { + e.stopPropagation(); + e.preventDefault(); + self.files = e.dataTransfer.files; + self.show(); + $("#file-error-max-size").hide(); + } + + $(document).on("click", "#file-browser", function(e) { + e.preventDefault(); + $("#file-form-element").get(0).click(); + }); + + $(document).on("click", "#file-upload-button", function(e) { + e.preventDefault(); + self.currentFile = 0; + self.checkFiles(); + }); + + $("#file-form-element").change(function() { + self.files = document.getElementById("file-form-element").files; + self.show(); + $("#file-error-max-size").hide(); + }); + } +}; + +FileUpload.prototype.show = function() { + $("#file-list").remove(); + + if (this.files.length > 0) { + $("#file-upload-button").prop("disabled", false); + $("#file-dropzone-inner").hide(); + + var ul = jQuery("<ul>", {"id": "file-list"}); + + for (var i = 0; i < this.files.length; i++) { + var percentage = jQuery("<span>", {"id": "file-percentage-" + i}).append("(0%)"); + var progress = jQuery("<progress>", {"id": "file-progress-" + i, "value": 0}); + var li = jQuery("<li>", {"id": "file-label-" + i}) + .append(progress) + .append(" ") + .append(this.files[i].name) + .append(" ") + .append(percentage); + + ul.append(li); + } + + $("#file-dropzone").append(ul); + } else { + $("#file-dropzone-inner").show(); + } +}; + +FileUpload.prototype.checkFiles = function() { + var max = parseInt($("#file-dropzone").data("max-size")); + + for (var i = 0; i < this.files.length; i++) { + if (this.files[i].size > max) { + $("#file-error-max-size").show(); + $("#file-label-" + i).addClass("file-error"); + $("#file-upload-button").prop("disabled", true); + return; + } + } + + this.uploadFiles(); +}; + +FileUpload.prototype.uploadFiles = function() { + if (this.files.length > 0) { + this.uploadFile(this.files[this.currentFile]); + } +}; + +FileUpload.prototype.uploadFile = function(file) { + var dropzone = document.getElementById("file-dropzone"); + var url = dropzone.dataset.url; + var xhr = new XMLHttpRequest(); + var fd = new FormData(); + + xhr.upload.addEventListener("progress", this.updateProgress.bind(this)); + xhr.upload.addEventListener("load", this.transferComplete.bind(this)); + + xhr.open("POST", url, true); + fd.append('files[]', file); + xhr.send(fd); +}; + +FileUpload.prototype.updateProgress = function(e) { + if (e.lengthComputable) { + $("#file-progress-" + this.currentFile).val(e.loaded / e.total); + $("#file-percentage-" + this.currentFile).text('(' + Math.floor((e.loaded / e.total) * 100) + '%)'); + } +}; + +FileUpload.prototype.transferComplete = function() { + this.currentFile++; + + if (this.currentFile < this.files.length) { + this.uploadFile(this.files[this.currentFile]); + } else { + $("#file-upload-button").prop("disabled", true); + $("#file-upload-button").parent().hide(); + $("#file-done").show(); + } +}; |