mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-29 01:59:39 +01:00
WIP DND:
- fix drag-hover not working smoothly - fix drop zone events being triggered by other draggable items (none et2action draggable)
This commit is contained in:
parent
d7beb18470
commit
ef6cf29ce1
@ -617,7 +617,7 @@ egwAction.prototype.execute = function(_senders, _target)
|
|||||||
|
|
||||||
if(!this._check_confirm_mass_selections(_senders, _target))
|
if(!this._check_confirm_mass_selections(_senders, _target))
|
||||||
{
|
{
|
||||||
this._check_confirm(_senders, _target);
|
return this._check_confirm(_senders, _target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,8 +214,9 @@ export function egwDragActionImplementation()
|
|||||||
}
|
}
|
||||||
|
|
||||||
node.setAttribute('draggable', true);
|
node.setAttribute('draggable', true);
|
||||||
node.addEventListener('dragstart', function(event) {
|
const dragstart = function(event) {
|
||||||
if(action) {
|
event.stopImmediatePropagation();
|
||||||
|
if (action) {
|
||||||
if (_context.isSelection(event)) return;
|
if (_context.isSelection(event)) return;
|
||||||
|
|
||||||
// Get all selected
|
// Get all selected
|
||||||
@ -245,11 +246,15 @@ export function egwDragActionImplementation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
event.dataTransfer.effectAllowed = 'copy';
|
||||||
|
|
||||||
if (event.dataTransfer.types.length == 0) {
|
if (event.dataTransfer.types.length == 0) {
|
||||||
// No file data? Abort: drag does nothing
|
// No file data? Abort: drag does nothing
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
event.dataTransfer.effectAllowed = 'linkMove';
|
||||||
}
|
}
|
||||||
// The helper function is called before the start function
|
// The helper function is called before the start function
|
||||||
// is evoked. Call the given callback function. The callback
|
// is evoked. Call the given callback function. The callback
|
||||||
@ -267,19 +272,30 @@ export function egwDragActionImplementation()
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!ai.helper)
|
if (!ai.helper) {
|
||||||
{
|
|
||||||
ai.helper = ai.defaultDDHelper(ai.selected);
|
ai.helper = ai.defaultDDHelper(ai.selected);
|
||||||
}
|
}
|
||||||
// Add a basic class to the helper in order to standardize the background layout
|
// Add a basic class to the helper in order to standardize the background layout
|
||||||
ai.helper[0].classList.add('et2_egw_action_ddHelper', 'ui-draggable-dragging');
|
ai.helper[0].classList.add('et2_egw_action_ddHelper', 'ui-draggable-dragging');
|
||||||
document.body.append(ai.helper[0]);
|
document.body.append(ai.helper[0]);
|
||||||
this.classList.add('drag--moving');
|
this.classList.add('drag--moving');
|
||||||
|
|
||||||
event.dataTransfer.setData('application/json', JSON.stringify(data))
|
event.dataTransfer.setData('application/json', JSON.stringify(data))
|
||||||
event.dataTransfer.effectAllowed = 'move';
|
|
||||||
|
|
||||||
event.dataTransfer.setDragImage(ai.helper[0], 12, 12);
|
event.dataTransfer.setDragImage(ai.helper[0], 12, 12);
|
||||||
} , false);
|
|
||||||
|
this.setAttribute('data-egwActionObjID', JSON.stringify(data.selected));
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragend = function(event){
|
||||||
|
const helper = document.querySelector('.et2_egw_action_ddHelper');
|
||||||
|
if (helper) helper.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Drag Event listeners
|
||||||
|
node.addEventListener('dragstart', dragstart , false);
|
||||||
|
node.addEventListener('dragend', dragend, false);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -425,53 +441,73 @@ export function egwDropActionImplementation()
|
|||||||
{
|
{
|
||||||
var ai = new egwActionImplementation();
|
var ai = new egwActionImplementation();
|
||||||
|
|
||||||
|
//keeps track of current drop element where dragged item's entered.
|
||||||
|
// it's necessary for dragenter/dragleave issue correction.
|
||||||
|
var currentDropEl = null;
|
||||||
|
|
||||||
ai.type = "drop";
|
ai.type = "drop";
|
||||||
|
|
||||||
ai.doRegisterAction = function(_aoi, _callback, _context)
|
ai.doRegisterAction = function(_aoi, _callback, _context)
|
||||||
{
|
{
|
||||||
var node = _aoi.getDOMNode()[0] ? _aoi.getDOMNode()[0] : _aoi.getDOMNode();
|
var node = _aoi.getDOMNode()[0] ? _aoi.getDOMNode()[0] : _aoi.getDOMNode();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
node.classList.add('et2dropzone');
|
node.classList.add('et2dropzone');
|
||||||
node.addEventListener('dragover', function (event) {
|
const dragover = function (event) {
|
||||||
if (event.preventDefault) {
|
if (event.preventDefault) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
event.dataTransfer.dropEffect = 'move';
|
if (!self.getTheDraggedDOM()) return ;
|
||||||
_aoi.triggerEvent(EGW_AI_DRAG_OVER, {event: event});//TODO: check this event
|
|
||||||
return false;
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
node.addEventListener('dragenter', function (event) {
|
const data = {
|
||||||
// stop the event from being fired for its children
|
event: event,
|
||||||
event.stopPropagation();
|
ui: self.getTheDraggedData()
|
||||||
|
};
|
||||||
|
_aoi.triggerEvent(EGW_AI_DRAG_OVER, data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragenter = function (event) {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
// don't trigger dragenter if we are entering the drag element
|
// don't trigger dragenter if we are entering the drag element
|
||||||
if (event.dataTransfer.getData('application/json') != '' || self.isTheDraggedDOM(this)) return;
|
// don't go further if the dragged element is no there (happens when a none et2 dragged element is being dragged)
|
||||||
|
if (!self.getTheDraggedDOM() || self.isTheDraggedDOM(this) || this == currentDropEl) return;
|
||||||
|
|
||||||
|
currentDropEl = event.currentTarget;
|
||||||
|
event.dataTransfer.dropEffect = 'link';
|
||||||
|
|
||||||
this.classList.add('drop-hover');
|
this.classList.add('drop-hover');
|
||||||
}, false);
|
|
||||||
|
|
||||||
node.addEventListener('drop', function (event) {
|
// stop the event from being fired for its children
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const drop = function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
// don't go further if the dragged element is no there (happens when a none et2 dragged element is being dragged)
|
||||||
|
if (!self.getTheDraggedDOM()) return ;
|
||||||
|
|
||||||
// remove the hover class
|
// remove the hover class
|
||||||
this.classList.remove('drop-hover');
|
this.classList.remove('drop-hover');
|
||||||
|
|
||||||
// clean up the helper dom
|
const helper = self.getHelperDOM();
|
||||||
const helper = document.querySelector('.et2_egw_action_ddHelper');
|
let ui = self.getTheDraggedData();
|
||||||
const ui = {
|
ui.position = {top: event.clientY, left: event.clientX};
|
||||||
position: {top: event.clientY, left: event.clientX},
|
ui.offset = {top: event.offsetY, left: event.offsetX};
|
||||||
offset: {top: event.offsetY, left: event.offsetX}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper) helper.remove();
|
|
||||||
|
|
||||||
let data = JSON.parse(event.dataTransfer.getData('application/json'));
|
let data = JSON.parse(event.dataTransfer.getData('application/json'));
|
||||||
|
|
||||||
if (!self.isAccepted(data, _context, _callback) || self.isTheDraggedDOM(this)) return;
|
if (!self.isAccepted(data, _context, _callback) || self.isTheDraggedDOM(this))
|
||||||
|
{
|
||||||
|
// clean up the helper dom
|
||||||
|
if (helper) helper.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let selected = data.selected.map((item) => {
|
let selected = data.selected.map((item) => {
|
||||||
return egw_getObjectManager(item.id, false)
|
return egw_getObjectManager(item.id, false)
|
||||||
@ -545,20 +581,41 @@ export function egwDropActionImplementation()
|
|||||||
// Set cursor back to auto. Seems FF can't handle cursor reversion
|
// Set cursor back to auto. Seems FF can't handle cursor reversion
|
||||||
jQuery('body').css({cursor: 'auto'});
|
jQuery('body').css({cursor: 'auto'});
|
||||||
|
|
||||||
_aoi.triggerEvent(EGW_AI_DRAG_OUT, {event: event});//TODO: check this event
|
_aoi.triggerEvent(EGW_AI_DRAG_OUT, {event: event, ui: self.getTheDraggedData()});
|
||||||
}, false);
|
|
||||||
|
|
||||||
node.addEventListener('dragleave', function (event) {
|
// clean up the helper dom
|
||||||
// stop the event from being fired for its children
|
if (helper) helper.remove();
|
||||||
event.stopPropagation();
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragleave = function (event) {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
// don't trigger dragleave if we are leaving the drag element
|
// don't trigger dragleave if we are leaving the drag element
|
||||||
if (event.dataTransfer.getData('application/json') != '') return;
|
// don't go further if the dragged element is no there (happens when a none et2 dragged element is being dragged)
|
||||||
|
if (!self.getTheDraggedDOM() || self.isTheDraggedDOM(this) || this == currentDropEl) return;
|
||||||
|
|
||||||
_aoi.triggerEvent(EGW_AI_DRAG_OUT, {event: event});//TODO: check this event
|
const data = {
|
||||||
|
event: event,
|
||||||
|
ui: self.getTheDraggedData()
|
||||||
|
};
|
||||||
|
|
||||||
|
_aoi.triggerEvent(EGW_AI_DRAG_OUT, data);
|
||||||
|
|
||||||
this.classList.remove('drop-hover');
|
this.classList.remove('drop-hover');
|
||||||
}, false);
|
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// DND Event listeners
|
||||||
|
node.addEventListener('dragover', dragover, false);
|
||||||
|
|
||||||
|
node.addEventListener('dragenter', dragenter, false);
|
||||||
|
|
||||||
|
node.addEventListener('drop', drop, false);
|
||||||
|
|
||||||
|
node.addEventListener('dragleave', dragleave, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -570,6 +627,33 @@ export function egwDropActionImplementation()
|
|||||||
return _dom.classList.contains('drag--moving');
|
return _dom.classList.contains('drag--moving');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ai.getTheDraggedDOM = function ()
|
||||||
|
{
|
||||||
|
return document.querySelector('.drag--moving');
|
||||||
|
}
|
||||||
|
|
||||||
|
ai.getHelperDOM = function ()
|
||||||
|
{
|
||||||
|
return document.querySelector('.et2_egw_action_ddHelper');
|
||||||
|
}
|
||||||
|
|
||||||
|
ai.getTheDraggedData = function()
|
||||||
|
{
|
||||||
|
let data = this.getTheDraggedDOM().dataset.egwactionobjid;
|
||||||
|
let selected = [];
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
data = JSON.parse(data);
|
||||||
|
selected = data.map((item)=>{return egw_getObjectManager(item.id, false)});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
draggable: this.getTheDraggedDOM(),
|
||||||
|
helper: this.getHelperDOM(),
|
||||||
|
selected: selected
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if given draggable is accepted for drop
|
// check if given draggable is accepted for drop
|
||||||
ai.isAccepted = function(_data, _context, _callback, _node)
|
ai.isAccepted = function(_data, _context, _callback, _node)
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ export function et2_dataview_rowAOI(_node)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (egwIsMobile()) {
|
if (egwIsMobile()) {
|
||||||
jQuery(_node).swipe({
|
/*jQuery(_node).swipe({
|
||||||
allowPageScroll: "vertical",
|
allowPageScroll: "vertical",
|
||||||
longTapThreshold: 10,
|
longTapThreshold: 10,
|
||||||
swipe: function (event, direction, distance)
|
swipe: function (event, direction, distance)
|
||||||
@ -131,7 +131,7 @@ export function et2_dataview_rowAOI(_node)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});*/
|
||||||
} else {
|
} else {
|
||||||
jQuery(_node).click(selectHandler);
|
jQuery(_node).click(selectHandler);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import "../jquery/jquery.noconflict.js";
|
|||||||
import "../jquery/mousewheel/mousewheel.js";
|
import "../jquery/mousewheel/mousewheel.js";
|
||||||
import '../jsapi/egw_inheritance.js';
|
import '../jsapi/egw_inheritance.js';
|
||||||
import {EGW_KEY_ENTER, EGW_KEY_SPACE} from '../egw_action/egw_action_constants.js';
|
import {EGW_KEY_ENTER, EGW_KEY_SPACE} from '../egw_action/egw_action_constants.js';
|
||||||
|
import interact from "@interactjs/interactjs";
|
||||||
/**
|
/**
|
||||||
* ui siemenu entry class
|
* ui siemenu entry class
|
||||||
* Basic sidebar menu implementation
|
* Basic sidebar menu implementation
|
||||||
@ -359,7 +359,8 @@ window.egw_fw_ui_tab = function(_parent, _contHeaderDiv, _contDiv, _icon, _callb
|
|||||||
// If dragging something over the tab, activate that app
|
// If dragging something over the tab, activate that app
|
||||||
var tab = this.headerDiv;
|
var tab = this.headerDiv;
|
||||||
this.headerDiv.addEventListener('dragenter', (event) => {
|
this.headerDiv.addEventListener('dragenter', (event) => {
|
||||||
tab._callbackObject.call(tab);
|
event.stopPropagation();
|
||||||
|
tab._callbackObject.call(tab);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user