Dateimanagement: Upload per Drag/Drop
authorBernd Bleßmann <bernd@kivitendo-premium.de>
Fri, 26 Feb 2021 11:45:01 +0000 (12:45 +0100)
committerBernd Bleßmann <bernd@kivitendo-premium.de>
Thu, 11 Mar 2021 10:30:27 +0000 (11:30 +0100)
css/common.css
js/kivi.File.js
js/locale/de.js
js/locale/en.js
locale/de/all
locale/en/all
templates/webpages/file/list.html

index fc3bca5..c8ade1f 100644 (file)
@@ -213,3 +213,11 @@ div.cke_textarea_inline {
 div.cke_textarea_inline:focus {
   outline: 0;
 }
+
+span.upload_drop_zone {
+  padding: 4px;
+  border: 2px;
+  border-color: darkgray lightgray lightgray;
+  border-style: solid;
+  background-color: whitesmoke;
+}
index c14c65f..327ef52 100644 (file)
@@ -1,4 +1,5 @@
 namespace('kivi.File', function(ns) {
+  ns.list_div_id = undefined;
 
   ns.rename = function(id,type,file_type,checkbox_class,is_global) {
     var $dlg       = $('#rename_dialog_'+file_type);
@@ -77,6 +78,8 @@ namespace('kivi.File', function(ns) {
   }
 
   ns.upload = function(id,type,filetype,upload_title,gl) {
+    $('#upload_status_dialog').remove();
+
     kivi.popup_dialog({ url:     'controller.pl',
                         data:    { action: 'File/ajax_upload',
                                    file_type:   filetype,
@@ -99,10 +102,30 @@ namespace('kivi.File', function(ns) {
       $('#upload_selected_button').prop('disabled',$('#upload_files').val() === '');
   }
 
+  ns.upload_status_dialog = function() {
+    $('#files_upload').remove();
+    $('#upload_status_dialog').remove();
+
+    var html  = '<div id="upload_status_dialog"><p><div id="upload_result"></div></p>';
+    html      = html + '<p><input type="button" value="' + kivi.t8('close') + '" size="30" onclick="$(\'#upload_status_dialog\').dialog(\'close\');">';
+    html      = html + '</p></div>';
+    $(html).hide().appendTo('#' + ns.list_div_id);
+
+    kivi.popup_dialog({id: 'upload_status_dialog',
+                       dialog: {title:  kivi.t8('Upload Status'),
+                                height: 200,
+                                width:  650 }});
+  };
+
   ns.upload_selected_files = function(id,type,filetype,maxsize,is_global) {
       var myform = document.getElementById("upload_form");
-      var filesize  = 0;
       var myfiles = document.getElementById("upload_files").files;
+
+      ns.upload_files(id, type, filetype, maxsize,is_global, myfiles, myform);
+  }
+
+  ns.upload_files = function(id, type, filetype, maxsize, is_global, myfiles, myform) {
+      var filesize  = 0;
       for ( i=0; i < myfiles.length; i++ ) {
           var fname ='';
           try {
@@ -125,16 +148,27 @@ namespace('kivi.File', function(ns) {
           return;
       }
 
-      myform.action ="controller.pl?action=File/ajax_files_uploaded&json=1&object_type="+
-          type+'&object_id='+id+'&file_type='+filetype+'&is_global='+is_global;
+      var fd = new FormData(myform);
+      if (!myform) {
+        $(myfiles).each(function(idx, elt) {
+          fd.append('uploadfiles[+]', elt);
+        });
+      }
+      fd.append('action',      'File/ajax_files_uploaded');
+      fd.append('json',        1);
+      fd.append('object_type', type);
+      fd.append('object_id',   id);
+      fd.append('file_type',   filetype);
+      fd.append('is_global',   is_global);
+
       var oReq = new XMLHttpRequest();
       oReq.onload            = ns.attSuccess;
       oReq.upload.onprogress = ns.attProgress;
       oReq.upload.onerror    = ns.attFailed;
       oReq.upload.onabort    = ns.attCanceled;
-      oReq.open("post",myform.action, true);
+      oReq.open("post", 'controller.pl', true);
       $("#upload_result").html(kivi.t8("start upload"));
-      oReq.send(new FormData(myform));
+      oReq.send(fd);
   }
 
   ns.attProgress = function(oEvent) {
@@ -155,6 +189,7 @@ namespace('kivi.File', function(ns) {
   }
 
   ns.attSuccess = function() {
+      $('#upload_status_dialog').dialog('close');
       $('#files_upload').dialog('close');
       kivi.eval_json_result(jQuery.parseJSON(this.response));
   }
@@ -265,4 +300,47 @@ namespace('kivi.File', function(ns) {
     $.download("controller.pl", data);
     return false;
   }
+
+  ns.init = function() {
+    // Preventing page from redirecting
+    $("#" + ns.list_div_id).on("dragover", function(e) {
+      e.preventDefault();
+      e.stopPropagation();
+    });
+
+    $("#" + ns.list_div_id).on("drop", function(e) {
+      e.preventDefault();
+      e.stopPropagation();
+    });
+
+    // Drag enter
+    $('.upload_drop_zone').on('dragenter', function (e) {
+      e.stopPropagation();
+      e.preventDefault();
+    });
+
+    // Drag over
+    $('.upload_drop_zone').on('dragover', function (e) {
+      e.stopPropagation();
+      e.preventDefault();
+    });
+
+    // Drop
+    $('.upload_drop_zone').on('drop', function (e) {
+      e.stopPropagation();
+      e.preventDefault();
+
+      ns.upload_status_dialog();
+
+      var object_type = $(e.target).data('object-type');
+      var object_id   = $(e.target).data('object-id');
+      var file_type   = $(e.target).data('file-type');
+      var is_global   = $(e.target).data('is-global');
+      var maxsize     = $(e.target).data('maxsize');
+      var files       = e.originalEvent.dataTransfer.files;
+      ns.upload_files(object_id, object_type, file_type, maxsize, is_global, files);
+    });
+
+  };
+
 });
index d6b20b6..9b0153d 100644 (file)
@@ -137,6 +137,7 @@ namespace("kivi").setupLocale({
 "Transaction description":"Vorgangsbezeichnung",
 "Update":"Erneuern",
 "Update quotation/order":"Auftrag/Angebot aktualisieren",
+"Upload Status":"Upload-Status",
 "Vendor details":"Lieferantendetails",
 "Vendor missing!":"Lieferant fehlt!",
 "Version actions":"Aktionen für Versionen",
@@ -146,6 +147,7 @@ namespace("kivi").setupLocale({
 "Yes":"Ja",
 "You have changed the currency or exchange rate. Please check prices.":"Die Währung oder der Wechselkurs hat sich geändert. Bitte überprüfen Sie die Preise.",
 "You have entered or selected the following shipping address for this customer:":"Sie haben die folgende Lieferadresse eingegeben oder ausgewählt:",
+"close":"schließen",
 "filename has not uploadable characters ":"Bitte Dateinamen ändern. Er hat für den Upload nicht verwendbare Sonderzeichen ",
 "filesize too big: ":"Datei zu groß: ",
 "flat-rate position":"Pauschalposition",
index 66e22fc..a089e68 100644 (file)
@@ -137,6 +137,7 @@ namespace("kivi").setupLocale({
 "Transaction description":"",
 "Update":"",
 "Update quotation/order":"",
+"Upload Status":"",
 "Vendor details":"",
 "Vendor missing!":"",
 "Version actions":"",
@@ -146,6 +147,7 @@ namespace("kivi").setupLocale({
 "Yes":"",
 "You have changed the currency or exchange rate. Please check prices.":"",
 "You have entered or selected the following shipping address for this customer:":"",
+"close":"",
 "filename has not uploadable characters ":"",
 "filesize too big: ":"",
 "flat-rate position":"",
index 1f5a291..23c8fcc 100755 (executable)
@@ -1121,6 +1121,7 @@ $self->{texts} = {
   'Draft for this Letter saved!' => 'Briefentwurf gespeichert!',
   'Draft saved.'                => 'Entwurf gespeichert.',
   'Drafts'                      => 'Entwürfe',
+  'Drag and drop files here'    => 'Dateien hierher ziehen und fallen lassen',
   'Drawing'                     => 'Zeichnung',
   'Due'                         => 'Fällig',
   'Due Date'                    => 'Fälligkeitsdatum',
@@ -3880,6 +3881,7 @@ $self->{texts} = {
   'Upload Attachments'          => 'Anhänge hochladen',
   'Upload Documents'            => 'Dokumente hochladen',
   'Upload Images'               => 'Bilder hochladen',
+  'Upload Status'               => 'Upload-Status',
   'Upload all marked'           => 'Markierte aktualisieren',
   'Upload file'                 => 'Datei hochladen',
   'Uploaded at'                 => 'Hochgeladen um',
index 14b13a5..9c9a857 100644 (file)
@@ -1121,6 +1121,7 @@ $self->{texts} = {
   'Draft for this Letter saved!' => '',
   'Draft saved.'                => '',
   'Drafts'                      => '',
+  'Drag and drop files here'    => '',
   'Drawing'                     => '',
   'Due'                         => '',
   'Due Date'                    => '',
@@ -3879,6 +3880,7 @@ $self->{texts} = {
   'Upload Attachments'          => '',
   'Upload Documents'            => '',
   'Upload Images'               => '',
+  'Upload Status'               => '',
   'Upload all marked'           => '',
   'Upload file'                 => '',
   'Uploaded at'                 => '',
index 16b4b85..dfb59f3 100644 (file)
@@ -1,4 +1,5 @@
 [%- USE LxERP -%][% USE L %]
+[% USE T8 %]
 [%- IF ! json %]
  <div id="[% file_type %]_list_[% object_type %]">
 [%- END %]
     [%- can_rename = 1 %]
     [% L.button_tag("kivi.File.rename(" _ object_id _ ",'" _ object_type _ "','" _ file_type _ "','" _ checkname _ "'," _ is_global _ ");",  source.rename_title ) %]
    [%- END %]
-   [%- IF source.can_upload %]
-    [% L.button_tag("kivi.File.upload(" _ object_id _ ",'" _ object_type _ "','" _ file_type _ "','" _ source.upload_title _ "'," _ is_global _ ");", source.upload_title ) %]
-   [%- END %]
    [%- IF source.can_import %]
     [% L.button_tag("kivi.File.import("   _ object_id _ ",'" _ object_type _ "','" _ file_type _ "','" _ source.name _ "','" _ source.path _"');",  source.import_title ) %]
    [%- END %]
+   [%- IF source.can_upload %]
+    [% L.button_tag("kivi.File.upload(" _ object_id _ ",'" _ object_type _ "','" _ file_type _ "','" _ source.upload_title _ "'," _ is_global _ ");", source.upload_title ) %]
+    <span class="upload_drop_zone"
+          data-object-type="[% object_type %]"
+          data-object-id="[% object_id %]"
+          data-file-type="[% file_type %]"
+          data-is-global="[% is_global %]"
+          data-maxsize="[% INSTANCE_CONF.get_doc_max_filesize %]">
+      [% 'Drag and drop files here' | $T8 %]
+    </span>
+   [%- END %]
   </div>
  [%- END # FOREACH source %]
  <div></div>
   [%- END %]
  [%- END %]
 [%- END %]
+
+<script>
+  $(function() {
+    kivi.File.list_div_id = "[% file_type %]_list_[% object_type %]";
+    kivi.File.init();
+  });
+</script>