|  | @ -128,13 +128,14 @@ DataSet.prototype._trigger = function (event, params, senderId) { | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | /** |  |  | /** | 
														
													
														
															
																|  |  | * Add data. Existing items with the same id will be overwritten. |  |  |  | 
														
													
														
															
																|  |  |  |  |  | * Add data. | 
														
													
														
															
																|  |  |  |  |  | * Adding an item will fail when there already is an item with the same id. | 
														
													
														
															
																|  |  | * @param {Object | Array | DataTable} data |  |  | * @param {Object | Array | DataTable} data | 
														
													
														
															
																|  |  | * @param {String} [senderId] Optional sender id, used to trigger events for |  |  | * @param {String} [senderId] Optional sender id, used to trigger events for | 
														
													
														
															
																|  |  | *                            all but this sender's event subscribers. |  |  | *                            all but this sender's event subscribers. | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  | DataSet.prototype.add = function (data, senderId) { |  |  | DataSet.prototype.add = function (data, senderId) { | 
														
													
														
															
																|  |  | var items = [], |  |  |  | 
														
													
														
															
																|  |  |  |  |  | var addedItems = [], | 
														
													
														
															
																|  |  | id, |  |  | id, | 
														
													
														
															
																|  |  | me = this; |  |  | me = this; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
												
													
														
															
																|  | @ -142,7 +143,7 @@ DataSet.prototype.add = function (data, senderId) { | 
														
													
														
															
																|  |  | // Array |  |  | // Array | 
														
													
														
															
																|  |  | data.forEach(function (item) { |  |  | data.forEach(function (item) { | 
														
													
														
															
																|  |  | var id = me._addItem(item); |  |  | var id = me._addItem(item); | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | addedItems.push(id); | 
														
													
														
															
																|  |  | }); |  |  | }); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else if (util.isDataTable(data)) { |  |  | else if (util.isDataTable(data)) { | 
														
													
												
													
														
															
																|  | @ -154,37 +155,53 @@ DataSet.prototype.add = function (data, senderId) { | 
														
													
														
															
																|  |  | item[field] = data.getValue(row, col); |  |  | item[field] = data.getValue(row, col); | 
														
													
														
															
																|  |  | }); |  |  | }); | 
														
													
														
															
																|  |  | id = me._addItem(item); |  |  | id = me._addItem(item); | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | addedItems.push(id); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else if (data instanceof Object) { |  |  | else if (data instanceof Object) { | 
														
													
														
															
																|  |  | // Single item |  |  | // Single item | 
														
													
														
															
																|  |  | id = me._addItem(data); |  |  | id = me._addItem(data); | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | addedItems.push(id); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else { |  |  | else { | 
														
													
														
															
																|  |  | throw new Error('Unknown dataType'); |  |  | throw new Error('Unknown dataType'); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | this._trigger('add', {items: items}, senderId); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (addedItems.length) { | 
														
													
														
															
																|  |  |  |  |  | this._trigger('add', {items: addedItems}, senderId); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | /** |  |  | /** | 
														
													
														
															
																|  |  | * Update existing items. Items with the same id will be merged |  |  |  | 
														
													
														
															
																|  |  |  |  |  | * Update existing items. When an item does not exist, it will be created | 
														
													
														
															
																|  |  | * @param {Object | Array | DataTable} data |  |  | * @param {Object | Array | DataTable} data | 
														
													
														
															
																|  |  | * @param {String} [senderId] Optional sender id, used to trigger events for |  |  | * @param {String} [senderId] Optional sender id, used to trigger events for | 
														
													
														
															
																|  |  | *                            all but this sender's event subscribers. |  |  | *                            all but this sender's event subscribers. | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  | DataSet.prototype.update = function (data, senderId) { |  |  | DataSet.prototype.update = function (data, senderId) { | 
														
													
														
															
																|  |  | var items = [], |  |  |  | 
														
													
														
															
																|  |  | id, |  |  |  | 
														
													
														
															
																|  |  | me = this; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | var addedItems = [], | 
														
													
														
															
																|  |  |  |  |  | updatedItems = [], | 
														
													
														
															
																|  |  |  |  |  | me = this, | 
														
													
														
															
																|  |  |  |  |  | fieldId = me.fieldId; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | var addOrUpdate = function (item) { | 
														
													
														
															
																|  |  |  |  |  | var id = item[fieldId]; | 
														
													
														
															
																|  |  |  |  |  | if (me.data[id]) { | 
														
													
														
															
																|  |  |  |  |  | // update item | 
														
													
														
															
																|  |  |  |  |  | id = me._updateItem(item); | 
														
													
														
															
																|  |  |  |  |  | updatedItems.push(id); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | else { | 
														
													
														
															
																|  |  |  |  |  | // add new item | 
														
													
														
															
																|  |  |  |  |  | id = me._addItem(item); | 
														
													
														
															
																|  |  |  |  |  | addedItems.push(id); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | if (data instanceof Array) { |  |  | if (data instanceof Array) { | 
														
													
														
															
																|  |  | // Array |  |  | // Array | 
														
													
														
															
																|  |  | data.forEach(function (item) { |  |  | data.forEach(function (item) { | 
														
													
														
															
																|  |  | var id = me._updateItem(item); |  |  |  | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | addOrUpdate(item); | 
														
													
														
															
																|  |  | }); |  |  | }); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else if (util.isDataTable(data)) { |  |  | else if (util.isDataTable(data)) { | 
														
													
												
													
														
															
																|  | @ -195,20 +212,23 @@ DataSet.prototype.update = function (data, senderId) { | 
														
													
														
															
																|  |  | columns.forEach(function (field, col) { |  |  | columns.forEach(function (field, col) { | 
														
													
														
															
																|  |  | item[field] = data.getValue(row, col); |  |  | item[field] = data.getValue(row, col); | 
														
													
														
															
																|  |  | }); |  |  | }); | 
														
													
														
															
																|  |  | id = me._updateItem(item); |  |  |  | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | addOrUpdate(item); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else if (data instanceof Object) { |  |  | else if (data instanceof Object) { | 
														
													
														
															
																|  |  | // Single item |  |  | // Single item | 
														
													
														
															
																|  |  | id = me._updateItem(data); |  |  |  | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | addOrUpdate(data); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else { |  |  | else { | 
														
													
														
															
																|  |  | throw new Error('Unknown dataType'); |  |  | throw new Error('Unknown dataType'); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | this._trigger('update', {items: items}, senderId); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (addedItems.length) { | 
														
													
														
															
																|  |  |  |  |  | this._trigger('add', {items: addedItems}, senderId); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | if (updatedItems.length) { | 
														
													
														
															
																|  |  |  |  |  | this._trigger('update', {items: updatedItems}, senderId); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | /** |  |  | /** | 
														
													
												
													
														
															
																|  | @ -440,19 +460,19 @@ DataSet.prototype._mergeFieldTypes = function (fieldTypes) { | 
														
													
														
															
																|  |  | *                            all but this sender's event subscribers. |  |  | *                            all but this sender's event subscribers. | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  | DataSet.prototype.remove = function (id, senderId) { |  |  | DataSet.prototype.remove = function (id, senderId) { | 
														
													
														
															
																|  |  | var items = [], |  |  |  | 
														
													
														
															
																|  |  |  |  |  | var removedItems = [], | 
														
													
														
															
																|  |  | me = this; |  |  | me = this; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | if (util.isNumber(id) || util.isString(id)) { |  |  | if (util.isNumber(id) || util.isString(id)) { | 
														
													
														
															
																|  |  | delete this.data[id]; |  |  | delete this.data[id]; | 
														
													
														
															
																|  |  | delete this.internalIds[id]; |  |  | delete this.internalIds[id]; | 
														
													
														
															
																|  |  | items.push(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | removedItems.push(id); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else if (id instanceof Array) { |  |  | else if (id instanceof Array) { | 
														
													
														
															
																|  |  | id.forEach(function (id) { |  |  | id.forEach(function (id) { | 
														
													
														
															
																|  |  | me.remove(id); |  |  | me.remove(id); | 
														
													
														
															
																|  |  | }); |  |  | }); | 
														
													
														
															
																|  |  | items = items.concat(id); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | removedItems = items.concat(id); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else if (id instanceof Object) { |  |  | else if (id instanceof Object) { | 
														
													
														
															
																|  |  | // search for the object |  |  | // search for the object | 
														
													
												
													
														
															
																|  | @ -461,13 +481,15 @@ DataSet.prototype.remove = function (id, senderId) { | 
														
													
														
															
																|  |  | if (this.data[i] == id) { |  |  | if (this.data[i] == id) { | 
														
													
														
															
																|  |  | delete this.data[i]; |  |  | delete this.data[i]; | 
														
													
														
															
																|  |  | delete this.internalIds[i]; |  |  | delete this.internalIds[i]; | 
														
													
														
															
																|  |  | items.push(i); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | removedItems.push(i); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | this._trigger('remove', {items: items}, senderId); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (removedItems.length) { | 
														
													
														
															
																|  |  |  |  |  | this._trigger('remove', {items: removedItems}, senderId); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | /** |  |  | /** | 
														
													
												
													
														
															
																|  | @ -566,18 +588,25 @@ DataSet.prototype.distinct = function (field) { | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | /** |  |  | /** | 
														
													
														
															
																|  |  | * Add a single item |  |  |  | 
														
													
														
															
																|  |  |  |  |  | * Add a single item. Will fail when an item with the same id already exists. | 
														
													
														
															
																|  |  | * @param {Object} item |  |  | * @param {Object} item | 
														
													
														
															
																|  |  | * @return {String} id |  |  | * @return {String} id | 
														
													
														
															
																|  |  | * @private |  |  | * @private | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  | DataSet.prototype._addItem = function (item) { |  |  | DataSet.prototype._addItem = function (item) { | 
														
													
														
															
																|  |  | var id = item[this.fieldId]; |  |  | var id = item[this.fieldId]; | 
														
													
														
															
																|  |  | if (id == undefined) { |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (id != undefined) { | 
														
													
														
															
																|  |  |  |  |  | // check whether this id is already taken | 
														
													
														
															
																|  |  |  |  |  | if (this.data[id]) { | 
														
													
														
															
																|  |  |  |  |  | // item already exists | 
														
													
														
															
																|  |  |  |  |  | throw new Error('Cannot add item: item with id ' + id + ' already exists'); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | else { | 
														
													
														
															
																|  |  | // generate an id |  |  | // generate an id | 
														
													
														
															
																|  |  | id = util.randomUUID(); |  |  | id = util.randomUUID(); | 
														
													
														
															
																|  |  | item[this.fieldId] = id; |  |  | item[this.fieldId] = id; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | this.internalIds[id] = item; |  |  | this.internalIds[id] = item; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
												
													
														
															
																|  | @ -589,7 +618,6 @@ DataSet.prototype._addItem = function (item) { | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | this.data[id] = d; |  |  | this.data[id] = d; | 
														
													
														
															
																|  |  | //TODO: fail when an item with this id already exists? |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | return id; |  |  | return id; | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
												
													
														
															
																|  | @ -636,7 +664,9 @@ DataSet.prototype._castItem = function (item, fieldTypes, fields) { | 
														
													
														
															
																|  |  | }; |  |  | }; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | /** |  |  | /** | 
														
													
														
															
																|  |  | * Update a single item: merge with existing item |  |  |  | 
														
													
														
															
																|  |  |  |  |  | * Update a single item: merge with existing item. | 
														
													
														
															
																|  |  |  |  |  | * Will fail when the item has no id, or when there does not exist an item | 
														
													
														
															
																|  |  |  |  |  | * with the same id. | 
														
													
														
															
																|  |  | * @param {Object} item |  |  | * @param {Object} item | 
														
													
														
															
																|  |  | * @return {String} id |  |  | * @return {String} id | 
														
													
														
															
																|  |  | * @private |  |  | * @private | 
														
													
												
													
														
															
																|  | @ -644,21 +674,20 @@ DataSet.prototype._castItem = function (item, fieldTypes, fields) { | 
														
													
														
															
																|  |  | DataSet.prototype._updateItem = function (item) { |  |  | DataSet.prototype._updateItem = function (item) { | 
														
													
														
															
																|  |  | var id = item[this.fieldId]; |  |  | var id = item[this.fieldId]; | 
														
													
														
															
																|  |  | if (id == undefined) { |  |  | if (id == undefined) { | 
														
													
														
															
																|  |  | throw new Error('Item has no id (item: ' + JSON.stringify(item) + ')'); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | throw new Error('Cannot update item: item has no id (item: ' + JSON.stringify(item) + ')'); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | var d = this.data[id]; |  |  | var d = this.data[id]; | 
														
													
														
															
																|  |  | if (d) { |  |  |  | 
														
													
														
															
																|  |  | // merge with current item |  |  |  | 
														
													
														
															
																|  |  | for (var field in item) { |  |  |  | 
														
													
														
															
																|  |  | if (item.hasOwnProperty(field)) { |  |  |  | 
														
													
														
															
																|  |  | var type = this.fieldTypes[field];  // type may be undefined |  |  |  | 
														
													
														
															
																|  |  | d[field] = util.cast(item[field], type); |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (!d) { | 
														
													
														
															
																|  |  |  |  |  | // item doesn't exist | 
														
													
														
															
																|  |  |  |  |  | throw new Error('Cannot update item: no item with id ' + id + ' found'); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | else { |  |  |  | 
														
													
														
															
																|  |  | // create new item |  |  |  | 
														
													
														
															
																|  |  | this._addItem(item); |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | // merge with current item | 
														
													
														
															
																|  |  |  |  |  | for (var field in item) { | 
														
													
														
															
																|  |  |  |  |  | if (item.hasOwnProperty(field)) { | 
														
													
														
															
																|  |  |  |  |  | var type = this.fieldTypes[field];  // type may be undefined | 
														
													
														
															
																|  |  |  |  |  | d[field] = util.cast(item[field], type); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | return id; |  |  | return id; | 
														
													
												
													
														
															
																|  |  |