diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF
index 9ba470ccf4..c39679ed5a 100644
--- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF
+++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF
@@ -187,6 +187,7 @@ Export-Package: fi.jawsy.jawwa.zk.atmosphere,
web.js.ckez.ext.CKeditor.vendor,
web.js.html2canvas,
web.js.jawwa.atmosphere,
+ web.js.dragdrop.attachment,
web.js.jquery.maskedinput,
web.js.org.idempiere.commons,
web.js.org.idempiere.websocket,
diff --git a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
index 3ac23523f0..e5dac4b1ae 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
+++ b/org.adempiere.ui.zk/WEB-INF/src/metainfo/zk/lang-addon.xml
@@ -53,9 +53,10 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
+
-
+
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java
index 7839dbb98f..0a09e9167d 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java
@@ -76,6 +76,7 @@ import org.zkoss.zul.Hbox;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Iframe;
import org.zkoss.zul.North;
+import org.zkoss.zul.Progressmeter;
import org.zkoss.zul.South;
import org.zkoss.zul.Vlayout;
@@ -136,6 +137,8 @@ public class WAttachment extends Window implements EventListener
private int maxPreviewSize;
private Component customPreviewComponent;
+
+ private Progressmeter progress = new Progressmeter(0);
private static List autoPreviewList;
@@ -225,6 +228,15 @@ public class WAttachment extends Window implements EventListener
{
}
+ String maxUploadSize = "";
+ int size = MSysConfig.getIntValue(MSysConfig.ZK_MAX_UPLOAD_SIZE, 0);
+ if (size > 0)
+ maxUploadSize = "" + size;
+
+ Clients.evalJavaScript("idempiere.dropToAttachFiles('" + this.getUuid() + "','" + mainPanel.getUuid() + "','"
+ + this.getDesktop().getId() + "','" + progress.getUuid() + "','" + sizeLabel.getUuid() + "','"
+ + maxUploadSize + "');");
+
} // WAttachment
/**
@@ -266,9 +278,11 @@ public class WAttachment extends Window implements EventListener
this.appendChild(mainPanel);
ZKUpdateUtil.setHeight(mainPanel, "100%");
ZKUpdateUtil.setWidth(mainPanel, "100%");
+ mainPanel.addEventListener(Events.ON_UPLOAD, this);
+
North northPanel = new North();
- northPanel.setStyle("padding: 4px");
+ northPanel.setStyle("padding: 4px; background: #e8e8e8;");
northPanel.setCollapsible(false);
northPanel.setSplittable(false);
@@ -286,14 +300,18 @@ public class WAttachment extends Window implements EventListener
toolBar.appendChild(cbContent);
toolBar.appendChild(sizeLabel);
- mainPanel.appendChild(northPanel);
+ progress.setClass("drop-progress-meter");
+ progress.setVisible(false);
+
Vlayout div = new Vlayout();
div.appendChild(toolBar);
+ div.appendChild(progress);
text.setRows(3);
ZKUpdateUtil.setHflex(text, "1");
div.appendChild(text);
northPanel.appendChild(div);
+ mainPanel.appendChild(northPanel);
bSave.setEnabled(false);
bSave.setSclass("img-btn");
@@ -336,8 +354,9 @@ public class WAttachment extends Window implements EventListener
bEmail.addEventListener(Events.ON_CLICK, this);
previewPanel.appendChild(preview);
- ZKUpdateUtil.setVflex(preview, "1");
- ZKUpdateUtil.setHflex(preview, "1");
+ previewPanel.setSclass("popup-content-background");
+ ZKUpdateUtil.setHeight(preview, "99%");
+ ZKUpdateUtil.setWidth(preview, "99%");
Center centerPane = new Center();
centerPane.setSclass("dialog-content");
@@ -685,7 +704,7 @@ public class WAttachment extends Window implements EventListener
}
private void processUploadMedia(Media media) {
- if (media != null && media.getByteData().length>0)
+ if (media != null && ((media.isBinary() && media.getByteData().length>0) || (!media.isBinary() && media.getStringData().length() > 0)))
{
// pdfViewer.setContent(media);
;
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/js/dragdrop/attachment/drag-drop-attachment.js b/org.adempiere.ui.zk/WEB-INF/src/web/js/dragdrop/attachment/drag-drop-attachment.js
new file mode 100644
index 0000000000..c89db67244
--- /dev/null
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/js/dragdrop/attachment/drag-drop-attachment.js
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (C) 2017 Adaxa Pty Ltd. All Rights Reserved. This program is free
+ * software; you can redistribute it and/or modify it under the terms version 2
+ * of the GNU General Public License as published by the Free Software
+ * Foundation. This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ ******************************************************************************/
+/**
+ * Drag and Drop functionality for Attachment
+ *
+ * @author Logilite Technologies
+ * @since October 16, 2017
+ */
+
+if (typeof window.idempiere === 'undefined')
+ window.idempiere = {};
+
+window.idempiere.dropToAttachFiles = function(formID, dropBtnID, desktopID, progBarID, progLabelID, maxUploadSize) {
+
+ var clsName = " attachment-drag-entered";
+
+ var seqID = 0;
+ var highlightdragging;
+ var dropBtn = document.getElementById(dropBtnID);
+ var progressbar = document.getElementById(progBarID);
+
+ var isSupported = {
+ dnd: 'draggable' in document.createElement('span'),
+ formdata: !!window.FormData,
+ progress: "upload" in new XMLHttpRequest
+ };
+
+ if (isSupported.dnd) {
+ dropBtn.ondragover = function() {
+ return false;
+ };
+
+ dropBtn.ondragenter = function(e) {
+ highlightdragging = e.target;
+ this.className = this.className + clsName;
+ return false;
+ };
+
+ dropBtn.ondragleave = function(e) {
+ if (e.target === highlightdragging)
+ this.className = findAndReplace(this.className, clsName, '');
+ return false;
+ };
+
+ dropBtn.ondrop = function(e) {
+ e.preventDefault();
+
+ var requestSize = 0;
+ var files = e.dataTransfer.files;
+ for (var i = 0; i < files.length; i++) {
+ requestSize = requestSize + files[i].size;
+ }
+
+ requestSize = Math.round(requestSize / 1024);
+
+ if (maxUploadSize && requestSize > maxUploadSize) {
+ alert('The request was rejected because its size (' + requestSize + ') exceeds the configured maximum (' + maxUploadSize + ')');
+ return;
+ }
+
+ progressbar.style = 'display: block';
+ progressbar.parentNode.style = 'display: block';
+ progressBarUploadStatus(progBarID, progLabelID, 0, 'Starting Upload...');
+ this.className = findAndReplace(this.className, clsName, '');
+
+ uploadFiles(files, seqID++);
+ return false;
+ };
+ } else {
+ clsName = "";
+ alert("Click to Upload Files");
+ } // drop listener
+
+ function uploadFiles(files, sid) {
+ var formData = isSupported.formdata ? new FormData() : null;
+ if (isSupported.formdata) {
+ for (var i = 0; i < files.length; i++) {
+ formData.append('file', files[i], files[i].name);
+ }
+ }
+
+ var xhr = new XMLHttpRequest();
+ var url = "/webui/zkau/upload?uuid=" + formID + "&dtid=" + desktopID + "&sid=" + sid + "&native=true";
+ if (maxUploadSize)
+ url = url + "&maxsize=" + maxUploadSize;
+
+ xhr.open("POST", url, true);
+
+ // Content-Type is automatically determined by the browser.
+ // Sets the content type to 'multipart/form-data' and says that the
+ // fields are separated by the boundary string like:
+ // "Content-Type: multipart/form-data; boundary=---90519140415446"
+
+ xhr.onload = function() {
+ disableProgressInfo(100);
+ };
+
+ if (isSupported.progress) {
+ xhr.upload.onprogress =
+ function(event) {
+ progressbar.style = 'display: block';
+ progressbar.parentNode.style = 'display: block';
+ if (event.lengthComputable) {
+ var complete = (event.loaded / event.total * 100 | 0);
+ var status = 'Uploading ' + complete + '% [ ' + Math.round(event.loaded / 1024) + ' / ' + Math.round(event.total / 1024) + ' KB ]';
+ progressBarUploadStatus(progBarID, progLabelID, complete, status);
+ }
+ };
+ }
+
+ xhr.onreadystatechange =
+ function() {
+ // 4: request finished and response is ready
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ var response = xhr.responseText;
+ var startIndex = response.indexOf("zul.Upload.sendResult(");
+ var endIndex = response.indexOf("zul.Upload.close(");
+ var data = response.substring(startIndex, endIndex);
+ var arr = data.split(",");
+
+ if (arr.length > 1) {
+ var contID = findAndReplace(arr[1].trim(), "'", "");
+ var wgt = zk.Widget.$(formID);
+ var event = new zk.Event(wgt.desktop, "updateResult", {
+ contentId: contID,
+ wid: dropBtnID,
+ sid: "" + sid
+ });
+
+ zAu.send(event);
+
+ } else {
+ alert('Ooops! Something went wrong...!!!');
+ disableProgressInfo(0);
+ }
+ } else {
+ alert('Something went wrong...!!! \nPlease you can try with clicking to upload button.')
+ disableProgressInfo(0);
+ }
+ }
+ };
+
+ xhr.onerror = function(errorType, exception) {
+ var msg = '';
+ if (xhr.status === 0) {
+ msg = 'Connection Lost. Please Verify Network.';
+ } else if (xhr.status == 404) {
+ msg = 'Requested page not found. [404]';
+ } else if (xhr.status == 500) {
+ msg = 'Internal Server Error [500].';
+ } else if (exception === 'parsererror') {
+ msg = 'Requested parse failed.';
+ } else if (exception === 'timeout') {
+ msg = 'Time out error.';
+ } else if (exception === 'abort') {
+ msg = 'Request aborted.';
+ } else {
+ msg = 'Uncaught Error.\n' + xhr.responseText;
+ }
+
+ disableProgressInfo(0);
+ console.log(errorType + " - " + exception + " - " + msg);
+ alert(msg);
+ };
+
+ xhr.send(formData);
+ } // uploadFiles
+
+ function disableProgressInfo(val) {
+ progressBarUploadStatus(progBarID, progLabelID, val, '');
+ progressbar.style = 'display: none';
+ progressbar.parentNode.style = 'display: none';
+ } // disableProgressInfo
+
+ function findAndReplace(str, target, replacement) {
+ return str.replace(new RegExp(target, 'g'), replacement);
+ } // findAndReplace
+
+ function progressBarUploadStatus(pbID, plID, val, fileStatus) {
+ var pbar = zk.Widget.$(pbID);
+ pbar.setValue(val);
+
+ var pLabel = zk.Widget.$(plID);
+ pLabel.setValue(fileStatus);
+ } // progressBarUploadStatus
+};
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/js/dragdrop/attachment/zk.wpd b/org.adempiere.ui.zk/WEB-INF/src/web/js/dragdrop/attachment/zk.wpd
new file mode 100644
index 0000000000..5a93548e26
--- /dev/null
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/js/dragdrop/attachment/zk.wpd
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/drag-drop-attachment.css.dsp b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/drag-drop-attachment.css.dsp
new file mode 100644
index 0000000000..a518330e53
--- /dev/null
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/fragment/drag-drop-attachment.css.dsp
@@ -0,0 +1,19 @@
+<%-- CSS for Drag & Drop on Attachment --%>
+
+.attachment-drag-entered {
+ border: 5px dashed #3fb900;
+}
+
+.drop-progress-meter
+{
+ width:100% !important;
+}
+
+.z-progressmeter-image {
+ background: linear-gradient(to bottom, #1eff00 0%, #1a6b18 100%);
+}
+
+.popup-content-background
+{
+ border: 3px solid #cfcfcf; background: #efefef;
+}
\ No newline at end of file
diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/theme.css.dsp b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/theme.css.dsp
index ffd22d5004..1c998b817c 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/theme.css.dsp
+++ b/org.adempiere.ui.zk/WEB-INF/src/web/theme/default/css/theme.css.dsp
@@ -124,6 +124,8 @@ table.z-vbox > tbody > tr > td > table {
+
+
\ No newline at end of file
diff --git a/org.adempiere.ui.zk/index.zul b/org.adempiere.ui.zk/index.zul
index 57c62e99ff..b6e5fa0454 100644
--- a/org.adempiere.ui.zk/index.zul
+++ b/org.adempiere.ui.zk/index.zul
@@ -30,6 +30,7 @@ if (window.location.protocol == 'https:') {
zk.load("org.idempiere.commons");
zk.load("jquery.maskedinput");
zk.load("photobooth");
+ zk.load("dragdrop.attachment");
zk.afterLoad(function() {
zk._Erbx.push = function(msg) {