Problems of live update

I’m using live update mode and encountered confused problem. I have 2 to 3 grids attached in one tab and may open several similar tabs at once. That means there will be many grids opened.

Some code is:

var DPContact = new dataProcessor ('../Company/contactData.php'); DPContact.enableDataNames (true); DPContact.setUpdateMode ("row"); DPContact.setTransactionMode ('POST',true); DPContact.live_updates (server+"/sync"); DPContact.init (contactGrid);

When I add or modify a row in one grid, e.g. Grid A. The modified row appears in all opened grids. So I checked live_update.js, the code is:

case 'updated': case 'update': case 'inserted': case 'insert': if (self.obj.exists(sid)) { if (self.obj.isLUEdit(data) === sid) { self.obj.stopEditBefore(); }; self.ignore(function() { self.obj.update(sid, data); if (sid !== tid) self.obj.changeId(sid, tid); }); } else { data.id = tid; self.ignore(function() { self.obj.add(data); }); } break;
It shows update and insert action share the same code, so modifing a row acts as inserting a row. So I changed the code as below:

case 'updated': case 'update': if (self.obj.exists(sid)) { if (self.obj.isLUEdit(data) === sid) { self.obj.stopEditBefore(); }; self.ignore(function() { self.obj.update(sid, data); if (sid !== tid) self.obj.changeId(sid, tid); }); } break; case 'inserted': case 'insert': if (!self.obj.exists(sid)) { data.id = tid; self.ignore(function() { self.obj.add(data); }); } break;
Then the modified row will not affect other grids.

But other two problems still remain.

One is the live_update.js code seems to search if there’s a row with same row id. If so, then modify it. If not then add a new one. So if grid row id is an auto increment one(e.g. 0, 1, 2, … ), live_update will modify it regardless of whether it’s the identical grid.

Another is if there not exist a row with such row id, live_update will add a new one. But It will add new row to all the opened grids. But when I add a new row to gridA, it must not added to GridB, isn’t it?

Pls give some advices. Thanks.

Hi, I modified live_update.js as below (only grid codes). Both verify rowId and columnIds, so it meets my need.
Please check codes, is there anything I missed or any better methods?

[code]if (typeof(dataProcessor) !== “undefined”) {

dataProcessor.prototype.live_updates = function(url) {
	if (typeof Faye === "undefined") return;
	var self = this;
	var lu = this._live_upd = {};

	lu.client = new Faye.Client(url);
	lu.subscription = lu.client.subscribe('/update', function(update){
		var sid = update.sid;
		var tid = update.tid;
		var status = update.status;
		var data = update.data;
		var cids = update.cids;
		// prevent selection loosing
		if (self.obj.isSelected(sid)) data.$selected = true;

/**************************************************************************************************
add parameter cids
/
self.callEvent(“onLiveUpdate”, [status, sid, tid, data, cids]);
switch (status) {
case ‘updated’:
case ‘update’:
/

exist() = 1: means rowId and colId are all identical
/
if (self.obj.exists(sid, cids) === 1) {
if (self.obj.isLUEdit(data) === sid) {
self.obj.stopEditBefore();
};
self.ignore(function() {
self.obj.update(sid, data);
if (sid !== tid) self.obj.changeId(sid, tid);
});
}
break;
case ‘inserted’:
case ‘insert’:
/

exist() = 0: means rowId not exist but has identical colId, so need inserting
/
if (self.obj.exists(sid, cids) === 0) {
data.id = tid;
self.ignore(function() {
self.obj.add(data);
});
}
break;
case ‘deleted’:
case ‘delete’:
self.ignore(function() {
/

exist() = 1: means rowId and colId are all identical
/
if (self.obj.exists(sid, cids) === 1) {
self.obj.setUserData(sid, ‘!nativeeditor_status’, ‘true_deleted’);
self.obj.stopEditBefore();
self.obj.remove(sid);
if (self.obj.isLUEdit(data) === sid) {
// prevent loosing not-saved data
self.obj.preventLUCollision(data);
/

add parameter cids
**************************************************************************************************/
if (self.obj.callEvent(“onLiveUpdateCollision”, [sid, tid, status, data, cids]) === false) {
// we have to close editor here without saving
self.obj.stopEditAfter();
}
}
}
});
break;
}
});

    this.changed = function(sid, action, tid, tag){
        var item;
        if (self.obj.exists(tid || sid))
            item = self.obj.item(tid || sid);
        else
            item = {};

        if (typeof(item.$selected) !== 'undefined') delete item.$selected;
        if (typeof(item.$template) !== 'undefined') delete item.$template;

/**************************************************************************************************
add parameter cids, publish cell value and columnIds together
**************************************************************************************************/
lu.client.publish(’/broadcast’, { sid: sid, tid: tid, status: action, data: item, cids: self.obj.columnIds });
};
this.attachEvent(“onAfterUpdate”, this.changed);

}

}

if (typeof(dhtmlXGridObject) !== “undefined”) {
dhtmlXGridObject.prototype.item = function(id) {
var row = this.getRowById(id);
if (!row) return [];

	var data = { data: this._getRowArray(row) };
	return data;
};
dhtmlXGridObject.prototype.update = function(id, data) {
	data = data.data;
	for (var i = 0; i < data.length; i++) {
		var cell = this.cells(id, i);
		cell.setValue(data[i]);
	}
};
dhtmlXGridObject.prototype.remove = function(id) {

/**************************************************************************************************
remove it, already checked before remove() called
**************************************************************************************************/
// if (this.doesRowExist(id,cids))
this.deleteRow(id);
};

/**************************************************************************************************
exist()
return: 1 - colIds and rowId are identical
0 - colIds are same but rowId does not exist
-1 - colIds are different but rowId is identical
-2 - colIds and rowId are both different
**************************************************************************************************/
dhtmlXGridObject.prototype.exists = function(rid, cids) {
var isExist = this.doesRowExist(rid);
if (typeof (cids) === ‘undefined’) return isExist;

	var cnt = this.columnIds.length;
	if (cnt != cids.length)		return isExist ? -1 : -2;
	
	for (var i=0;i<cnt;i++) {
		if (this.columnIds[i] !== cids[i])	break;
	}
	return (i === cnt) ? (isExist ? 1 : 0) : (isExist ? -1 : -2);
};

dhtmlXGridObject.prototype.add = function(data) {
	var id = data.id;
	data = data.data;
	return this.addRow(id, data);
};

dhtmlXGridObject.prototype.changeId = function(old_id, new_id) {
	return this.changeRowId(old_id, new_id);
};

dhtmlXGridObject.prototype.stopEditBefore = function() {
	this.editStop();
};
dhtmlXGridObject.prototype.stopEditAfter = function() {};

dhtmlXGridObject.prototype.isLUEdit = function(data) {
	if (this.editor === null) return null;
	return this.row.idd;
};

dhtmlXGridObject.prototype.isSelected = function(id) { return false; };

}[/code]

And dp.enableDataNames (true); is needed

Hmm, may be it’s better to set a grid user data called ‘gridName’ and verify gridName but not columnIds

You are right, the existing version of data update uses a single channel for all updates, so it will not work correctly in case of multiple different grids

You can use different urls for live_updates command in different grids - but it will require multiple Faye servers, which is far from the best.

Thanks for the provided code, we will check how it can be included in the next version of dhtmlx suite.

It would be REALLY nice to have this work with multiple grids…

Are you still planning to include?

Please open ticket at the support.dhtmlx.com, we can provide a sample how the above code can be used with multiple grids.