-
Notifications
You must be signed in to change notification settings - Fork 4
/
external-site-example.html
255 lines (223 loc) · 10.3 KB
/
external-site-example.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>This is an example to show data transfer to an external site</title>
<!-- ===================================================================================================================== -->
<script>
if (!("i2b2" in window)) i2b2 = {};
i2b2.sdx = {};
i2b2.sdx.dd_events = {};
// List of acceptable SDX data types (modify to use only the types you need)
i2b2.sdx.TypeControllers = {
"CONCPT":{},
"QGDEF":{},
"QM":{},
"QI":{},
"PRC":{},
"PRS":{},
"ENS":{},
"PR":{},
"QDEF":{},
"WRK":{},
"XML":{}
};
//===========================================================
i2b2.sdx.AttachType = function(container, typeCode) {
// change the container into a DOM element reference
if (typeof container === "string") {
container = document.getElementById(container);
if (container.length === 0) {
container = null;
}
}
// manage if it is a document reference
if (container && container.length > 0) {
container = container[0];
}
//no valid container provided
if (!container) return false;
// add class for target bubbling
container.classList.add("i2b2DropTarget");
// confirm that it is a proper DOM node
let attrlist = [
"ondrag",
"ondragend",
"ondragenter",
"ondragover"
];
let isDomEl = true;
while (attrlist.length) {
if (typeof container[attrlist.pop()] !== "object") { isDomEl = false; }
}
// improper reference to a DOM element or element does not exist
if (!isDomEl) {
return false;
} else {
['drop', 'dragover', 'dragenter', 'dragleave'].forEach(function(e) {
container.addEventListener(e, i2b2.sdx.onDragDropEvents);
// save sdx type as valid for drop
let acceptedtypes = container.dataset.RegSdxTypes;
if (acceptedtypes === undefined) acceptedtypes = "[]";
let temp = JSON.parse(acceptedtypes);
temp.push(typeCode);
container.dataset.RegSdxTypes = JSON.stringify([...new Set(temp)]);
});
return true;
}
};
//===========================================================
i2b2.sdx.onDragDropEvents = function(e,a) {
// get a list of SDX types that are in this DD operation
let sdxTypeList = [];
for (let i in e.dataTransfer.types) {
if (String(e.dataTransfer.types[i]).toLowerCase().indexOf("application/i2b2-sdxtype+") === 0) {
let sdxTypes = String(e.dataTransfer.types[i]).toUpperCase().split("+");
sdxTypes.shift();
sdxTypeList = sdxTypeList.concat(sdxTypes);
}
}
let eventHandlers = i2b2.sdx.dd_events[this.id];
const acceptedtypes = JSON.parse(this.dataset.RegSdxTypes)
switch(e.type) {
case "drop":
// forward the event to the drop handler passing the object being dropped
while (sdxTypeList.length) {
let sdxType = sdxTypeList.pop();
if (typeof eventHandlers[sdxType] === "object" && typeof eventHandlers[sdxType].DropHandler === "function") {
let sdxJSON = JSON.parse(e.dataTransfer.getData("application/i2b2+json"));
eventHandlers[sdxType].DropHandler(sdxJSON, e);
}
}
e.stopImmediatePropagation();
e.currentTarget.classList.remove('dragging');
break;
case "dragover":
// enable drop if a drop handler exists for the object being dropped
while (sdxTypeList.length) {
let sdxType = sdxTypeList.pop();
if (acceptedtypes.includes(sdxType)) e.currentTarget.classList.add('dragging');
if (typeof eventHandlers[sdxType] === "object" && typeof eventHandlers[sdxType].DropHandler === "function") {
if (typeof eventHandlers[sdxType].DropChecker === "function") {
if (eventHandlers[sdxType].DropChecker(e.target, e, this)) {
// this is REQUIRED for proper drop
e.preventDefault();
}
} else {
// this is REQUIRED for proper drop
e.preventDefault();
}
}
}
break;
case "dragenter":
while (sdxTypeList.length) {
let sdxType = sdxTypeList.pop();
if (acceptedtypes.includes(sdxType)) e.currentTarget.classList.add('dragging');
if (typeof eventHandlers[sdxType] === "object" && typeof eventHandlers[sdxType].onHoverOver === "function") {
eventHandlers[sdxType].onHoverOver(e.target);
}
}
e.preventDefault();
break;
case "dragleave":
while (sdxTypeList.length) {
let sdxType = sdxTypeList.pop();
if (typeof eventHandlers[sdxType] === "object" && typeof eventHandlers[sdxType].onHoverOut === "function") {
eventHandlers[sdxType].onHoverOut(e.target);
}
}
e.preventDefault();
e.currentTarget.classList.remove('dragging');
break;
}
return false;
};
//===========================================================
i2b2.sdx.setHandlerCustom = function(container, typeCode, handlerName, newHandlerFunction) {
// containerID: string
// typeCode: string
// handlerName: string (example: DropHandler)
// newHandlerFunction: function to be used
// change the container into a DOM element reference
if (typeof container === "string") {
container = document.getElementById(container);
if (container.length === 0) {
container = null;
}
}
// manage if it is a document reference
if (container && container.length > 0) {
container = container[0];
}
//no valid container provided
if(!container){
return false;
}
// confirm that it is a proper DOM node
let attrlist = [
"ondrag",
"ondragend",
"ondragenter",
"ondragover"
];
let isDomEl = true;
while (attrlist.length) {
if (typeof container[attrlist.pop()] !== "object") {
isDomEl = false;
}
}
// improper reference to a DOM element or element does not exist
if (!isDomEl) {
return false;
} else {
if (typeof i2b2.sdx.dd_events[container.id] === "undefined") {
i2b2.sdx.dd_events[container.id] = {};
}
if (typeof i2b2.sdx.dd_events[container.id][typeCode] === "undefined") {
i2b2.sdx.dd_events[container.id][typeCode] = {};
}
// add new events
i2b2.sdx.dd_events[container.id][typeCode][handlerName] = newHandlerFunction;
return true;
}
};
</script>
<!-- ===================================================================================================================== -->
<!-- ===================================================================================================================== -->
<style>
.i2b2DropTarget {
background: lightgrey;
}
.i2b2DropTarget.dragging {
border-width: 3px !important;
background-color: #99CC99;
}
</style>
<!-- ===================================================================================================================== -->
</head>
<body>
<pre style="font-size:1.4rem">
This is an example of how to accept drag/drop operations from the i2b2 web client running in another window.
Drag and drop any i2b2 object onto the DIV below. The ".i2b2DropTarget" CSS class is applied to all containers
that are registered at i2b2 SDX drop targets. The ".i2b2DropTarget.dragging" CSS classes are applied to a
registered container that has a drag/drop operation occuring on it which contains a SDX data type that it has
been registered to accept. When the drop occurs your registered event handler is called with the SDX data object
being passed to it as the only parameter. See your browser's debug window console to view the data passed from
the main i2b2 web client window.
</pre>
<div style="width:50%; height:50%; left:25%; position:absolute; border:solid 1px" id="targetDiv"></div>
<script>
let funcDropHandler = function(data) {
console.dir(data);
alert("Drop Received");
};
Object.keys(i2b2.sdx.TypeControllers).forEach((sdxTypeCode) => {
// attach the SDX type to the container
i2b2.sdx.AttachType("targetDiv", sdxTypeCode);
// register a handler function for when that SDX type is dropped onto the container
i2b2.sdx.setHandlerCustom("targetDiv", sdxTypeCode, "DropHandler", funcDropHandler);
});
</script>
</body>
</html>