Assign tags by drag & dropping them onto tasks (#2389); some fixes concerning saving and resorting tasks
This commit is contained in:
parent
1dc581eb71
commit
5d34d79457
2 changed files with 113 additions and 32 deletions
|
@ -189,13 +189,10 @@ body.attachmentwin #topnav .topright {
|
||||||
|
|
||||||
#tagslist li.inactive {
|
#tagslist li.inactive {
|
||||||
color: #89b3be;
|
color: #89b3be;
|
||||||
|
padding-right: 0.6em;
|
||||||
/* display: none; */
|
/* display: none; */
|
||||||
}
|
}
|
||||||
|
|
||||||
#tagslist li.inactive .count {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tagslist li .count {
|
#tagslist li .count {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -1px;
|
top: -1px;
|
||||||
|
@ -213,6 +210,11 @@ body.attachmentwin #topnav .topright {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag-draghelper .tag .count,
|
||||||
|
#tagslist li.inactive .count {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#tasklists li {
|
#tasklists li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
@ -504,6 +506,7 @@ body.attachmentwin #topnav .topright {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag-draghelper .tag,
|
||||||
.taskhead .tags .tag {
|
.taskhead .tags .tag {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
background: #d9ecf4;
|
background: #d9ecf4;
|
||||||
|
@ -513,6 +516,11 @@ body.attachmentwin #topnav .topright {
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag-draghelper li.tag {
|
||||||
|
list-style: none;
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.taskhead .date {
|
.taskhead .date {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
|
|
|
@ -64,6 +64,8 @@ function rcube_tasklist_ui(settings)
|
||||||
var search_request;
|
var search_request;
|
||||||
var search_query;
|
var search_query;
|
||||||
var completeness_slider;
|
var completeness_slider;
|
||||||
|
var task_draghelper;
|
||||||
|
var tag_draghelper;
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
// general datepicker settings
|
// general datepicker settings
|
||||||
|
@ -337,7 +339,8 @@ function rcube_tasklist_ui(settings)
|
||||||
$(input).datepicker('widget').find('button.ui-datepicker-close')
|
$(input).datepicker('widget').find('button.ui-datepicker-close')
|
||||||
.html(rcmail.gettext('nodate','tasklist'))
|
.html(rcmail.gettext('nodate','tasklist'))
|
||||||
.attr('onclick', '')
|
.attr('onclick', '')
|
||||||
.click(function(e){
|
.unbind('click')
|
||||||
|
.bind('click', function(e){
|
||||||
$(input).datepicker('setDate', null).datepicker('hide');
|
$(input).datepicker('setDate', null).datepicker('hide');
|
||||||
});
|
});
|
||||||
}, 1);
|
}, 1);
|
||||||
|
@ -570,7 +573,18 @@ function rcube_tasklist_ui(settings)
|
||||||
|
|
||||||
// append new tags to tag cloud
|
// append new tags to tag cloud
|
||||||
$.each(newtags, function(i, tag){
|
$.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
|
// re-sort tags list
|
||||||
|
@ -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',
|
revert: 'invalid',
|
||||||
addClasses: false,
|
addClasses: false,
|
||||||
cursorAt: { left:-10, top:12 },
|
cursorAt: { left:-10, top:12 },
|
||||||
helper: draggable_helper,
|
helper: task_draggable_helper,
|
||||||
appendTo: 'body',
|
appendTo: 'body',
|
||||||
start: draggable_start,
|
start: task_draggable_start,
|
||||||
stop: draggable_stop,
|
stop: task_draggable_stop,
|
||||||
revertDuration: 300
|
revertDuration: 300
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -769,7 +836,7 @@ function rcube_tasklist_ui(settings)
|
||||||
*/
|
*/
|
||||||
function resort_task(rec, li, animated)
|
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
|
// animated moving
|
||||||
var insert_animated = function(li, before, after) {
|
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
|
// 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_li = $(elem);
|
||||||
next_id = next_li.attr('rel');
|
next_id = next_li.attr('rel');
|
||||||
next_rec = listdata[next_id];
|
next_rec = listdata[next_id];
|
||||||
|
|
||||||
if (next_id == rec.id) {
|
if (next_id == rec.id) {
|
||||||
next_li = null;
|
past_myself = true;
|
||||||
return 1; // continue
|
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;
|
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);
|
if (animated) insert_animated(li, next_li);
|
||||||
else li.insertBefore(next_li);
|
else li.insertBefore(next_li);
|
||||||
next_li = null;
|
index = $.inArray(next_id, listindex);
|
||||||
return false;
|
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) {
|
next_id = insert_after.attr('rel');
|
||||||
if (animated) insert_animated(li, null, next_li);
|
index = $.inArray(next_id, listindex);
|
||||||
else li.insertAfter(next_li);
|
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert into list index
|
// insert into list index
|
||||||
|
@ -865,20 +935,20 @@ function rcube_tasklist_ui(settings)
|
||||||
|
|
||||||
/* Helper functions for drag & drop functionality */
|
/* Helper functions for drag & drop functionality */
|
||||||
|
|
||||||
function draggable_helper()
|
function task_draggable_helper()
|
||||||
{
|
{
|
||||||
if (!draghelper)
|
if (!task_draghelper)
|
||||||
draghelper = $('<div class="taskitem-draghelper">✔</div>');
|
task_draghelper = $('<div class="taskitem-draghelper">✔</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({
|
$('.taskhead, #rootdroppable, #'+rcmail.gui_objects.folderlist.id+' li').droppable({
|
||||||
hoverClass: 'droptarget',
|
hoverClass: 'droptarget',
|
||||||
accept: droppable_accept,
|
accept: task_droppable_accept,
|
||||||
drop: draggable_dropped,
|
drop: task_draggable_dropped,
|
||||||
addClasses: false
|
addClasses: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -886,13 +956,13 @@ function rcube_tasklist_ui(settings)
|
||||||
$('#rootdroppable').show();
|
$('#rootdroppable').show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function draggable_stop(event, ui)
|
function task_draggable_stop(event, ui)
|
||||||
{
|
{
|
||||||
$(this).parent().removeClass('dragging');
|
$(this).parent().removeClass('dragging');
|
||||||
$('#rootdroppable').hide();
|
$('#rootdroppable').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
function droppable_accept(draggable)
|
function task_droppable_accept(draggable)
|
||||||
{
|
{
|
||||||
if (rcmail.busy)
|
if (rcmail.busy)
|
||||||
return false;
|
return false;
|
||||||
|
@ -924,7 +994,7 @@ function rcube_tasklist_ui(settings)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function draggable_dropped(event, ui)
|
function task_draggable_dropped(event, ui)
|
||||||
{
|
{
|
||||||
var drop_id = $(this).data('id'),
|
var drop_id = $(this).data('id'),
|
||||||
task_id = ui.draggable.data('id'),
|
task_id = ui.draggable.data('id'),
|
||||||
|
@ -1220,6 +1290,9 @@ function rcube_tasklist_ui(settings)
|
||||||
if (!me.selected_task.list && list.id)
|
if (!me.selected_task.list && list.id)
|
||||||
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))
|
if (save_task(me.selected_task, action))
|
||||||
$dialog.dialog('close');
|
$dialog.dialog('close');
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue