- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables
Class ::xowiki::BootstrapNavbarDropzone
::xowiki::BootstrapNavbarDropzone create ... \Dropzone widget for drag and drop of files, e.g. in the menubar. The widget provides added support for updating the current page with feedback of the dropped files.
[ -disposition (default "File") ] \
[ -file_name_prefix (default "") ] \
[ -href (default "#") ] \
[ -label (default "DropZone") ] \
[ -text (default "") ]
Defined in packages/xowiki/tcl/bootstrap-procs.tcl
- Documented Parameters:
- href
- URL for POST request
- label
- Text to be displayed at the place where files are dropped to
- file_name_prefix
- prefix for files being uploaded (used e.g. by the online exam).
- disposition
- define, what happens after the file was uploaded, e.g. whether the content has to be transformed, stored and displayed later.
Class Relations
::xo::tdom::Class create ::xowiki::BootstrapNavbarDropzone \ -superclass ::xowiki::MenuComponentMethods (to be applied on instances)
disposition (setter)
file_name_prefix (setter)
href (setter)
js (scripted)
html::script -type "text/javascript" -nonce [security::csp::nonce] { html::t { + function($) { 'use strict'; var dropZone = document.getElementById('drop-zone'); var uploadForm = document.getElementById('js-upload-form'); var progressBar = document.getElementById('dropzone-progress-bar'); var dropZoneResponse = document.getElementById('thumbnail-files-wrapper'); var uploadFileRunning = 0; var uploadFilesStatus = []; var uploadFilesResponse = []; var startUpload = function(files, disposition, url, prefix, csrf) { //console.log("files " + files + " dispo '"+ disposition + "' url " + url + " prefix " + prefix); if (typeof files !== "undefined") { for (var i=0, l=files.length; i<l; i++) { // Send the file as multiple single requests and // not as a single post containing all entries. This // gives users with older NaviServers or AOLserver the chance // drop multiple files. uploadFile(files[i], disposition, url, prefix, csrf); } } else { alert("No support for the File API in this web browser"); } } var uploadFile = function(file, disposition, url, prefix, csrf) { var xhr; var formData = new FormData(); var fullName = (prefix == "" ? file.name : prefix + '/' + file.name); var fullUrl = url + "&disposition=" + encodeURIComponent(disposition) + "&name=" + encodeURIComponent(fullName); xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { // For multiple drop files, we should probably we // should sum up the sizes. However, since the // uploads are in parallel, this is already useful. progressBar.style.width = (evt.loaded / evt.total) * 100 + "%"; } else { // No data to calculate on } }, false); xhr.addEventListener("load", function (event) { uploadFileRunning--; uploadFilesStatus.push(event.currentTarget.status); uploadFilesResponse.push(event.currentTarget.response); //console.log("ended with status " + event.currentTarget.status); //console.log("running: " + uploadFileRunning); if (dropZoneResponse) { // We have a dropzone response and update this in the // web page. dropZoneResponse.innerHTML = uploadFilesResponse[uploadFilesResponse.length-1]; dropZoneResponse.querySelectorAll('.thumbnail-file').forEach(el => thumbnail_files_setup(el)); } if (uploadFileRunning < 1) { if (dropZoneResponse) { // We are done with all uploads. When the response is // provided, it was updated above already in the web // page, but we have still to reset the progress bar // to indicate that we are done. progressBar.style.width = '0%'; } else { // Reload the page to trigger a refresh location.reload(true); } } }, false); xhr.open("post", fullUrl, true); formData.append("upload", file); formData.append("__csrf_token", csrf); uploadFileRunning++; xhr.send(formData); } uploadForm.addEventListener('submit', function(e) { // // Input handler for classical form submit // var input = document.getElementById('js-upload-files'); var uploadFiles = input.files; var csrf = input.form.elements["__csrf_token"].value; e.preventDefault(); //console.log("Submit handler"); startUpload(input.files, input.dataset.disposition ?? 'File', input.dataset.url, input.dataset.file_name_prefix ?? '', csrf); }) dropZone.ondrop = function(e) { // // Input handler for drag & drop // e.preventDefault(); this.className = 'upload-drop-zone'; var form = document.getElementById('js-upload-files').form; var csrf = form.elements["__csrf_token"].value; var input = document.getElementById('js-upload-files'); //console.log("Drop handler"); startUpload(e.dataTransfer.files, input.dataset.disposition ?? 'File', input.dataset.url, input.dataset.file_name_prefix ?? '', csrf); } dropZone.ondragover = function() { this.className = 'upload-drop-zone drop'; return false; } dropZone.ondragleave = function() { this.className = 'upload-drop-zone'; return false; } } (jQuery); } }label (setter)
render (scripted, public)
<instance of xowiki::BootstrapNavbarDropzone> renderdoku
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- create_folder_with_page, create_workflow_with_instance
if {${:href} ni {"" "#"}} { html::li { html::form -method "post" -enctype "multipart/form-data" -style "display: none;" -id "js-upload-form" { html::div -class "form-inline" { html::div -class "form-group" { html::input -type "file" -name {files[]} -id "js-upload-files" -data-file_name_prefix ${:file_name_prefix} -data-url ${:href} -data-disposition ${:disposition} -multiple multiple } html::button -type "submit" -class "btn btn-sm btn-primary" -id "js-upload-submit" { html::t ${:text} } ::html::CSRFToken } } html::div -class "upload-drop-zone" -id "drop-zone" { html::span {html::t ${:label}} html::div -class "progress" { html::div -style "width: 0%;" -class "progress-bar" -id dropzone-progress-bar { html::span -class "sr-only" {html::t ""} } } } } :js }text (setter)
- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables