Browse Source

Timeline editable can override items (#2284)

* Timeline:
* Add overrideItems sub-property to timeline.editable
* Change behavior to override item.editable when overrideItems=true
* Added new example for timeline/editing to higlight differeing editable behaviors.
* Update timeline doc to reflect addition of timeline.editable.overrideItems
* Timeline - fixed logic oversights found in editable override testing
* Timeline - enable changeGroup when item.editable = true and not overriden
* Timeline - Small format changes to documentation and example pages for overrideItems
codeClimate
Simon Morris 8 years ago
committed by Alexander Wunschik
parent
commit
a83ef017b1
5 changed files with 134 additions and 22 deletions
  1. +11
    -4
      docs/timeline/index.html
  2. +99
    -0
      examples/timeline/editing/overrideEditingItems.html
  3. +19
    -15
      lib/timeline/component/ItemSet.js
  4. +4
    -3
      lib/timeline/component/item/Item.js
  5. +1
    -0
      lib/timeline/optionsTimeline.js

+ 11
- 4
docs/timeline/index.html View File

@ -339,7 +339,7 @@ var items = new vis.DataSet([
<td>editable</td> <td>editable</td>
<td>Boolean</td> <td>Boolean</td>
<td>no</td> <td>no</td>
<td>Override the editable option of the timeline for a specific item.</td>
<td>Override the editable option of the timeline for a specific item (assuming <code>timeline.editable.overrideItems</code> is false).</td>
</table> </table>
<h3 id="groups">Groups</h3> <h3 id="groups">Groups</h3>
@ -545,6 +545,12 @@ function (option, path) {
<td><code>false</code></td> <td><code>false</code></td>
<td>If true, items can be dragged to another moment in time. See section <a href="#Editing_Items">Editing Items</a> for a detailed explanation.</td> <td>If true, items can be dragged to another moment in time. See section <a href="#Editing_Items">Editing Items</a> for a detailed explanation.</td>
</tr> </tr>
<tr parent="editable" class="hidden">
<td class="indent">editable.overrideItems</td>
<td>boolean</td>
<td><code>false</code></td>
<td>If true, item specific editable properties are overridden by timeline settings</td>
</tr>
<tr> <tr>
<td>end</td> <td>end</td>
@ -1041,7 +1047,7 @@ function (option, path) {
<td>verticalScroll</td> <td>verticalScroll</td>
<td>Boolean</td> <td>Boolean</td>
<td><code>false</code></td> <td><code>false</code></td>
<td> Show a vertical scroll on the side of the group list and link it to the scroll event when zoom is not triggered. Notice that defining this option as <code>true</code> will NOT override <code>horizontalScroll</code>. The scroll event will be vertically ignored, but a vertical scrollbar will be visible
<td> Show a vertical scroll on the side of the group list and link it to the scroll event when zoom is not triggered. Notice that defining this option as <code>true</code> will NOT override <code>horizontalScroll</code>. The scroll event will be vertically ignored, but a vertical scrollbar will be visible
</td> </td>
</tr> </tr>
@ -1566,12 +1572,13 @@ var options = {
add: true, // add new items by double tapping add: true, // add new items by double tapping
updateTime: true, // drag items horizontally updateTime: true, // drag items horizontally
updateGroup: true, // drag items from one group to another updateGroup: true, // drag items from one group to another
remove: true // delete an item by tapping the delete button top right
remove: true, // delete an item by tapping the delete button top right
overrideItems: false // allow these options to override item.editable
} }
};</pre> };</pre>
<p> <p>
Editing can be enabled/disabled for specific items. Setting the property <code>editable</code> to <code>true</code> or <code>false</code> on a data item will override the timeline option.
Editing can be enabled/disabled for specific items. Setting the property <code>editable</code> to <code>true</code> or <code>false</code> on a data item will override the timeline option except when <code>timeline.editable.overrideItems</code> is set to <code>true</code>.
</p> </p>
<pre class="prettyprint lang-js"> <pre class="prettyprint lang-js">

+ 99
- 0
examples/timeline/editing/overrideEditingItems.html View File

@ -0,0 +1,99 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Individual editable items</title>
<style>
body, html {
font-family: arial, sans-serif;
font-size: 11pt;
}
div.vis-editable,
div.vis-editable.vis-selected {
/* custom styling for editable items... */
}
div.vis-readonly,
div.vis-readonly.vis-selected {
/* custom styling for readonly items... */
background-color: #ff4500;
border-color: red;
color: white;
}
</style>
<script src="../../../dist/vis.js"></script>
<link href="../../../dist/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
<script src="../../googleAnalytics.js"></script>
</head>
<body>
<p>Specify individual items to be editable or readonly. Toggle edit options and override behavior from timeline.editable</p>
<div id="visualization"></div>
<p>
<form>
Timeline.editable = {</br>
<input name="add" type="checkbox" checked>add</input></br>
<input name="remove" type="checkbox" checked>remove</input></br>
<input name="updateGroup" type="checkbox">updateGroup</input></br>
<input name="updateTime" type="checkbox" checked>updateTime</input><br>
<input name="overrideItems" type="checkbox">overrideItems</input><br>
}
</form>
</p>
<script>
// create a DataSet with items
var items = new vis.DataSet([
{id: 1, content: 'Editable', editable: true, start: '2010-08-23', group: 1},
{id: 2, content: 'Editable', editable: true, start: '2010-08-23T23:00:00', group: 2},
{id: 3, content: 'Read-only', editable: false, start: '2010-08-24T16:00:00', group: 1},
{id: 4, content: 'Read-only', editable: false, start: '2010-08-26', end: '2010-09-02', group: 2},
{id: 5, content: 'Editable', editable: true, start: '2010-08-28', group: 1},
{id: 6, content: 'Read-only', editable: false, start: '2010-08-29', group: 2},
{id: 7, content: 'Editable', editable: true, start: '2010-08-31', end: '2010-09-03', group: 1},
{id: 8, content: 'Read-only', editable: false, start: '2010-09-04T12:00:00', group: 2},
{id: 9, content: 'Default', start: '2010-09-04', group: 1},
{id: 10, content: 'Default', start: '2010-08-24', group: 2}
]);
var groups = [
{
id: 1,
content: 'group 1'
},
{
id: 2,
content: 'group 2'
}
]
var container = document.getElementById('visualization');
var options = {
editable: {
add: true,
remove: true,
updateGroup: false,
updateTime: true,
overrideItems: false
} // default for all items
};
var timeline = new vis.Timeline(container, items, groups, options);
var updateEditOptions = function(e){
var changedOption = e.target.name;
var options = { editable: { } };
options.editable[changedOption] = e.target.checked;
timeline.setOptions(options);
};
var cbs = document.getElementsByTagName("input");
[].forEach.call(cbs, function(cb){
cb.onchange = updateEditOptions;
});
</script>
</body>
</html>

+ 19
- 15
lib/timeline/component/ItemSet.js View File

@ -48,7 +48,8 @@ function ItemSet(body, options) {
updateTime: false, updateTime: false,
updateGroup: false, updateGroup: false,
add: false, add: false,
remove: false
remove: false,
overrideItems: false
}, },
groupEditable: { groupEditable: {
@ -356,16 +357,17 @@ ItemSet.prototype.setOptions = function(options) {
if ('editable' in options) { if ('editable' in options) {
if (typeof options.editable === 'boolean') { if (typeof options.editable === 'boolean') {
this.options.editable.updateTime = options.editable;
this.options.editable.updateGroup = options.editable;
this.options.editable.add = options.editable;
this.options.editable.remove = options.editable;
this.options.editable.updateTime = options.editable;
this.options.editable.updateGroup = options.editable;
this.options.editable.add = options.editable;
this.options.editable.remove = options.editable;
this.options.editable.overrideItems = options.editable;
} }
else if (typeof options.editable === 'object') { else if (typeof options.editable === 'object') {
util.selectiveExtend(['updateTime', 'updateGroup', 'add', 'remove'], this.options.editable, options.editable);
util.selectiveExtend(['updateTime', 'updateGroup', 'add', 'remove', 'overrideItems'], this.options.editable, options.editable);
} }
} }
if ('groupEditable' in options) { if ('groupEditable' in options) {
if (typeof options.groupEditable === 'boolean') { if (typeof options.groupEditable === 'boolean') {
this.options.groupEditable.order = options.groupEditable; this.options.groupEditable.order = options.groupEditable;
@ -1216,14 +1218,15 @@ ItemSet.prototype._onDragStart = function (event) {
if (item && (item.selected || this.options.itemsAlwaysDraggable)) { if (item && (item.selected || this.options.itemsAlwaysDraggable)) {
if (!this.options.editable.updateTime &&
!this.options.editable.updateGroup &&
!item.editable) {
if (this.options.editable.overrideItems &&
!this.options.editable.updateTime &&
!this.options.editable.updateGroup) {
return; return;
} }
// override options.editable // override options.editable
if (item.editable === false) {
if ((item.editable === false || !item.editable)
&& !this.options.editable.overrideItems) {
return; return;
} }
@ -1358,7 +1361,8 @@ ItemSet.prototype._onDrag = function (event) {
//only calculate the new group for the item that's actually dragged //only calculate the new group for the item that's actually dragged
var selectedItem = this.touchParams.selectedItem; var selectedItem = this.touchParams.selectedItem;
var updateGroupAllowed = me.options.editable.updateGroup;
var updateGroupAllowed = me.options.editable.updateGroup ||
(!this.options.editable.overrideItems && selectedItem.editable === true);
var newGroupBase = null; var newGroupBase = null;
if (updateGroupAllowed && selectedItem) { if (updateGroupAllowed && selectedItem) {
if (selectedItem.data.group != undefined) { if (selectedItem.data.group != undefined) {
@ -1384,12 +1388,12 @@ ItemSet.prototype._onDrag = function (event) {
} }
var itemData = this._cloneItemData(props.item.data); // clone the data var itemData = this._cloneItemData(props.item.data); // clone the data
if (props.item.editable === false) {
if (props.item.editable === false && !me.options.editable.overrideItems) {
return; return;
} }
var updateTimeAllowed = me.options.editable.updateTime ||
props.item.editable === true;
var updateTimeAllowed = me.options.editable.updateTime || (
props.item.editable === true && !me.options.editable.overrideItems);
if (updateTimeAllowed) { if (updateTimeAllowed) {
if (props.dragLeft) { if (props.dragLeft) {
// drag left side of a range item // drag left side of a range item

+ 4
- 3
lib/timeline/component/item/Item.js View File

@ -146,9 +146,10 @@ Item.prototype.repositionY = function() {
* @protected * @protected
*/ */
Item.prototype._repaintDeleteButton = function (anchor) { Item.prototype._repaintDeleteButton = function (anchor) {
var editable = (this.options.editable.remove ||
this.data.editable === true) &&
this.data.editable !== false;
var editable = (this.options.editable.remove &&
this.options.editable.overrideItems)
|| (this.data.editable === true &&
!this.options.editable.overrideItems);
if (this.selected && editable && !this.dom.deleteButton) { if (this.selected && editable && !this.dom.deleteButton) {
// create and show button // create and show button

+ 1
- 0
lib/timeline/optionsTimeline.js View File

@ -36,6 +36,7 @@ let allOptions = {
remove: {boolean, 'undefined': 'undefined'}, remove: {boolean, 'undefined': 'undefined'},
updateGroup: {boolean, 'undefined': 'undefined'}, updateGroup: {boolean, 'undefined': 'undefined'},
updateTime: {boolean, 'undefined': 'undefined'}, updateTime: {boolean, 'undefined': 'undefined'},
overrideItems: {boolean, 'undefined': 'undefined'},
__type__: {boolean, object} __type__: {boolean, object}
}, },
end: {number, date, string, moment}, end: {number, date, string, moment},

Loading…
Cancel
Save