plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Thu Oct 24 14:01:22 CEST 2013


 plugins/tasklist/skins/larry/tasklist.css |   16 ++-
 plugins/tasklist/tasklist.js              |  129 +++++++++++++++++++++++-------
 2 files changed, 113 insertions(+), 32 deletions(-)

New commits:
commit 5d34d7945789db9c9e84f76a18acf4c2e86eb12d
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Thu Oct 24 14:00:36 2013 +0200

    Assign tags by drag & dropping them onto tasks (#2389); some fixes concerning saving and resorting tasks

diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index fadb62b..9efc18b 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -189,13 +189,10 @@ body.attachmentwin #topnav .topright {
 
 #tagslist li.inactive {
 	color: #89b3be;
+	padding-right: 0.6em;
 /*	display: none; */
 }
 
-#tagslist li.inactive .count {
-	display: none;
-}
-
 #tagslist li .count {
 	position: relative;
 	top: -1px;
@@ -213,6 +210,11 @@ body.attachmentwin #topnav .topright {
 	border-radius: 8px;
 }
 
+.tag-draghelper .tag .count,
+#tagslist li.inactive .count {
+	display: none;
+}
+
 #tasklists li {
 	margin: 0;
 	height: 20px;
@@ -504,6 +506,7 @@ body.attachmentwin #topnav .topright {
 	text-align: right;
 }
 
+.tag-draghelper .tag,
 .taskhead .tags .tag {
 	font-size: 85%;
 	background: #d9ecf4;
@@ -513,6 +516,11 @@ body.attachmentwin #topnav .topright {
 	margin-right: 3px;
 }
 
+.tag-draghelper li.tag {
+    list-style: none;
+    font-size: 100%;
+}
+
 .taskhead .date {
 	position: absolute;
 	top: 4px;
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index d318011..68ea117 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -64,6 +64,8 @@ function rcube_tasklist_ui(settings)
     var search_request;
     var search_query;
     var completeness_slider;
+    var task_draghelper;
+    var tag_draghelper;
     var me = this;
 
     // general datepicker settings
@@ -337,7 +339,8 @@ function rcube_tasklist_ui(settings)
                     $(input).datepicker('widget').find('button.ui-datepicker-close')
                         .html(rcmail.gettext('nodate','tasklist'))
                         .attr('onclick', '')
-                        .click(function(e){
+                        .unbind('click')
+                        .bind('click', function(e){
                             $(input).datepicker('setDate', null).datepicker('hide');
                         });
                 }, 1);
@@ -570,8 +573,19 @@ function rcube_tasklist_ui(settings)
 
         // append new tags to tag cloud
         $.each(newtags, function(i, tag){
-            $('<li>').attr('rel', tag).data('value', tag).html(Q(tag) + '<span class="count"></span>').appendTo(rcmail.gui_objects.tagslist);
-        });
+            $('<li>').attr('rel', tag).data('value', tag)
+                .html(Q(tag) + '<span class="count"></span>')
+                .appendTo(rcmail.gui_objects.tagslist)
+                .draggable({
+                    addClasses: false,
+                    revert: 'invalid',
+                    revertDuration: 300,
+                    helper: tag_draggable_helper,
+                    start: tag_draggable_start,
+                    appendTo: 'body',
+                    cursor: 'pointer',
+                });
+            });
 
         // re-sort tags list
         $(rcmail.gui_objects.tagslist).children('li').sortElements(function(a,b){
@@ -595,6 +609,59 @@ function rcube_tasklist_ui(settings)
         });
     }
 
+    /*  Helper functions for drag & drop functionality of tags  */
+    
+    function tag_draggable_helper()
+    {
+        if (!tag_draghelper)
+            tag_draghelper = $('<div class="tag-draghelper"></div>');
+        else
+            tag_draghelper.html('');
+
+        $(this).clone().addClass('tag').appendTo(tag_draghelper);
+        return tag_draghelper;
+    }
+
+    function tag_draggable_start(event, ui)
+    {
+        $('.taskhead').droppable({
+            hoverClass: 'droptarget',
+            accept: tag_droppable_accept,
+            drop: tag_draggable_dropped,
+            addClasses: false
+        });
+    }
+
+    function tag_droppable_accept(draggable)
+    {
+        if (rcmail.busy)
+            return false;
+
+        var tag = draggable.data('value'),
+            drop_id = $(this).data('id'),
+            drop_rec = listdata[drop_id];
+
+        // target already has this tag assigned
+        if (!drop_rec || (drop_rec.tags && $.inArray(tag, drop_rec.tags) >= 0)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    function tag_draggable_dropped(event, ui)
+    {
+        var drop_id = $(this).data('id'),
+            tag = ui.draggable.data('value'),
+            rec = listdata[drop_id];
+
+        if (rec && rec.id) {
+            if (!rec.tags) rec.tags = [];
+            rec.tags.push(tag);
+            save_task(rec, 'edit');
+        }
+    }
+
     /**
      *
      */
@@ -721,10 +788,10 @@ function rcube_tasklist_ui(settings)
                 revert: 'invalid',
                 addClasses: false,
                 cursorAt: { left:-10, top:12 },
-                helper: draggable_helper,
+                helper: task_draggable_helper,
                 appendTo: 'body',
-                start: draggable_start,
-                stop: draggable_stop,
+                start: task_draggable_start,
+                stop: task_draggable_stop,
                 revertDuration: 300
             });
 
