From 93e2bd4b3cd03d54f8220e2c165c3736b1839bc2 Mon Sep 17 00:00:00 2001 From: josdejong Date: Wed, 15 Jan 2014 14:45:03 +0100 Subject: [PATCH] Implemented function `select` for the Timeline --- src/module/header.js | 2 +- src/timeline/Timeline.js | 9 ++++ src/timeline/component/Group.js | 9 ++++ src/timeline/component/GroupSet.js | 20 ++++++++ src/timeline/component/ItemSet.js | 74 +++++++++++++++++++++++++++++- 5 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/module/header.js b/src/module/header.js index d5fb94b6..18cb777d 100644 --- a/src/module/header.js +++ b/src/module/header.js @@ -8,7 +8,7 @@ * @date @@date * * @license - * Copyright (C) 2011-2013 Almende B.V, http://almende.com + * Copyright (C) 2011-2014 Almende B.V, http://almende.com * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js index cceebc7b..ec122d74 100644 --- a/src/timeline/Timeline.js +++ b/src/timeline/Timeline.js @@ -340,3 +340,12 @@ Timeline.prototype.getItemRange = function getItemRange() { max: (max != null) ? new Date(max) : null }; }; + +/** + * Change the item selection, and/or get currently selected items + * @param {Array} [ids] An array with zero or more ids of the items to be selected. + * @return {Array} ids The ids of the selected items + */ +Timeline.prototype.select = function select(ids) { + return this.content ? this.content.select(ids) : []; +}; diff --git a/src/timeline/component/Group.js b/src/timeline/component/Group.js index 74fac5dc..e95091f2 100644 --- a/src/timeline/component/Group.js +++ b/src/timeline/component/Group.js @@ -75,6 +75,15 @@ Group.prototype.setItems = function setItems(items) { } }; +/** + * Change the item selection, and/or get currently selected items + * @param {Array} [ids] An array with zero or more ids of the items to be selected. + * @return {Array} ids The ids of the selected items + */ +Group.prototype.select = function select(ids) { + return this.itemset ? this.itemset.select(ids) : []; +}; + /** * Repaint the item * @return {Boolean} changed diff --git a/src/timeline/component/GroupSet.js b/src/timeline/component/GroupSet.js index 970a83d6..79d13fdd 100644 --- a/src/timeline/component/GroupSet.js +++ b/src/timeline/component/GroupSet.js @@ -149,6 +149,26 @@ GroupSet.prototype.getGroups = function getGroups() { return this.groupsData; }; +/** + * Change the item selection, and/or get currently selected items + * @param {Array} [ids] An array with zero or more ids of the items to be selected. + * @return {Array} ids The ids of the selected items + */ +GroupSet.prototype.select = function select(ids) { + var selection = [], + groups = this.groups; + + // iterate over each of the groups + for (var id in groups) { + if (groups.hasOwnProperty(id)) { + var group = groups[id]; + selection = selection.concat(group.select(ids)); + } + } + + return selection; +}; + /** * Repaint the component * @return {Boolean} changed diff --git a/src/timeline/component/ItemSet.js b/src/timeline/component/ItemSet.js index f68a3572..4b5fa24a 100644 --- a/src/timeline/component/ItemSet.js +++ b/src/timeline/component/ItemSet.js @@ -53,8 +53,9 @@ function ItemSet(parent, depends, options) { } }; - this.items = {}; // object with an Item for every data item - this.queue = {}; // queue with id/actions: 'add', 'update', 'delete' + this.items = {}; // object with an Item for every data item + this.selection = []; // list with the ids of all selected nodes + this.queue = {}; // queue with id/actions: 'add', 'update', 'delete' this.stack = new Stack(this, Object.create(this.options)); this.conversion = null; @@ -110,6 +111,69 @@ ItemSet.prototype.setRange = function setRange(range) { this.range = range; }; +/** + * Change the item selection, and/or get currently selected items + * @param {Array} [ids] An array with zero or more ids of the items to be selected. + * @return {Array} ids The ids of the selected items + */ +ItemSet.prototype.select = function select(ids) { + var i, ii, id, item, selection; + + if (ids) { + if (!Array.isArray(ids)) { + throw new TypeError('Array expected'); + } + + // unselect currently selected items + for (i = 0, ii = this.selection.length; i < ii; i++) { + id = this.selection[i]; + item = this.items[id]; + if (item) item.unselect(); + } + + // select items + this.selection = []; + for (i = 0, ii = ids.length; i < ii; i++) { + id = ids[i]; + item = this.items[id]; + if (item) { + this.selection.push(id); + item.select(); + } + } + + // trigger a select event + selection = this.selection.concat([]); + events.trigger(this, 'select', { + ids: selection + }); + + if (this.controller) { + this.requestRepaint(); + } + } + else { + selection = this.selection.concat([]); + } + + return selection; +}; + +/** + * Deselect a selected item + * @param {String | Number} id + * @private + */ +ItemSet.prototype._deselect = function _deselect(id) { + var selection = this.selection; + for (var i = 0, ii = selection.length; i < ii; i++) { + if (selection[i] == id) { // non-strict comparison! + selection.splice(i, 1); + break; + } + } +}; + /** * Repaint the component * @return {Boolean} changed @@ -234,6 +298,7 @@ ItemSet.prototype.repaint = function repaint() { // create item if (constructor) { item = new constructor(me, itemData, options, defaultOptions); + item.id = id; changed++; } else { @@ -253,6 +318,11 @@ ItemSet.prototype.repaint = function repaint() { case 'remove': if (item) { + // remove the item from the set selected items + if (item.selected) { + me._deselect(id); + } + // remove DOM of the item changed += item.hide(); }