Permalink
Browse files

MDL-31114 Filemanager drag and drop upload - displays 'drop here' mes…

…sage when dragging over page / highlights when over element
  • Loading branch information...
1 parent 36dc503 commit 7d44996c2a281b52ff029c230f87888e6ff9e1d5 @davosmith davosmith committed Feb 14, 2012
Showing with 97 additions and 7 deletions.
  1. +71 −3 lib/form/dndupload.js
  2. +8 −1 lib/form/filemanager.js
  3. +1 −1 lib/form/filemanager.php
  4. +11 −0 lib/form/filepicker.js
  5. +6 −2 theme/base/style/core.css
View
@@ -51,7 +51,7 @@ M.form_dndupload.init = function(Y, options) {
// Nasty hack to distinguish between dragenter(first entry),
// dragenter+dragleave(moving between child elements) and dragleave (leaving element)
entercount: 0,
-
+ pageentercount: 0,
/**
* Initalise the drag and drop upload interface
@@ -108,6 +108,7 @@ M.form_dndupload.init = function(Y, options) {
}
this.init_events();
+ this.init_page_events();
this.Y.one('#dndenabled-'+this.clientid).setStyle('display', 'inline');
},
@@ -154,6 +155,51 @@ M.form_dndupload.init = function(Y, options) {
},
/**
+ * Initialise whole-page events (to show / hide the 'drop files here'
+ * message)
+ */
+ init_page_events: function() {
+ this.Y.on('dragenter', this.drag_enter_page, 'body', this);
+ this.Y.on('dragleave', this.drag_leave_page, 'body', this);
+ },
+
+ /**
+ * Show the 'drop files here' message when file(s) are dragged
+ * onto the page
+ */
+ drag_enter_page: function(e) {
+ if (!this.has_files(e) || this.reached_maxfiles()) {
+ return false;
+ }
+
+ this.pageentercount++;
+ if (this.pageentercount >= 2) {
+ this.pageentercount = 2;
+ return false;
+ }
+
+ this.show_drop_target();
+
+ return false;
+ },
+
+ /**
+ * Hide the 'drop files here' message when file(s) are dragged off
+ * the page again
+ */
+ drag_leave_page: function(e) {
+ this.pageentercount--;
+ if (this.pageentercount == 1) {
+ return false;
+ }
+ this.pageentercount = 0;
+
+ this.hide_drop_target();
+
+ return false;
+ },
+
+ /**
* Check if the drag contents are valid and then call
* preventdefault / stoppropagation to let the browser know
* we will handle this drag/drop
@@ -194,6 +240,12 @@ M.form_dndupload.init = function(Y, options) {
return false;
}
+ // These lines are needed if the user has dragged something directly
+ // from application onto the 'fileupload' box, without crossing another
+ // part of the page first
+ this.pageentercount = 2;
+ this.show_drop_target();
+
this.show_upload_ready();
return false;
},
@@ -239,7 +291,9 @@ M.form_dndupload.init = function(Y, options) {
}
this.entercount = 0;
+ this.pageentercount = 0;
this.hide_upload_ready();
+ this.hide_drop_target();
this.show_progress_spinner();
var files = e._event.dataTransfer.files;
@@ -294,7 +348,18 @@ M.form_dndupload.init = function(Y, options) {
},
/**
- * Highlight the destination node
+ * Highlight the area where files could be dropped
+ */
+ show_drop_target: function() {
+ this.Y.one('#filemanager-uploadmessage'+this.clientid).setStyle('display', 'block');
+ },
+
+ hide_drop_target: function() {
+ this.Y.one('#filemanager-uploadmessage'+this.clientid).setStyle('display', 'none');
+ },
+
+ /**
+ * Highlight the destination node (ready to drop)
*/
show_upload_ready: function() {
this.container.addClass('dndupload-over');
@@ -321,7 +386,10 @@ M.form_dndupload.init = function(Y, options) {
* Remove progress spinner in the destination node
*/
hide_progress_spinner: function() {
- this.Y.one('#dndprogresspinner-'+this.clientid).remove();
+ var spinner = this.Y.one('#dndprogresspinner-'+this.clientid);
+ if (spinner) {
+ spinner.remove();
+ }
},
/**
@@ -264,7 +264,13 @@ M.form_filemanager.init = function(Y, options) {
}, this);
},
empty_filelist: function(container) {
- container.set('innerHTML', '<div class="mdl-align">'+M.str.repository.nofilesattached+'</div>');
+ container.set('innerHTML', '<div class="mdl-align">'+M.str.repository.nofilesattached+'</div>'+this.upload_message());
+ },
+ upload_message: function() {
+ var div = '<div id="filemanager-uploadmessage'+this.client_id+'" style="display:none" class="dndupload-target">';
+ div += M.util.get_string('droptoupload', 'moodle');
+ div += '</div>';
+ return div;
},
render: function() {
var options = this.options;
@@ -415,6 +421,7 @@ M.form_filemanager.init = function(Y, options) {
var filelist = Y.Node.create('<ul id="draftfiles-'+this.client_id+'"></ul>');
container.appendChild(filelist);
}
+ listhtml += this.upload_message();
Y.one('#draftfiles-'+this.client_id).set('innerHTML', listhtml);
// click normal file menu
@@ -288,7 +288,7 @@ function form_filemanager_render($options) {
<span> $maxsize </span>
<span id="dndenabled-{$client_id}" style="display: none"> - $strdndenabled </span>
</div>
- <div class="filemanager-container" id="filemanager-{$client_id}">
+ <div class="filemanager-container" id="filemanager-{$client_id}" style="position: relative" >
<ul id="draftfiles-{$client_id}" class="fm-filelist">
<li>Loading...</li>
</ul>
@@ -6,13 +6,23 @@ M.form_filepicker.instances = [];
M.form_filepicker.callback = function(params) {
var html = '<a href="'+params['url']+'">'+params['file']+'</a>';
document.getElementById('file_info_'+params['client_id']).innerHTML = html;
+ M.form_filepicker.add_upload_message(params['client_id']);
//When file is added then set status of global variable to true
var elementname = M.core_filepicker.instances[params['client_id']].options.elementname;
M.form_filepicker.instances[elementname].fileadded = true;
//generate event to indicate changes which will be used by disable if or validation code
M.form_filepicker.Y.one('#id_'+elementname).simulate('change');
};
+M.form_filepicker.add_upload_message = function(client_id) {
+ var div = '<div id="filemanager-uploadmessage'+client_id+'" style="display:none" class="dndupload-target">';
+ div += M.util.get_string('droptoupload', 'moodle');
+ div += '</div>';
+ var iteminfo = document.getElementById('file_info_'+client_id);
+ iteminfo.innerHTML += div;
+ iteminfo.style.position = 'relative';
+}
+
/**
* This fucntion is called for each file picker on page.
*/
@@ -42,6 +52,7 @@ M.form_filepicker.init = function(Y, options) {
item = document.getElementById('filepicker-wrapper-'+options.client_id);
if (item) {
item.style.display = '';
+ this.add_upload_message(options.client_id);
}
var dndoptions = {
@@ -532,8 +532,12 @@ body.tag .managelink {padding: 5px;}
.fm-file-entry{border: 1px solid red;}
.fm-operation {font-weight: bold;}
-.filemanager-container.dndupload-over,
-.filepicker-filelist.dndupload-over {background: #8EF947;}
+.filemanager-container,
+.filepicker-filelist {overflow:hidden;}
+.filemanager-container .dndupload-target,
+.filepicker-filelist .dndupload-target {background:#f7f998;position:absolute;height:100%;width:100%;top:0;left:0;text-align:center;padding:5px;z-index:1000}
+.filemanager-container.dndupload-over .dndupload-target,
+.filepicker-filelist.dndupload-over .dndupload-target {background:#8EF947;font-weight:bold}
/*
* Backup and Restore CSS

0 comments on commit 7d44996

Please sign in to comment.