738 lines
20 KiB
JavaScript
738 lines
20 KiB
JavaScript
/*
|
|
Product Name: dhtmlxSuite
|
|
Version: 5.2.0
|
|
Edition: Professional
|
|
License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com
|
|
Copyright UAB Dinamenta http://www.dhtmlx.com
|
|
*/
|
|
|
|
/**
|
|
* @desc: constructor, data processor object
|
|
* @param: serverProcessorURL - url used for update
|
|
* @type: public
|
|
*/
|
|
function dataProcessor(serverProcessorURL){
|
|
this.serverProcessor = serverProcessorURL;
|
|
this.action_param="!nativeeditor_status";
|
|
|
|
this.object = null;
|
|
this.updatedRows = []; //ids of updated rows
|
|
|
|
this.autoUpdate = true;
|
|
this.updateMode = "cell";
|
|
this._tMode="GET";
|
|
this._headers = null;
|
|
this._payload = null;
|
|
this.post_delim = "_";
|
|
|
|
this._waitMode=0;
|
|
this._in_progress={};//?
|
|
this._invalid={};
|
|
this.mandatoryFields=[];
|
|
this.messages=[];
|
|
|
|
this.styles={
|
|
updated:"font-weight:bold;",
|
|
inserted:"font-weight:bold;",
|
|
deleted:"text-decoration : line-through;",
|
|
invalid:"background-color:FFE0E0;",
|
|
invalid_cell:"border-bottom:2px solid red;",
|
|
error:"color:red;",
|
|
clear:"font-weight:normal;text-decoration:none;"
|
|
};
|
|
|
|
this.enableUTFencoding(true);
|
|
dhx4._eventable(this);
|
|
|
|
if (this.connector_init){
|
|
this.setTransactionMode("POST",true);
|
|
this.serverProcessor+=(this.serverProcessor.indexOf("?")!=-1?"&":"?")+"editing=true";
|
|
};
|
|
|
|
return this;
|
|
}
|
|
|
|
dataProcessor.prototype={
|
|
url:function(str){
|
|
if (str.indexOf("?") != -1)
|
|
return "&";
|
|
else
|
|
return "?";
|
|
},
|
|
setTransactionMode:function(mode,total){
|
|
if (typeof mode == "object"){
|
|
this._tMode = mode.mode || this._tMode;
|
|
this._headers = this._headers || mode.headers;
|
|
this._payload = this._payload || mode.payload;
|
|
} else {
|
|
this._tMode=mode;
|
|
this._tSend=total;
|
|
}
|
|
|
|
if (this._tMode == "REST"){
|
|
this._tSend = false;
|
|
this._endnm = true;
|
|
}
|
|
if (this._tMode == "JSON"){
|
|
this._tSend = false;
|
|
this._endnm = true;
|
|
this._headers = this._headers || {};
|
|
this._headers["Content-type"] = "application/json";
|
|
}
|
|
},
|
|
escape:function(data){
|
|
if (this._utf)
|
|
return encodeURIComponent(data);
|
|
else
|
|
return escape(data);
|
|
},
|
|
/**
|
|
* @desc: allows to set escaping mode
|
|
* @param: true - utf based escaping, simple - use current page encoding
|
|
* @type: public
|
|
*/
|
|
enableUTFencoding:function(mode){
|
|
this._utf=dhx4.s2b(mode);
|
|
},
|
|
/**
|
|
* @desc: allows to define, which column may trigger update
|
|
* @param: val - array or list of true/false values
|
|
* @type: public
|
|
*/
|
|
setDataColumns:function(val){
|
|
this._columns=(typeof val == "string")?val.split(","):val;
|
|
},
|
|
/**
|
|
* @desc: get state of updating
|
|
* @returns: true - all in sync with server, false - some items not updated yet.
|
|
* @type: public
|
|
*/
|
|
getSyncState:function(){
|
|
return !this.updatedRows.length;
|
|
},
|
|
/**
|
|
* @desc: enable/disable named field for data syncing, will use column ids for grid
|
|
* @param: mode - true/false
|
|
* @type: public
|
|
*/
|
|
enableDataNames:function(mode){
|
|
this._endnm=dhx4.s2b(mode);
|
|
},
|
|
/**
|
|
* @desc: enable/disable mode , when only changed fields and row id send to the server side, instead of all fields in default mode
|
|
* @param: mode - true/false
|
|
* @type: public
|
|
*/
|
|
enablePartialDataSend:function(mode){
|
|
this._changed=dhx4.s2b(mode);
|
|
},
|
|
/**
|
|
* @desc: set if rows should be send to server automaticaly
|
|
* @param: mode - "row" - based on row selection changed, "cell" - based on cell editing finished, "off" - manual data sending
|
|
* @type: public
|
|
*/
|
|
setUpdateMode:function(mode,dnd){
|
|
this.autoUpdate = (mode=="cell");
|
|
this.updateMode = mode;
|
|
this.dnd=dnd;
|
|
},
|
|
ignore:function(code,master){
|
|
this._silent_mode=true;
|
|
code.call(master||window);
|
|
this._silent_mode=false;
|
|
},
|
|
/**
|
|
* @desc: mark row as updated/normal. check mandatory fields,initiate autoupdate (if turned on)
|
|
* @param: rowId - id of row to set update-status for
|
|
* @param: state - true for "updated", false for "not updated"
|
|
* @param: mode - update mode name
|
|
* @type: public
|
|
*/
|
|
setUpdated:function(rowId,state,mode){
|
|
this._log("item "+rowId+" "+(state?"marked":"unmarked")+" ["+(mode||"updated")+"]");
|
|
|
|
if (this._silent_mode) return;
|
|
var ind=this.findRow(rowId);
|
|
|
|
mode=mode||"updated";
|
|
var existing = this.obj.getUserData(rowId,this.action_param);
|
|
if (existing && mode == "updated") mode=existing;
|
|
if (state){
|
|
this.set_invalid(rowId,false); //clear previous error flag
|
|
this.updatedRows[ind]=rowId;
|
|
this.obj.setUserData(rowId,this.action_param,mode);
|
|
if (this._in_progress[rowId])
|
|
this._in_progress[rowId]="wait";
|
|
} else{
|
|
if (!this.is_invalid(rowId)){
|
|
this.updatedRows.splice(ind,1);
|
|
this.obj.setUserData(rowId,this.action_param,"");
|
|
}
|
|
}
|
|
|
|
//clear changed flag
|
|
if (!state)
|
|
this._clearUpdateFlag(rowId);
|
|
|
|
this.markRow(rowId,state,mode);
|
|
if (state && this.autoUpdate) this.sendData(rowId);
|
|
},
|
|
_clearUpdateFlag:function(id){},
|
|
markRow:function(id,state,mode){
|
|
var str="";
|
|
var invalid=this.is_invalid(id);
|
|
if (invalid){
|
|
str=this.styles[invalid];
|
|
state=true;
|
|
}
|
|
if (this.callEvent("onRowMark",[id,state,mode,invalid])){
|
|
//default logic
|
|
str=this.styles[state?mode:"clear"]+str;
|
|
|
|
this.obj[this._methods[0]](id,str);
|
|
|
|
if (invalid && invalid.details){
|
|
str+=this.styles[invalid+"_cell"];
|
|
for (var i=0; i < invalid.details.length; i++)
|
|
if (invalid.details[i])
|
|
this.obj[this._methods[1]](id,i,str);
|
|
}
|
|
}
|
|
},
|
|
getState:function(id){
|
|
return this.obj.getUserData(id,this.action_param);
|
|
},
|
|
is_invalid:function(id){
|
|
return this._invalid[id];
|
|
},
|
|
set_invalid:function(id,mode,details){
|
|
if (details) mode={value:mode, details:details, toString:function(){ return this.value.toString(); }};
|
|
this._invalid[id]=mode;
|
|
},
|
|
/**
|
|
* @desc: check mandatory fields and varify values of cells, initiate update (if specified)
|
|
* @param: rowId - id of row to set update-status for
|
|
* @type: public
|
|
*/
|
|
checkBeforeUpdate:function(rowId){
|
|
return true;
|
|
},
|
|
/**
|
|
* @desc: send row(s) values to server
|
|
* @param: rowId - id of row which data to send. If not specified, then all "updated" rows will be send
|
|
* @type: public
|
|
*/
|
|
sendData:function(rowId){
|
|
if (rowId)
|
|
this._log("Sending: "+rowId);
|
|
|
|
if (this._waitMode && (this.obj.mytype=="tree" || this.obj._h2)) return;
|
|
if (this.obj.editStop) this.obj.editStop();
|
|
|
|
|
|
if(typeof rowId == "undefined" || this._tSend) return this.sendAllData();
|
|
if (this._in_progress[rowId]) return false;
|
|
|
|
this.messages=[];
|
|
if (this.getState(rowId) !== "deleted")
|
|
if (!this.checkBeforeUpdate(rowId) && this.callEvent("onValidationError",[rowId,this.messages])) return false;
|
|
|
|
this._beforeSendData(this._getRowData(rowId),rowId);
|
|
},
|
|
_beforeSendData:function(data,rowId){
|
|
if (!this.callEvent("onBeforeUpdate",[rowId,this.getState(rowId),data])) return false;
|
|
this._sendData(data,rowId);
|
|
},
|
|
serialize:function(data, id){
|
|
if (typeof data == "string")
|
|
return data;
|
|
if (typeof id != "undefined")
|
|
return this.serialize_one(data,"");
|
|
else{
|
|
var stack = [];
|
|
var keys = [];
|
|
for (var key in data)
|
|
if (data.hasOwnProperty(key)){
|
|
stack.push(this.serialize_one(data[key],key+this.post_delim));
|
|
keys.push(key);
|
|
}
|
|
stack.push("ids="+this.escape(keys.join(",")));
|
|
if (window.dhtmlx && dhtmlx.security_key)
|
|
stack.push("dhx_security="+dhtmlx.security_key);
|
|
return stack.join("&");
|
|
}
|
|
},
|
|
serialize_one:function(data, pref){
|
|
if (typeof data == "string")
|
|
return data;
|
|
var stack = [];
|
|
for (var key in data)
|
|
if (data.hasOwnProperty(key)){
|
|
if ((key == "id" || key == this.action_param) && this._tMode == "REST") continue;
|
|
stack.push(this.escape((pref||"")+key)+"="+this.escape(data[key]));
|
|
}
|
|
return stack.join("&");
|
|
},
|
|
_applyPayload:function(url){
|
|
if (this._payload)
|
|
for (var key in this._payload)
|
|
url = url + (url.indexOf("?") === -1 ? "?" : "&" ) + this.escape(key) + "=" + this.escape(this._payload[key]);
|
|
return url;
|
|
},
|
|
_sendData:function(a1,rowId){
|
|
|
|
this._log("url: "+this.serverProcessor);
|
|
this._log(a1)
|
|
|
|
if (!a1) return; //nothing to send
|
|
if (!this.callEvent("onBeforeDataSending",rowId?[rowId,this.getState(rowId),a1]:[null, null, a1])) return false;
|
|
|
|
if (rowId)
|
|
this._in_progress[rowId]=(new Date()).valueOf();
|
|
|
|
var that = this;
|
|
var back = function(xml){
|
|
var ids = [];
|
|
if (rowId)
|
|
ids.push(rowId);
|
|
else if (a1)
|
|
for (var key in a1)
|
|
ids.push(key);
|
|
|
|
return that.afterUpdate(that,xml,ids);
|
|
};
|
|
|
|
var a3 = this.serverProcessor+(this._user?(this.url(this.serverProcessor)+["dhx_user="+this._user,"dhx_version="+this.obj.getUserData(0,"version")].join("&")):"");
|
|
var a4 = this._applyPayload(a3);
|
|
|
|
if (this._tMode=="GET"){
|
|
dhx4.ajax.query({
|
|
url:a4+((a4.indexOf("?")!=-1)?"&":"?")+this.serialize(a1,rowId),
|
|
method:"GET",
|
|
headers:this._headers,
|
|
callback:back
|
|
});
|
|
}
|
|
else if (this._tMode == "POST"){
|
|
dhx4.ajax.query({
|
|
url:a4,
|
|
method:"POST",
|
|
headers:this._headers,
|
|
callback:back,
|
|
data:this.serialize(a1,rowId)
|
|
});
|
|
}
|
|
else if (this._tMode == "JSON"){
|
|
var action = a1[this.action_param];
|
|
var data = {};
|
|
for (var key in a1) data[key] = a1[key];
|
|
delete data[this.action_param];
|
|
delete data.id;
|
|
delete data.gr_id;
|
|
|
|
dhx4.ajax.query({
|
|
url:a4,
|
|
method:"POST",
|
|
headers:this._headers,
|
|
callback:back,
|
|
data:JSON.stringify({
|
|
id: rowId,
|
|
action: action,
|
|
data: data
|
|
})
|
|
});
|
|
}
|
|
else if (this._tMode == "REST"){
|
|
var state = this.getState(rowId);
|
|
var url = a3.replace(/(\&|\?)editing\=true/,"");
|
|
var parts = url.split("?");
|
|
if (parts[1])
|
|
parts[1] = "?"+parts[1];
|
|
|
|
var data = "";
|
|
var method = "POST";
|
|
|
|
if (state == "inserted"){
|
|
data = this.serialize(a1, rowId);
|
|
} else if (state == "deleted"){
|
|
method = "DELETE";
|
|
url = parts[0]+rowId+(parts[1]||"");
|
|
} else {
|
|
method = "PUT";
|
|
data = this.serialize(a1, rowId);
|
|
url = parts[0]+rowId+(parts[1]||"");
|
|
}
|
|
|
|
this._applyPayload(url);
|
|
dhx4.ajax.query({
|
|
url:url,
|
|
method:method,
|
|
headers:this._headers,
|
|
data:data,
|
|
callback:back
|
|
});
|
|
}
|
|
|
|
this._waitMode++;
|
|
},
|
|
sendAllData:function(){
|
|
this._log("Sending all updated items");
|
|
if (!this.updatedRows.length) return;
|
|
|
|
this.messages=[]; var valid=true;
|
|
for (var i=0; i<this.updatedRows.length; i++)
|
|
if (this.getState(this.updatedRows[i]) !== "deleted")
|
|
valid&=this.checkBeforeUpdate(this.updatedRows[i]);
|
|
|
|
if (!valid && !this.callEvent("onValidationError",["",this.messages])) return false;
|
|
|
|
if (this._tSend)
|
|
this._sendData(this._getAllData());
|
|
else
|
|
for (var i=0; i<this.updatedRows.length; i++)
|
|
if (!this._in_progress[this.updatedRows[i]]){
|
|
if (this.is_invalid(this.updatedRows[i])) continue;
|
|
this._beforeSendData(this._getRowData(this.updatedRows[i]),this.updatedRows[i]);
|
|
if (this._waitMode && (this.obj.mytype=="tree" || this.obj._h2)) return; //block send all for tree
|
|
}
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_getAllData:function(rowId){
|
|
var out={};
|
|
var has_one = false;
|
|
for(var i=0;i<this.updatedRows.length;i++){
|
|
var id=this.updatedRows[i];
|
|
if (this._in_progress[id] || this.is_invalid(id)) continue;
|
|
if (!this.callEvent("onBeforeUpdate",[id,this.getState(id), this._getRowData(id)])) continue;
|
|
out[id]=this._getRowData(id,id+this.post_delim);
|
|
has_one = true;
|
|
this._in_progress[id]=(new Date()).valueOf();
|
|
}
|
|
return has_one?out:null;
|
|
},
|
|
|
|
|
|
/**
|
|
* @desc: specify column which value should be varified before sending to server
|
|
* @param: ind - column index (0 based)
|
|
* @param: verifFunction - function (object) which should verify cell value (if not specified, then value will be compared to empty string). Two arguments will be passed into it: value and column name
|
|
* @type: public
|
|
*/
|
|
setVerificator:function(ind,verifFunction){
|
|
this.mandatoryFields[ind] = verifFunction||(function(value){return (value!=="");});
|
|
},
|
|
/**
|
|
* @desc: remove column from list of those which should be verified
|
|
* @param: ind - column Index (0 based)
|
|
* @type: public
|
|
*/
|
|
clearVerificator:function(ind){
|
|
this.mandatoryFields[ind] = false;
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
findRow:function(pattern){
|
|
var i=0;
|
|
for(i=0;i<this.updatedRows.length;i++)
|
|
if(pattern==this.updatedRows[i]) break;
|
|
return i;
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @desc: define custom actions
|
|
* @param: name - name of action, same as value of action attribute
|
|
* @param: handler - custom function, which receives a XMl response content for action
|
|
* @type: private
|
|
*/
|
|
defineAction:function(name,handler){
|
|
if (!this._uActions) this._uActions=[];
|
|
this._uActions[name]=handler;
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @desc: used in combination with setOnBeforeUpdateHandler to create custom client-server transport system
|
|
* @param: sid - id of item before update
|
|
* @param: tid - id of item after up0ate
|
|
* @param: action - action name
|
|
* @type: public
|
|
* @topic: 0
|
|
*/
|
|
afterUpdateCallback:function(sid, tid, action, btag) {
|
|
this._log("Action: "+action+" SID:"+sid+" TID:"+tid, btag);
|
|
var marker = sid;
|
|
var correct=(action!="error" && action!="invalid");
|
|
if (!correct) this.set_invalid(sid,action);
|
|
if ((this._uActions)&&(this._uActions[action])&&(!this._uActions[action](btag)))
|
|
return (delete this._in_progress[marker]);
|
|
|
|
if (this._in_progress[marker]!="wait")
|
|
this.setUpdated(sid, false);
|
|
|
|
var soid = sid;
|
|
|
|
switch (action) {
|
|
case "inserted":
|
|
case "insert":
|
|
if (tid != sid) {
|
|
this.obj[this._methods[2]](sid, tid);
|
|
sid = tid;
|
|
}
|
|
break;
|
|
case "delete":
|
|
case "deleted":
|
|
this.obj.setUserData(sid, this.action_param, "true_deleted");
|
|
this.obj[this._methods[3]](sid);
|
|
delete this._in_progress[marker];
|
|
return this.callEvent("onAfterUpdate", [sid, action, tid, btag]);
|
|
break;
|
|
}
|
|
|
|
if (this._in_progress[marker]!="wait"){
|
|
if (correct) this.obj.setUserData(sid, this.action_param,'');
|
|
delete this._in_progress[marker];
|
|
} else {
|
|
delete this._in_progress[marker];
|
|
this.setUpdated(tid,true,this.obj.getUserData(sid,this.action_param));
|
|
}
|
|
|
|
this.callEvent("onAfterUpdate", [soid, action, tid, btag]);
|
|
},
|
|
enableDebug:function(){
|
|
this._debug = true;
|
|
},
|
|
_log:function(){
|
|
if (this._debug && window.console && window.console.info)
|
|
window.console.info.apply(window.console, arguments);
|
|
},
|
|
/**
|
|
* @desc: response from server
|
|
* @param: xml - XMLLoader object with response XML
|
|
* @type: private
|
|
*/
|
|
afterUpdate:function(that,xml,id){
|
|
this._log("Server response received");
|
|
//try to use json first
|
|
if (window.JSON){
|
|
try{
|
|
var tag = JSON.parse(xml.xmlDoc.responseText);
|
|
var action = tag.action || this.getState(id) || "updated";
|
|
var sid = tag.sid || id[0];
|
|
var tid = tag.tid || id[0];
|
|
that.afterUpdateCallback(sid, tid, action, tag);
|
|
that.finalizeUpdate();
|
|
return;
|
|
} catch(e){
|
|
}
|
|
}
|
|
//xml response
|
|
var top = dhx4.ajax.xmltop("data", xml.xmlDoc); //fix incorrect content type in IE
|
|
if (!top || top.tagName == "DIV") return this.cleanUpdate(id);
|
|
var atag=dhx4.ajax.xpath("//data/action", top);
|
|
if (!atag.length) return this.cleanUpdate(id);
|
|
|
|
for (var i=0; i<atag.length; i++){
|
|
var btag=atag[i];
|
|
var action = btag.getAttribute("type");
|
|
var sid = btag.getAttribute("sid");
|
|
var tid = btag.getAttribute("tid");
|
|
|
|
that.afterUpdateCallback(sid,tid,action,btag);
|
|
}
|
|
that.finalizeUpdate();
|
|
},
|
|
cleanUpdate:function(id){
|
|
if (id)
|
|
for (var i = 0; i < id.length; i++)
|
|
delete this._in_progress[id[i]];
|
|
},
|
|
finalizeUpdate:function(){
|
|
if (this._waitMode) this._waitMode--;
|
|
|
|
if ((this.obj.mytype=="tree" || this.obj._h2) && this.updatedRows.length)
|
|
this.sendData();
|
|
this.callEvent("onAfterUpdateFinish",[]);
|
|
if (!this.updatedRows.length)
|
|
this.callEvent("onFullSync",[]);
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @desc: initializes data-processor
|
|
* @param: anObj - dhtmlxGrid object to attach this data-processor to
|
|
* @type: public
|
|
*/
|
|
init:function(anObj){
|
|
this.obj = anObj;
|
|
if (anObj._dp_init)
|
|
anObj._dp_init(this);
|
|
if (this.connector_init)
|
|
anObj._dataprocessor=this;
|
|
},
|
|
|
|
|
|
setOnAfterUpdate:function(ev){
|
|
this.attachEvent("onAfterUpdate",ev);
|
|
},
|
|
setOnBeforeUpdateHandler:function(func){
|
|
this.attachEvent("onBeforeDataSending",func);
|
|
},
|
|
|
|
|
|
|
|
/* starts autoupdate mode
|
|
@param interval
|
|
time interval for sending update requests
|
|
*/
|
|
setAutoUpdate: function(interval, user) {
|
|
interval = interval || 2000;
|
|
|
|
this._user = user || (new Date()).valueOf();
|
|
this._need_update = false;
|
|
this._update_busy = false;
|
|
|
|
this.attachEvent("onAfterUpdate",function(sid,action,tid,xml_node){
|
|
this.afterAutoUpdate(sid, action, tid, xml_node);
|
|
});
|
|
this.attachEvent("onFullSync",function(){
|
|
this.fullSync();
|
|
});
|
|
|
|
var self = this;
|
|
window.setInterval(function(){
|
|
self.loadUpdate();
|
|
}, interval);
|
|
},
|
|
|
|
|
|
/* process updating request answer
|
|
if status == collision version is depricated
|
|
set flag for autoupdating immidiatly
|
|
*/
|
|
afterAutoUpdate: function(sid, action, tid, xml_node) {
|
|
if (action == 'collision') {
|
|
this._need_update = true;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
},
|
|
|
|
|
|
/* callback function for onFillSync event
|
|
call update function if it's need
|
|
*/
|
|
fullSync: function() {
|
|
if (this._need_update == true) {
|
|
this._need_update = false;
|
|
this.loadUpdate();
|
|
}
|
|
return true;
|
|
},
|
|
|
|
|
|
/* sends query to the server and call callback function
|
|
*/
|
|
getUpdates: function(url,callback){
|
|
if (this._update_busy)
|
|
return false;
|
|
else
|
|
this._update_busy = true;
|
|
|
|
dhx4.ajax.get(url, callback);
|
|
},
|
|
|
|
|
|
/* returns xml node value
|
|
@param node
|
|
xml node
|
|
*/
|
|
_v: function(node) {
|
|
if (node.firstChild) return node.firstChild.nodeValue;
|
|
return "";
|
|
},
|
|
|
|
|
|
/* returns values array of xml nodes array
|
|
@param arr
|
|
array of xml nodes
|
|
*/
|
|
_a: function(arr) {
|
|
var res = [];
|
|
for (var i=0; i < arr.length; i++) {
|
|
res[i]=this._v(arr[i]);
|
|
};
|
|
return res;
|
|
},
|
|
|
|
|
|
/* loads updates and processes them
|
|
*/
|
|
loadUpdate: function(){
|
|
var self = this;
|
|
var version = this.obj.getUserData(0,"version");
|
|
var url = this.serverProcessor+this.url(this.serverProcessor)+["dhx_user="+this._user,"dhx_version="+version].join("&");
|
|
url = url.replace("editing=true&","");
|
|
this.getUpdates(url, function(r){
|
|
var top = dhx4.ajax.xmltop("updates", r.xmlDoc);
|
|
var vers = dhx4.ajax.xpath("//userdata", top);
|
|
self.obj.setUserData(0,"version",self._v(vers[0]));
|
|
|
|
var upds = dhx4.ajax.xpath("//update", top);
|
|
if (upds.length){
|
|
self._silent_mode = true;
|
|
|
|
for (var i=0; i<upds.length; i++) {
|
|
var status = upds[i].getAttribute('status');
|
|
var id = upds[i].getAttribute('id');
|
|
var parent = upds[i].getAttribute('parent');
|
|
switch (status) {
|
|
case 'inserted':
|
|
self.callEvent("insertCallback",[upds[i], id, parent]);
|
|
break;
|
|
case 'updated':
|
|
self.callEvent("updateCallback",[upds[i], id, parent]);
|
|
break;
|
|
case 'deleted':
|
|
self.callEvent("deleteCallback",[upds[i], id, parent]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
self._silent_mode = false;
|
|
}
|
|
|
|
self._update_busy = false;
|
|
self = null;
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
//(c)dhtmlx ltd. www.dhtmlx.com
|