Skip to content

Commit 919f852

Browse files
committed
Add support for drag-and-drop of nodes on touch devices
1 parent 5b72bdc commit 919f852

File tree

6 files changed

+298
-105
lines changed

6 files changed

+298
-105
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "orgchart",
3-
"version": "2.0.15",
3+
"version": "2.0.16",
44
"homepage": "https://github.com/dabeng/OrgChart",
55
"authors": [
66
"dabeng <[email protected]>"

demo/js/jquery.orgchart.js

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,98 @@
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+
} else {
1059+
console.log("orgChart: touchmove 3: this node (" + touchingNodeElement.id + ") is NOT allowed to be a drop target");
1060+
this.touchTargetNode = null;
1061+
}
1062+
} else {
1063+
console.log("orgchart: touchmove 4: not touching a node");
1064+
this.touchTargetNode = null;
1065+
}
1066+
},
1067+
//
1068+
touchendHandler: function (event) {
1069+
console.log("orgChart: touchend 1: touchHandled=" + this.touchHandled + ", touchMoved=" + this.touchMoved + ", " + event.target.innerText + " ");
1070+
if (!this.touchHandled) {
1071+
console.log("orgChart: touchend 2: not handled by us, so aborting");
1072+
return;
1073+
}
1074+
if (this.touchMoved) {
1075+
// we've had movement, so this was a 'drag' touch
1076+
if (this.touchTargetNode) {
1077+
console.log("orgChart: touchend 3: moved to a node, so simulating drop");
1078+
var fakeEventForDropHandler = { delegateTarget: this.touchTargetNode };
1079+
this.dropHandler(fakeEventForDropHandler);
1080+
this.touchTargetNode = null;
1081+
}
1082+
console.log("orgChart: touchend 4: simulating dragend");
1083+
this.simulateMouseEvent(event, 'dragend');
1084+
}
1085+
else {
1086+
// we did not move, so assume this was a 'press' touch
1087+
console.log("orgChart: touchend 5: moved, so simulating click");
1088+
this.simulateMouseEvent(event, 'click');
1089+
}
1090+
this.touchHandled = false;
1091+
},
1092+
// simulate a mouse event (so we can fake them on a touch device)
1093+
simulateMouseEvent: function (event, simulatedType) {
1094+
// Ignore multi-touch events
1095+
if (event.originalEvent.touches.length > 1) {
1096+
return;
1097+
}
1098+
var touch = event.originalEvent.changedTouches[0];
1099+
var simulatedEvent = document.createEvent('MouseEvents');
1100+
simulatedEvent.initMouseEvent(
1101+
simulatedType, // type
1102+
true, // bubbles
1103+
true, // cancelable
1104+
window, // view
1105+
1, // detail
1106+
touch.screenX, // screenX
1107+
touch.screenY, // screenY
1108+
touch.clientX, // clientX
1109+
touch.clientY, // clientY
1110+
false, // ctrlKey
1111+
false, // altKey
1112+
false, // shiftKey
1113+
false, // metaKey
1114+
0, // button
1115+
null // relatedTarget
1116+
);
1117+
// Dispatch the simulated event to the target element
1118+
event.target.dispatchEvent(simulatedEvent);
1119+
},
10281120
// create node
10291121
createNode: function (nodeData, level, opts) {
10301122
var that = this;
@@ -1075,7 +1167,13 @@
10751167
$nodeDiv.on('dragstart', this.dragstartHandler.bind(this))
10761168
.on('dragover', this.dragoverHandler.bind(this))
10771169
.on('dragend', this.dragendHandler.bind(this))
1078-
.on('drop', this.dropHandler.bind(this));
1170+
.on('drop', this.dropHandler.bind(this))
1171+
.on('touchstart', this.touchstartHandler.bind(this))
1172+
.on('touchmove', this.touchmoveHandler.bind(this))
1173+
.on('touchend', this.touchendHandler.bind(this));
1174+
this.touchHandled = false;
1175+
this.touchMoved = false;
1176+
this.touchTargetNode = null;
10791177
}
10801178
// allow user to append dom modification after finishing node create of orgchart
10811179
if (opts.createNode) {

dist/js/jquery.orgchart.js

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,98 @@
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+
} else {
1059+
console.log("orgChart: touchmove 3: this node (" + touchingNodeElement.id + ") is NOT allowed to be a drop target");
1060+
this.touchTargetNode = null;
1061+
}
1062+
} else {
1063+
console.log("orgchart: touchmove 4: not touching a node");
1064+
this.touchTargetNode = null;
1065+
}
1066+
},
1067+
//
1068+
touchendHandler: function (event) {
1069+
console.log("orgChart: touchend 1: touchHandled=" + this.touchHandled + ", touchMoved=" + this.touchMoved + ", " + event.target.innerText + " ");
1070+
if (!this.touchHandled) {
1071+
console.log("orgChart: touchend 2: not handled by us, so aborting");
1072+
return;
1073+
}
1074+
if (this.touchMoved) {
1075+
// we've had movement, so this was a 'drag' touch
1076+
if (this.touchTargetNode) {
1077+
console.log("orgChart: touchend 3: moved to a node, so simulating drop");
1078+
var fakeEventForDropHandler = { delegateTarget: this.touchTargetNode };
1079+
this.dropHandler(fakeEventForDropHandler);
1080+
this.touchTargetNode = null;
1081+
}
1082+
console.log("orgChart: touchend 4: simulating dragend");
1083+
this.simulateMouseEvent(event, 'dragend');
1084+
}
1085+
else {
1086+
// we did not move, so assume this was a 'press' touch
1087+
console.log("orgChart: touchend 5: moved, so simulating click");
1088+
this.simulateMouseEvent(event, 'click');
1089+
}
1090+
this.touchHandled = false;
1091+
},
1092+
// simulate a mouse event (so we can fake them on a touch device)
1093+
simulateMouseEvent: function (event, simulatedType) {
1094+
// Ignore multi-touch events
1095+
if (event.originalEvent.touches.length > 1) {
1096+
return;
1097+
}
1098+
var touch = event.originalEvent.changedTouches[0];
1099+
var simulatedEvent = document.createEvent('MouseEvents');
1100+
simulatedEvent.initMouseEvent(
1101+
simulatedType, // type
1102+
true, // bubbles
1103+
true, // cancelable
1104+
window, // view
1105+
1, // detail
1106+
touch.screenX, // screenX
1107+
touch.screenY, // screenY
1108+
touch.clientX, // clientX
1109+
touch.clientY, // clientY
1110+
false, // ctrlKey
1111+
false, // altKey
1112+
false, // shiftKey
1113+
false, // metaKey
1114+
0, // button
1115+
null // relatedTarget
1116+
);
1117+
// Dispatch the simulated event to the target element
1118+
event.target.dispatchEvent(simulatedEvent);
1119+
},
10281120
// create node
10291121
createNode: function (nodeData, level, opts) {
10301122
var that = this;
@@ -1075,7 +1167,13 @@
10751167
$nodeDiv.on('dragstart', this.dragstartHandler.bind(this))
10761168
.on('dragover', this.dragoverHandler.bind(this))
10771169
.on('dragend', this.dragendHandler.bind(this))
1078-
.on('drop', this.dropHandler.bind(this));
1170+
.on('drop', this.dropHandler.bind(this))
1171+
.on('touchstart', this.touchstartHandler.bind(this))
1172+
.on('touchmove', this.touchmoveHandler.bind(this))
1173+
.on('touchend', this.touchendHandler.bind(this));
1174+
this.touchHandled = false;
1175+
this.touchMoved = false;
1176+
this.touchTargetNode = null;
10791177
}
10801178
// allow user to append dom modification after finishing node create of orgchart
10811179
if (opts.createNode) {

dist/js/jquery.orgchart.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "orgchart",
3-
"version": "2.0.15",
3+
"version": "2.0.16",
44
"description": "Simple and direct organization chart(tree-like hierarchy) plugin based on pure DOM and jQuery.",
55
"main": "./dist/js/jquery.orgchart.min.js",
66
"style": [

0 commit comments

Comments
 (0)