Browse Source

Dragging left and right side of a range almost working

css_transitions
josdejong 10 years ago
parent
commit
339d39ec3d
6 changed files with 149 additions and 57 deletions
  1. +1
    -1
      HISTORY.md
  2. +43
    -26
      src/timeline/component/ItemSet.js
  3. +28
    -11
      src/timeline/component/css/item.css
  4. +13
    -19
      src/timeline/component/item/Item.js
  5. +62
    -0
      src/timeline/component/item/ItemRange.js
  6. +2
    -0
      src/timeline/component/item/ItemRangeOverflow.js

+ 1
- 1
HISTORY.md View File

@ -6,7 +6,7 @@ http://visjs.org
### Timeline ### Timeline
- items can be dragged and deleted.
- items can be dragged and removed.
- Implemented options `selectable`, `editable`. - Implemented options `selectable`, `editable`.
- added events when dragging the custom time bar. - added events when dragging the custom time bar.

+ 43
- 26
src/timeline/component/ItemSet.js View File

@ -688,9 +688,34 @@ ItemSet.prototype._onDragStart = function (event) {
me = this; me = this;
if (item && item.selected) { if (item && item.selected) {
this.touchParams.items = this.getSelection().map(function (id) {
return me.items[id];
});
var dragLeftItem = event.target.dragLeftItem;
var dragRightItem = event.target.dragRightItem;
if (dragLeftItem) {
this.touchParams.itemProps = [{
item: dragLeftItem,
start: item.data.start.valueOf()
}];
}
else if (dragRightItem) {
this.touchParams.itemProps = [{
item: dragRightItem,
end: item.data.end.valueOf()
}];
}
else {
this.touchParams.itemProps = this.getSelection().map(function (id) {
var item = me.items[id];
var props = {
item: item
};
if ('start' in item.data) { props.start = item.data.start.valueOf() }
if ('end' in item.data) { props.end = item.data.end.valueOf() }
return props;
});
}
event.stopPropagation(); event.stopPropagation();
} }
@ -702,16 +727,16 @@ ItemSet.prototype._onDragStart = function (event) {
* @private * @private
*/ */
ItemSet.prototype._onDrag = function (event) { ItemSet.prototype._onDrag = function (event) {
if (this.touchParams.items) {
var deltaX = event.gesture.deltaX;
if (this.touchParams.itemProps) {
var deltaX = event.gesture.deltaX,
offset = deltaX / this.conversion.scale;
// adjust the offset of the items being dragged
this.touchParams.items.forEach(function (item) {
item.setOffset(deltaX);
// move
this.touchParams.itemProps.forEach(function (props) {
if ('start' in props) { props.item.data.start = new Date(props.start + offset); }
if ('end' in props) { props.item.data.end = new Date(props.end + offset); }
}); });
// TODO: stacking on dragend changes the order. (stacking orders by start date, which isn't yet changed)
// TODO: implement snapping to nice dates // TODO: implement snapping to nice dates
// TODO: implement dragging from one group to another // TODO: implement dragging from one group to another
@ -728,29 +753,21 @@ ItemSet.prototype._onDrag = function (event) {
* @private * @private
*/ */
ItemSet.prototype._onDragEnd = function (event) { ItemSet.prototype._onDragEnd = function (event) {
if (this.touchParams.items) {
var deltaX = event.gesture.deltaX,
scale = this.conversion.scale;
if (this.touchParams.itemProps) {
// prepare a changeset for the changed items // prepare a changeset for the changed items
var changes = this.touchParams.items.map(function (item) {
item.setOffset(0);
var changes = this.touchParams.itemProps.map(function (props) {
var change = { var change = {
id: item.id
id: props.item.id
}; };
if ('start' in item.data) {
change.start = new Date(item.data.start.valueOf() + deltaX / scale);
}
if ('end' in item.data) {
change.end = new Date(item.data.end.valueOf() + deltaX / scale);
}
if ('start' in props.item.data) { change.start = props.item.data.start; }
if ('end' in props.item.data) { change.end = props.item.data.end; }
// TODO: only fire changes when start or end is actually changed
return change; return change;
}); });
this.touchParams.items = null;
this.touchParams.itemProps = null;
// apply the changes to the data // apply the changes to the data
var dataset = this._myDataSet(); var dataset = this._myDataSet();

+ 28
- 11
src/timeline/component/css/item.css View File

@ -57,6 +57,7 @@
border-width: 1px; border-width: 1px;
border-radius: 2px; border-radius: 2px;
-moz-border-radius: 2px; /* For Firefox 3.6 and older */ -moz-border-radius: 2px; /* For Firefox 3.6 and older */
box-sizing: border-box;
} }
.vis.timeline .item.rangeoverflow { .vis.timeline .item.rangeoverflow {
@ -64,19 +65,11 @@
border-width: 1px; border-width: 1px;
border-radius: 2px; border-radius: 2px;
-moz-border-radius: 2px; /* For Firefox 3.6 and older */ -moz-border-radius: 2px; /* For Firefox 3.6 and older */
box-sizing: border-box;
} }
.vis.timeline .item.range .drag-left, .vis.timeline .item.rangeoverflow .drag-left {
cursor: w-resize;
z-index: 1000;
}
.vis.timeline .item.range .drag-right, .vis.timeline .item.rangeoverflow .drag-right {
cursor: e-resize;
z-index: 1000;
}
.vis.timeline .item.range .content, .vis.timeline .item.rangeoverflow .content {
.vis.timeline .item.range .content,
.vis.timeline .item.rangeoverflow .content {
position: relative; position: relative;
display: inline-block; display: inline-block;
} }
@ -107,3 +100,27 @@
right: -24px; right: -24px;
cursor: pointer; cursor: pointer;
} }
.vis.timeline .item.range .drag-left,
.vis.timeline .item.rangeoverflow .drag-left {
position: absolute;
width: 24px;
height: 100%;
top: 0;
left: -4px;
cursor: w-resize;
z-index: 10000;
}
.vis.timeline .item.range .drag-right,
.vis.timeline .item.rangeoverflow .drag-right {
position: absolute;
width: 24px;
height: 100%;
top: 0;
right: -4px;
cursor: e-resize;
z-index: 10001; /* a little higher z-index than .drag-left */
}

+ 13
- 19
src/timeline/component/item/Item.js View File

@ -87,35 +87,29 @@ Item.prototype.setOffset = function setOffset(offset) {
* @private * @private
*/ */
Item.prototype._repaintDeleteButton = function (anchor) { Item.prototype._repaintDeleteButton = function (anchor) {
// show/remove delete button
if (this.selected && !this.dom.deleteButton) { if (this.selected && !this.dom.deleteButton) {
// create and show button
var parent = this.parent; var parent = this.parent;
var id = this.id; var id = this.id;
this.dom.deleteButton = Item.createDeleteButton(function () {
var deleteButton = document.createElement('div');
deleteButton.className = 'delete';
deleteButton.title = 'Delete this item';
Hammer(deleteButton, {
preventDefault: true
}).on('tap', function () {
parent.removeItem(id); parent.removeItem(id);
}); });
anchor.appendChild(this.dom.deleteButton);
anchor.appendChild(deleteButton);
this.dom.deleteButton = deleteButton;
} }
else if (!this.selected && this.dom.deleteButton) { else if (!this.selected && this.dom.deleteButton) {
// remove button
if (this.dom.deleteButton.parentNode) { if (this.dom.deleteButton.parentNode) {
this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton); this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton);
} }
this.dom.deleteButton = null; this.dom.deleteButton = null;
} }
}; };
/**
* Create a delete button which can be attached to this item
* @param {function} callback Called when the button is clicked
* @returns {HTMLElement} deleteButton
*/
Item.createDeleteButton = function createDeleteButton (callback) {
var button = document.createElement('div');
button.className = 'delete';
Hammer(button, {
preventDefault: true
}).on('tap', callback);
return button;
};

+ 62
- 0
src/timeline/component/item/ItemRange.js View File

@ -68,6 +68,8 @@ ItemRange.prototype.repaint = function repaint() {
} }
this._repaintDeleteButton(dom.box); this._repaintDeleteButton(dom.box);
this._repaintDragLeft();
this._repaintDragRight();
// update class // update class
var className = (this.data.className? ' ' + this.data.className : '') + var className = (this.data.className? ' ' + this.data.className : '') +
@ -251,3 +253,63 @@ ItemRange.prototype.reposition = function reposition() {
dom.content.style.left = props.content.left + 'px'; dom.content.style.left = props.content.left + 'px';
} }
}; };
/**
* Repaint a drag area on the left side of the range when the range is selected
* @private
*/
ItemRange.prototype._repaintDragLeft = function () {
if (this.selected && !this.dom.dragLeft) {
// create and show drag area
var dragLeft = document.createElement('div');
dragLeft.className = 'drag-left';
dragLeft.dragLeftItem = this;
// TODO: this should be redundant?
Hammer(dragLeft, {
preventDefault: true
}).on('drag', function () {
//console.log('drag left')
});
this.dom.box.appendChild(dragLeft);
this.dom.dragLeft = dragLeft;
}
else if (!this.selected && this.dom.dragLeft) {
// delete drag area
if (this.dom.dragLeft.parentNode) {
this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft);
}
this.dom.dragLeft = null;
}
};
/**
* Repaint a drag area on the right side of the range when the range is selected
* @private
*/
ItemRange.prototype._repaintDragRight = function () {
if (this.selected && !this.dom.dragRight) {
// create and show drag area
var dragRight = document.createElement('div');
dragRight.className = 'drag-right';
dragRight.dragRightItem = this;
// TODO: this should be redundant?
Hammer(dragRight, {
preventDefault: true
}).on('drag', function () {
//console.log('drag right')
});
this.dom.box.appendChild(dragRight);
this.dom.dragRight = dragRight;
}
else if (!this.selected && this.dom.dragRight) {
// delete drag area
if (this.dom.dragRight.parentNode) {
this.dom.dragRight.parentNode.removeChild(this.dom.dragRight);
}
this.dom.dragRight = null;
}
};

+ 2
- 0
src/timeline/component/item/ItemRangeOverflow.js View File

@ -84,6 +84,8 @@ ItemRangeOverflow.prototype.repaint = function repaint() {
} }
this._repaintDeleteButton(dom.box); this._repaintDeleteButton(dom.box);
this._repaintDragLeft();
this._repaintDragRight();
// update class // update class
var className = (this.data.className? ' ' + this.data.className : '') + var className = (this.data.className? ' ' + this.data.className : '') +

Loading…
Cancel
Save