1 | import Hammer from '../../../module/hammer';
|
2 | import util from 'vis-util';
|
3 | import moment from '../../../module/moment';
|
4 |
|
5 | import '../css/item.css';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | function Item (data, conversion, options) {
|
17 | this.id = null;
|
18 | this.parent = null;
|
19 | this.data = data;
|
20 | this.dom = null;
|
21 | this.conversion = conversion || {};
|
22 | this.options = options || {};
|
23 | this.selected = false;
|
24 | this.displayed = false;
|
25 | this.groupShowing = true;
|
26 | this.dirty = true;
|
27 |
|
28 | this.top = null;
|
29 | this.right = null;
|
30 | this.left = null;
|
31 | this.width = null;
|
32 | this.height = null;
|
33 |
|
34 | this.editable = null;
|
35 | this._updateEditStatus();
|
36 | }
|
37 |
|
38 | Item.prototype.stack = true;
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | Item.prototype.select = function() {
|
44 | this.selected = true;
|
45 | this.dirty = true;
|
46 | if (this.displayed) this.redraw();
|
47 | };
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | Item.prototype.unselect = function() {
|
53 | this.selected = false;
|
54 | this.dirty = true;
|
55 | if (this.displayed) this.redraw();
|
56 | };
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | Item.prototype.setData = function(data) {
|
64 | var groupChanged = data.group != undefined && this.data.group != data.group;
|
65 | if (groupChanged && this.parent != null) {
|
66 | this.parent.itemSet._moveToGroup(this, data.group);
|
67 | }
|
68 |
|
69 | if (this.parent) {
|
70 | this.parent.stackDirty = true;
|
71 | }
|
72 |
|
73 | var subGroupChanged = data.subgroup != undefined && this.data.subgroup != data.subgroup;
|
74 | if (subGroupChanged && this.parent != null) {
|
75 | this.parent.changeSubgroup(this, this.data.subgroup, data.subgroup);
|
76 | }
|
77 |
|
78 | this.data = data;
|
79 | this._updateEditStatus();
|
80 | this.dirty = true;
|
81 | if (this.displayed) this.redraw();
|
82 | };
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 | Item.prototype.setParent = function(parent) {
|
89 | if (this.displayed) {
|
90 | this.hide();
|
91 | this.parent = parent;
|
92 | if (this.parent) {
|
93 | this.show();
|
94 | }
|
95 | }
|
96 | else {
|
97 | this.parent = parent;
|
98 | }
|
99 | };
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 | Item.prototype.isVisible = function(range) {
|
107 | return false;
|
108 | };
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 | Item.prototype.show = function() {
|
115 | return false;
|
116 | };
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | Item.prototype.hide = function() {
|
123 | return false;
|
124 | };
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | Item.prototype.redraw = function() {
|
130 |
|
131 | };
|
132 |
|
133 |
|
134 |
|
135 |
|
136 | Item.prototype.repositionX = function() {
|
137 |
|
138 | };
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | Item.prototype.repositionY = function() {
|
144 |
|
145 | };
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 | Item.prototype._repaintDragCenter = function () {
|
152 | if (this.selected && this.options.editable.updateTime && !this.dom.dragCenter) {
|
153 | var me = this;
|
154 |
|
155 | var dragCenter = document.createElement('div');
|
156 | dragCenter.className = 'vis-drag-center';
|
157 | dragCenter.dragCenterItem = this;
|
158 | var hammer = new Hammer(dragCenter);
|
159 |
|
160 | hammer.on('tap', function (event) {
|
161 | me.parent.itemSet.body.emitter.emit('click', {
|
162 | event: event,
|
163 | item: me.id
|
164 | });
|
165 | });
|
166 | hammer.on('doubletap', function (event) {
|
167 | event.stopPropagation();
|
168 | me.parent.itemSet._onUpdateItem(me);
|
169 | me.parent.itemSet.body.emitter.emit('doubleClick', {
|
170 | event: event,
|
171 | item: me.id
|
172 | });
|
173 | });
|
174 |
|
175 | if (this.dom.box) {
|
176 | if (this.dom.dragLeft) {
|
177 | this.dom.box.insertBefore(dragCenter, this.dom.dragLeft);
|
178 | }
|
179 | else {
|
180 | this.dom.box.appendChild(dragCenter);
|
181 | }
|
182 | }
|
183 | else if (this.dom.point) {
|
184 | this.dom.point.appendChild(dragCenter);
|
185 | }
|
186 |
|
187 | this.dom.dragCenter = dragCenter;
|
188 | }
|
189 | else if (!this.selected && this.dom.dragCenter) {
|
190 |
|
191 | if (this.dom.dragCenter.parentNode) {
|
192 | this.dom.dragCenter.parentNode.removeChild(this.dom.dragCenter);
|
193 | }
|
194 | this.dom.dragCenter = null;
|
195 | }
|
196 | };
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 | Item.prototype._repaintDeleteButton = function (anchor) {
|
204 | var editable = ((this.options.editable.overrideItems || this.editable == null) && this.options.editable.remove) ||
|
205 | (!this.options.editable.overrideItems && this.editable != null && this.editable.remove);
|
206 |
|
207 | if (this.selected && editable && !this.dom.deleteButton) {
|
208 |
|
209 | var me = this;
|
210 |
|
211 | var deleteButton = document.createElement('div');
|
212 |
|
213 | if (this.options.rtl) {
|
214 | deleteButton.className = 'vis-delete-rtl';
|
215 | } else {
|
216 | deleteButton.className = 'vis-delete';
|
217 | }
|
218 | deleteButton.title = 'Delete this item';
|
219 |
|
220 |
|
221 | new Hammer(deleteButton).on('tap', function (event) {
|
222 | event.stopPropagation();
|
223 | me.parent.removeFromDataSet(me);
|
224 | });
|
225 |
|
226 | anchor.appendChild(deleteButton);
|
227 | this.dom.deleteButton = deleteButton;
|
228 | }
|
229 | else if (!this.selected && this.dom.deleteButton) {
|
230 |
|
231 | if (this.dom.deleteButton.parentNode) {
|
232 | this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton);
|
233 | }
|
234 | this.dom.deleteButton = null;
|
235 | }
|
236 | };
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 | Item.prototype._repaintOnItemUpdateTimeTooltip = function (anchor) {
|
244 | if (!this.options.tooltipOnItemUpdateTime) return;
|
245 |
|
246 | var editable = (this.options.editable.updateTime ||
|
247 | this.data.editable === true) &&
|
248 | this.data.editable !== false;
|
249 |
|
250 | if (this.selected && editable && !this.dom.onItemUpdateTimeTooltip) {
|
251 | var onItemUpdateTimeTooltip = document.createElement('div');
|
252 |
|
253 | onItemUpdateTimeTooltip.className = 'vis-onUpdateTime-tooltip';
|
254 | anchor.appendChild(onItemUpdateTimeTooltip);
|
255 | this.dom.onItemUpdateTimeTooltip = onItemUpdateTimeTooltip;
|
256 |
|
257 | } else if (!this.selected && this.dom.onItemUpdateTimeTooltip) {
|
258 |
|
259 | if (this.dom.onItemUpdateTimeTooltip.parentNode) {
|
260 | this.dom.onItemUpdateTimeTooltip.parentNode.removeChild(this.dom.onItemUpdateTimeTooltip);
|
261 | }
|
262 | this.dom.onItemUpdateTimeTooltip = null;
|
263 | }
|
264 |
|
265 |
|
266 | if (this.dom.onItemUpdateTimeTooltip) {
|
267 |
|
268 |
|
269 | this.dom.onItemUpdateTimeTooltip.style.visibility = this.parent.itemSet.touchParams.itemIsDragging ? 'visible' : 'hidden';
|
270 |
|
271 |
|
272 | if (this.options.rtl) {
|
273 | this.dom.onItemUpdateTimeTooltip.style.right = this.dom.content.style.right;
|
274 | } else {
|
275 | this.dom.onItemUpdateTimeTooltip.style.left = this.dom.content.style.left;
|
276 | }
|
277 |
|
278 |
|
279 | var tooltipOffset = 50;
|
280 | var scrollTop = this.parent.itemSet.body.domProps.scrollTop;
|
281 |
|
282 |
|
283 |
|
284 | var itemDistanceFromTop
|
285 | if (this.options.orientation.item == 'top') {
|
286 | itemDistanceFromTop = this.top;
|
287 | } else {
|
288 | itemDistanceFromTop = (this.parent.height - this.top - this.height)
|
289 | }
|
290 | var isCloseToTop = itemDistanceFromTop + this.parent.top - tooltipOffset < -scrollTop;
|
291 |
|
292 | if (isCloseToTop) {
|
293 | this.dom.onItemUpdateTimeTooltip.style.bottom = "";
|
294 | this.dom.onItemUpdateTimeTooltip.style.top = this.height + 2 + "px";
|
295 | } else {
|
296 | this.dom.onItemUpdateTimeTooltip.style.top = "";
|
297 | this.dom.onItemUpdateTimeTooltip.style.bottom = this.height + 2 + "px";
|
298 | }
|
299 |
|
300 |
|
301 | var content;
|
302 | var templateFunction;
|
303 |
|
304 | if (this.options.tooltipOnItemUpdateTime && this.options.tooltipOnItemUpdateTime.template) {
|
305 | templateFunction = this.options.tooltipOnItemUpdateTime.template.bind(this);
|
306 | content = templateFunction(this.data);
|
307 | } else {
|
308 | content = 'start: ' + moment(this.data.start).format('MM/DD/YYYY hh:mm');
|
309 | if (this.data.end) {
|
310 | content += '<br> end: ' + moment(this.data.end).format('MM/DD/YYYY hh:mm');
|
311 | }
|
312 | }
|
313 | this.dom.onItemUpdateTimeTooltip.innerHTML = content;
|
314 | }
|
315 | };
|
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 | Item.prototype._updateContents = function (element) {
|
324 | var content;
|
325 | var changed;
|
326 | var templateFunction;
|
327 | var itemVisibleFrameContent;
|
328 | var visibleFrameTemplateFunction;
|
329 | var itemData = this.parent.itemSet.itemsData.get(this.id);
|
330 |
|
331 | var frameElement = this.dom.box || this.dom.point;
|
332 | var itemVisibleFrameContentElement = frameElement.getElementsByClassName('vis-item-visible-frame')[0]
|
333 |
|
334 | if (this.options.visibleFrameTemplate) {
|
335 | visibleFrameTemplateFunction = this.options.visibleFrameTemplate.bind(this);
|
336 | itemVisibleFrameContent = visibleFrameTemplateFunction(itemData, frameElement);
|
337 | } else {
|
338 | itemVisibleFrameContent = '';
|
339 | }
|
340 |
|
341 | if (itemVisibleFrameContentElement) {
|
342 | if ((itemVisibleFrameContent instanceof Object) && !(itemVisibleFrameContent instanceof Element)) {
|
343 | visibleFrameTemplateFunction(itemData, itemVisibleFrameContentElement)
|
344 | } else {
|
345 | changed = this._contentToString(this.itemVisibleFrameContent) !== this._contentToString(itemVisibleFrameContent);
|
346 | if (changed) {
|
347 |
|
348 | if (itemVisibleFrameContent instanceof Element) {
|
349 | itemVisibleFrameContentElement.innerHTML = '';
|
350 | itemVisibleFrameContentElement.appendChild(itemVisibleFrameContent);
|
351 | }
|
352 | else if (itemVisibleFrameContent != undefined) {
|
353 | itemVisibleFrameContentElement.innerHTML = itemVisibleFrameContent;
|
354 | }
|
355 | else {
|
356 | if (!(this.data.type == 'background' && this.data.content === undefined)) {
|
357 | throw new Error('Property "content" missing in item ' + this.id);
|
358 | }
|
359 | }
|
360 |
|
361 | this.itemVisibleFrameContent = itemVisibleFrameContent;
|
362 | }
|
363 | }
|
364 | }
|
365 |
|
366 | if (this.options.template) {
|
367 | templateFunction = this.options.template.bind(this);
|
368 | content = templateFunction(itemData, element, this.data);
|
369 | } else {
|
370 | content = this.data.content;
|
371 | }
|
372 |
|
373 | if ((content instanceof Object) && !(content instanceof Element)) {
|
374 | templateFunction(itemData, element)
|
375 | } else {
|
376 | changed = this._contentToString(this.content) !== this._contentToString(content);
|
377 | if (changed) {
|
378 |
|
379 | if (content instanceof Element) {
|
380 | element.innerHTML = '';
|
381 | element.appendChild(content);
|
382 | }
|
383 | else if (content != undefined) {
|
384 | element.innerHTML = content;
|
385 | }
|
386 | else {
|
387 | if (!(this.data.type == 'background' && this.data.content === undefined)) {
|
388 | throw new Error('Property "content" missing in item ' + this.id);
|
389 | }
|
390 | }
|
391 | this.content = content;
|
392 | }
|
393 | }
|
394 | };
|
395 |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 |
|
401 | Item.prototype._updateDataAttributes = function(element) {
|
402 | if (this.options.dataAttributes && this.options.dataAttributes.length > 0) {
|
403 | var attributes = [];
|
404 |
|
405 | if (Array.isArray(this.options.dataAttributes)) {
|
406 | attributes = this.options.dataAttributes;
|
407 | }
|
408 | else if (this.options.dataAttributes == 'all') {
|
409 | attributes = Object.keys(this.data);
|
410 | }
|
411 | else {
|
412 | return;
|
413 | }
|
414 |
|
415 | for (var i = 0; i < attributes.length; i++) {
|
416 | var name = attributes[i];
|
417 | var value = this.data[name];
|
418 |
|
419 | if (value != null) {
|
420 | element.setAttribute('data-' + name, value);
|
421 | }
|
422 | else {
|
423 | element.removeAttribute('data-' + name);
|
424 | }
|
425 | }
|
426 | }
|
427 | };
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 |
|
434 | Item.prototype._updateStyle = function(element) {
|
435 |
|
436 | if (this.style) {
|
437 | util.removeCssText(element, this.style);
|
438 | this.style = null;
|
439 | }
|
440 |
|
441 |
|
442 | if (this.data.style) {
|
443 | util.addCssText(element, this.data.style);
|
444 | this.style = this.data.style;
|
445 | }
|
446 | };
|
447 |
|
448 |
|
449 |
|
450 |
|
451 |
|
452 |
|
453 |
|
454 |
|
455 | Item.prototype._contentToString = function (content) {
|
456 | if (typeof content === 'string') return content;
|
457 | if (content && 'outerHTML' in content) return content.outerHTML;
|
458 | return content;
|
459 | };
|
460 |
|
461 |
|
462 |
|
463 |
|
464 | Item.prototype._updateEditStatus = function() {
|
465 | if (this.options) {
|
466 | if(typeof this.options.editable === 'boolean') {
|
467 | this.editable = {
|
468 | updateTime: this.options.editable,
|
469 | updateGroup: this.options.editable,
|
470 | remove: this.options.editable
|
471 | };
|
472 | } else if(typeof this.options.editable === 'object') {
|
473 | this.editable = {};
|
474 | util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, this.options.editable);
|
475 | }
|
476 | }
|
477 |
|
478 | if (!this.options || !(this.options.editable) || (this.options.editable.overrideItems !== true)) {
|
479 | if (this.data) {
|
480 | if (typeof this.data.editable === 'boolean') {
|
481 | this.editable = {
|
482 | updateTime: this.data.editable,
|
483 | updateGroup: this.data.editable,
|
484 | remove: this.data.editable
|
485 | }
|
486 | } else if (typeof this.data.editable === 'object') {
|
487 |
|
488 |
|
489 | this.editable = {};
|
490 | util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, this.data.editable);
|
491 | }
|
492 | }
|
493 | }
|
494 | };
|
495 |
|
496 |
|
497 |
|
498 |
|
499 |
|
500 | Item.prototype.getWidthLeft = function () {
|
501 | return 0;
|
502 | };
|
503 |
|
504 |
|
505 |
|
506 |
|
507 |
|
508 | Item.prototype.getWidthRight = function () {
|
509 | return 0;
|
510 | };
|
511 |
|
512 |
|
513 |
|
514 |
|
515 |
|
516 | Item.prototype.getTitle = function () {
|
517 | return this.data.title;
|
518 | };
|
519 |
|
520 | export default Item;
|