@@ -769,7 +836,7 @@ function rcube_tasklist_ui(settings)
      */
     function resort_task(rec, li, animated)
     {
-        var dir = 0, index, slice, next_li, next_id, next_rec;
+        var dir = 0, index, slice, cmp, next_li, next_id, next_rec, insert_after, past_myself;
 
         // animated moving
         var insert_animated = function(li, before, after) {
@@ -795,33 +862,36 @@ function rcube_tasklist_ui(settings)
         }
 
         // find the right place to insert the task item
-        li.siblings().each(function(i, elem){
+        li.parent().children('.taskitem').each(function(i, elem){
             next_li = $(elem);
             next_id = next_li.attr('rel');
             next_rec = listdata[next_id];
 
             if (next_id == rec.id) {
-                next_li = null;
+                past_myself = true;
                 return 1; // continue
             }
 
-            if (next_rec && task_cmp(rec, next_rec) > 0) {
+            cmp = next_rec ? task_cmp(rec, next_rec) : 0;
+
+            if (cmp > 0 || (cmp == 0 && !past_myself)) {
+                insert_after = next_li;
                 return 1; // continue;
             }
-            else if (next_rec && next_li && task_cmp(rec, next_rec) < 0) {
+            else if (next_li && cmp < 0) {
                 if (animated) insert_animated(li, next_li);
                 else          li.insertBefore(next_li);
-                next_li = null;
-                return false;
+                index = $.inArray(next_id, listindex);
+                return false; // break
             }
         });
 
-        index = $.inArray(next_id, listindex);
+        if (insert_after) {
+            if (animated) insert_animated(li, null, insert_after);
+            else          li.insertAfter(insert_after);
 
-        if (next_li) {
-            if (animated) insert_animated(li, null, next_li);
-            else          li.insertAfter(next_li);
-            index++;
+            next_id = insert_after.attr('rel');
+            index = $.inArray(next_id, listindex);
         }
 
         // insert into list index
@@ -865,20 +935,20 @@ function rcube_tasklist_ui(settings)
 
     /*  Helper functions for drag & drop functionality  */
     
-    function draggable_helper()
+    function task_draggable_helper()
     {
-        if (!draghelper)
-            draghelper = $('<div class="taskitem-draghelper">&#x2714;</div>');
+        if (!task_draghelper)
+            task_draghelper = $('<div class="taskitem-draghelper">&#x2714;</div>');
 
-        return draghelper;
+        return task_draghelper;
     }
 
-    function draggable_start(event, ui)
+    function task_draggable_start(event, ui)
     {
         $('.taskhead, #rootdroppable, #'+rcmail.gui_objects.folderlist.id+' li').droppable({
             hoverClass: 'droptarget',
-            accept: droppable_accept,
-            drop: draggable_dropped,
+            accept: task_droppable_accept,
+            drop: task_draggable_dropped,
             addClasses: false
         });
 
@@ -886,13 +956,13 @@ function rcube_tasklist_ui(settings)
         $('#rootdroppable').show();
     }
 
-    function draggable_stop(event, ui)
+    function task_draggable_stop(event, ui)
     {
         $(this).parent().removeClass('dragging');
         $('#rootdroppable').hide();
     }
 
-    function droppable_accept(draggable)
+    function task_droppable_accept(draggable)
     {
         if (rcmail.busy)
             return false;
@@ -924,7 +994,7 @@ function rcube_tasklist_ui(settings)
         return true;
     }
 
-    function draggable_dropped(event, ui)
+    function task_draggable_dropped(event, ui)
     {
         var drop_id = $(this).data('id'),
             task_id = ui.draggable.data('id'),
@@ -1220,6 +1290,9 @@ function rcube_tasklist_ui(settings)
             if (!me.selected_task.list && list.id)
                 me.selected_task.list = list.id;
 
+            if (!me.selected_task.tags.length)
+                me.selected_task.tags = '';
+
             if (save_task(me.selected_task, action))
                 $dialog.dialog('close');
         };




More information about the commits mailing list