Fix drag and drop for toolbar widget

This commit is contained in:
Hadi Nategh 2022-06-07 17:18:56 +02:00
parent 29a46999f8
commit d32d2f554b
2 changed files with 104 additions and 55 deletions

View File

@ -247,8 +247,12 @@ export class et2_toolbar extends et2_DOMWidget implements et2_IInput
{ {
// Clear existing // Clear existing
this.div.empty(); this.div.empty();
this.actionbox.empty(); this.actionbox
this.actionlist.empty(); .removeClass('et2_toolbarDropArea')
.empty();
this.actionlist
.removeClass('et2_toolbarDropArea')
.empty();
let admin_setting = this.options.is_admin ? '<span class="toolbar-admin-pref" title="'+egw.lang('Admin settings')+' ..."></span>': ''; let admin_setting = this.options.is_admin ? '<span class="toolbar-admin-pref" title="'+egw.lang('Admin settings')+' ..."></span>': '';
const list_header = this.options.list_header == 'more'?true:false; const list_header = this.options.list_header == 'more'?true:false;
this.actionbox.append('<summary class="ui-toolbar-menulistHeader'+(!list_header?' list_header-short':' ')+'">'+(list_header?egw.lang('more')+' ...':'')+admin_setting+'</summary>'); this.actionbox.append('<summary class="ui-toolbar-menulistHeader'+(!list_header?' list_header-short':' ')+'">'+(list_header?egw.lang('more')+' ...':'')+admin_setting+'</summary>');
@ -394,7 +398,7 @@ export class et2_toolbar extends et2_DOMWidget implements et2_IInput
let dropdown = <Et2DropdownButton><unknown>loadWebComponent("et2-dropdown-button", { let dropdown = <Et2DropdownButton><unknown>loadWebComponent("et2-dropdown-button", {
id: this.id + "-" + action.id, id: this.id + "-" + action.id,
label: action.caption, label: action.caption,
class: this.preference[action.id] ? 'et2_toolbar-dropdown et2_toolbar_draggable et2_toolbar-dropdown-menulist' : 'et2_toolbar-dropdown et2_toolbar_draggable', class: this.preference[action.id] ? `et2_toolbar-dropdown et2_toolbar_draggable${this.id} et2_toolbar-dropdown-menulist` : `et2_toolbar-dropdown et2_toolbar_draggable${this.id}`,
onchange: function(ev) onchange: function(ev)
{ {
let action = that._actionManager.getActionById(dropdown.value); let action = that._actionManager.getActionById(dropdown.value);
@ -452,62 +456,103 @@ export class et2_toolbar extends et2_DOMWidget implements et2_IInput
let toolbar = this.actionlist.find('span[data-group]'), let toolbar = this.actionlist.find('span[data-group]'),
toolbox = this.actionbox, toolbox = this.actionbox,
menulist = jQuery(this.actionbox.children()[1]); menulist = jQuery(this.actionbox.children()[1]);
this.actionlist[0].classList.add(`et2_toolbar_dropzone_list${this.id}`);
this.actionbox[0].classList.add(`et2_toolbar_dropzone_more${this.id}`);
this.actions = actions; this.actions = actions;
let sToolbar = new Sortable(this.actionlist[0], { let dragPosition = {x:0,y:0};
group: { let dragTranslate = {x:0, y:0};
name: 'toolbar', let draggables = this.getDOMNode().querySelectorAll(`.et2_toolbar_draggable${this.id}`);
}, draggables.forEach(_item => {
animation: 150, interact(_item).draggable({
sort: false, startAxis: 'xy',
swapThreshold: 0.1, listeners: {
draggable: '.et2_toolbar_draggable', start: function(e)
//fallbackOnBody: true, {
dataIdAttr: 'id', dragPosition = {x:e.page.x, y:e.page.y};
onAdd: function(e) e.target.setAttribute('style', `width:${e.target.clientWidth}px !important`);
e.target.style.position = 'fixed';
e.target.style.transform =
`translate(${dragPosition.x}px, ${dragPosition.y}px)`;
},
move : function(e)
{
dragTranslate.x += e.delta.x;
dragTranslate.y += e.delta.y;
e.target.style.transform =
`translate(${dragTranslate.x}px, ${dragTranslate.y}px)`;
},
end : function (e)
{ {
that.set_prefered(e.item.id.replace(that.id + '-', ''), false);
that._build_menu(that.actions); that._build_menu(that.actions);
} }
}
}); });
toolbar.each((_index, _item) =>{ });
new Sortable(_item, { interact(`.et2_toolbar_dropzone_list${this.id}`).unset();
group: { interact(`.et2_toolbar_dropzone_list${this.id}`).dropzone({
name: 'toolbar', checker: function (
dragEvent, // related dragmove or dragend
event, // Touch, Pointer or Mouse Event
dropped, // bool default checker result
dropzone, // dropzone Interactable
dropzoneElement, // dropzone element
draggable, // draggable Interactable
draggableElement // draggable element
) {
return dropped && !dropzoneElement.contains(draggableElement);
}, },
swapThreshold: 0.1, accept: `.et2_toolbar_draggable${this.id}`,
animation: 150, ondrop: function(e)
draggable: '.et2_toolbar_draggable', {
sort: false that.set_prefered(e.draggable.target.id.replace(that.id + '-', ''), false);
}); that._build_menu(that.actions);
});
[this.actionbox[0], menulist[0]].forEach(_item => {
return new Sortable(_item, {
group: {
name: 'toolbar',
pull: 'clone'
}, },
animation: 150, ondragenter: function(e)
sort: false, {
swapThreshold: 0.1, e.target.classList.add('et2_toolbarDropArea');
draggable: '.et2_toolbar_draggable', },
onAdd: function (e) { ondragleave: function(e)
that.set_prefered(e.item.id.replace(that.id + '-', ''), true); {
if (that.actionlist.find(".et2_toolbar_draggable").length == 0) e.target.classList.remove('et2_toolbarDropArea');
}
});
interact(`.et2_toolbar_dropzone_more${this.id}`).unset();
interact(`.et2_toolbar_dropzone_more${this.id}`).dropzone({
checker: function (
dragEvent, // related dragmove or dragend
event, // Touch, Pointer or Mouse Event
dropped, // bool default checker result
dropzone, // dropzone Interactable
dropzoneElement, // dropzone element
draggable, // draggable Interactable
draggableElement // draggable element
) {
console.log(dragEvent);
return dropped && !dropzoneElement.contains(draggableElement);
},
accept: `.et2_toolbar_draggable${this.id}`,
ondrop: function(e)
{
that.set_prefered(e.draggable.target.id.replace(that.id + '-', ''), true);
if (that.actionlist.find(`.et2_toolbar_draggable${that.id}`).length == 0)
{ {
that.preference = {}; that.preference = {};
egw.set_preference(that.options.preference_app,that.options.preference_id,that.preference); egw.set_preference(that.options.preference_app,that.options.preference_id,that.preference);
} }
that._build_menu(that.actions); that._build_menu(that.actions);
}, },
onStart: function(e) { ondragenter: function(e)
jQuery(that.actionlist).addClass('et2_toolbarDropArea');
},
onEnd: function()
{ {
jQuery(that.actionlist).removeClass('et2_toolbarDropArea'); e.target.classList.add('et2_toolbarDropArea');
},
ondragleave: function(e)
{
e.target.classList.remove('et2_toolbarDropArea');
} }
}); });
});
toolbox.on('toggle', (e)=>{ toolbox.on('toggle', (e)=>{
const details = <HTMLDetailsElement>e.target; const details = <HTMLDetailsElement>e.target;
@ -555,7 +600,7 @@ export class et2_toolbar extends et2_DOMWidget implements et2_IInput
let button_options = { let button_options = {
}; };
let button = jQuery(document.createElement('button')) let button = jQuery(document.createElement('button'))
.addClass("et2_toolbar_draggable et2_button et2_button_text et2_button_with_image") .addClass(`et2_toolbar_draggable${this.id} et2_button et2_button_text et2_button_with_image`)
.attr('id', this.id+'-'+action.id) .attr('id', this.id+'-'+action.id)
.attr('type', 'button') .attr('type', 'button')
.appendTo(this.preference[action.id]?this.actionbox.children()[1]:jQuery('[data-group='+action.group+']',this.actionlist)); .appendTo(this.preference[action.id]?this.actionbox.children()[1]:jQuery('[data-group='+action.group+']',this.actionlist));

View File

@ -3131,7 +3131,11 @@ div.et2_toolbar_more h.ui-accordion-header {
} }
.et2_toolbarDropArea { .et2_toolbarDropArea {
border: 1px dashed lightgray; border: 2px dashed #d3d3d3;
padding: 0px;
background: #effaff;
border-radius: 3px;
padding-bottom: 2px;
} }
.et2_label > input.et2_checkbox { .et2_label > input.et2_checkbox {