Skip to content

Commit 5b72bdc

Browse files
authored
Merge pull request #335 from richardwalker-iamtech/master
Drag-and-drop nodes on touch devices
2 parents 0f8338b + 8eb689b commit 5b72bdc

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

src/js/jquery.orgchart.js

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,100 @@
10251025
.end().end().siblings().remove();
10261026
}
10271027
},
1028+
//
1029+
touchstartHandler: function (event) {
1030+
console.log("orgChart: touchstart 1: touchHandled=" + this.touchHandled + ", touchMoved=" + this.touchMoved + ", target=" + event.target.innerText);
1031+
if (this.touchHandled)
1032+
return;
1033+
this.touchHandled = true;
1034+
this.touchMoved = false; // this is so we can work out later if this was a 'press' or a 'drag' touch
1035+
event.preventDefault();
1036+
},
1037+
//
1038+
touchmoveHandler: function (event) {
1039+
if (!this.touchHandled)
1040+
return;
1041+
event.preventDefault();
1042+
if (!this.touchMoved) {
1043+
var nodeIsSelected = $(this).hasClass('focused');
1044+
console.log("orgChart: touchmove 1: " + event.touches.length + " touches, we have not moved, so simulate a drag start", event.touches);
1045+
// TODO: visualise the start of the drag (as would happen on desktop)
1046+
this.simulateMouseEvent(event, 'dragstart');
1047+
}
1048+
this.touchMoved = true;
1049+
var $touching = $(document.elementFromPoint(event.touches[0].clientX, event.touches[0].clientY));
1050+
var $touchingNode = $touching.closest('div.node');
1051+
1052+
if ($touchingNode.length > 0) {
1053+
var touchingNodeElement = $touchingNode[0];
1054+
// TODO: simulate the dragover visualisation
1055+
if ($touchingNode.is('.allowedDrop')) {
1056+
console.log("orgChart: touchmove 2: this node (" + touchingNodeElement.id + ") is allowed to be a drop target");
1057+
this.touchTargetNode = touchingNodeElement;
1058+
}
1059+
else {
1060+
console.log("orgChart: touchmove 3: this node (" + touchingNodeElement.id + ") is NOT allowed to be a drop target");
1061+
this.touchTargetNode = null;
1062+
}
1063+
}
1064+
else {
1065+
console.log("orgchart: touchmove 4: not touching a node");
1066+
this.touchTargetNode = null;
1067+
}
1068+
},
1069+
//
1070+
touchendHandler: function (event) {
1071+
console.log("orgChart: touchend 1: touchHandled=" + this.touchHandled + ", touchMoved=" + this.touchMoved + ", " + event.target.innerText + " ");
1072+
if (!this.touchHandled) {
1073+
console.log("orgChart: touchend 2: not handled by us, so aborting");
1074+
return;
1075+
}
1076+
if (this.touchMoved) {
1077+
// we've had movement, so this was a 'drag' touch
1078+
if (this.touchTargetNode) {
1079+
console.log("orgChart: touchend 3: moved to a node, so simulating drop");
1080+
var fakeEventForDropHandler = { delegateTarget: this.touchTargetNode };
1081+
this.dropHandler(fakeEventForDropHandler);
1082+
this.touchTargetNode = null;
1083+
}
1084+
console.log("orgChart: touchend 4: simulating dragend");
1085+
this.simulateMouseEvent(event, 'dragend');
1086+
}
1087+
else {
1088+
// we did not move, so assume this was a 'press' touch
1089+
console.log("orgChart: touchend 5: moved, so simulating click");
1090+
this.simulateMouseEvent(event, 'click');
1091+
}
1092+
this.touchHandled = false;
1093+
},
1094+
// simulate a mouse event (so we can fake them on a touch device)
1095+
simulateMouseEvent: function (event, simulatedType) {
1096+
// Ignore multi-touch events
1097+
if (event.originalEvent.touches.length > 1) {
1098+
return;
1099+
}
1100+
var touch = event.originalEvent.changedTouches[0];
1101+
var simulatedEvent = document.createEvent('MouseEvents');
1102+
simulatedEvent.initMouseEvent(
1103+
simulatedType, // type
1104+
true, // bubbles
1105+
true, // cancelable
1106+
window, // view
1107+
1, // detail
1108+
touch.screenX, // screenX
1109+
touch.screenY, // screenY
1110+
touch.clientX, // clientX
1111+
touch.clientY, // clientY
1112+
false, // ctrlKey
1113+
false, // altKey
1114+
false, // shiftKey
1115+
false, // metaKey
1116+
0, // button
1117+
null // relatedTarget
1118+
);
1119+
// Dispatch the simulated event to the target element
1120+
event.target.dispatchEvent(simulatedEvent);
1121+
},
10281122
// create node
10291123
createNode: function (nodeData, level, opts) {
10301124
var that = this;
@@ -1075,7 +1169,14 @@
10751169
$nodeDiv.on('dragstart', this.dragstartHandler.bind(this))
10761170
.on('dragover', this.dragoverHandler.bind(this))
10771171
.on('dragend', this.dragendHandler.bind(this))
1078-
.on('drop', this.dropHandler.bind(this));
1172+
.on('drop', this.dropHandler.bind(this))
1173+
.on('touchstart', this.touchstartHandler.bind(this))
1174+
.on('touchmove', this.touchmoveHandler.bind(this))
1175+
.on('touchend', this.touchendHandler.bind(this));
1176+
1177+
this.touchHandled = false;
1178+
this.touchMoved = false;
1179+
this.touchTargetNode = null;
10791180
}
10801181
// allow user to append dom modification after finishing node create of orgchart
10811182
if (opts.createNode) {

0 commit comments

Comments
 (0)