Dataprocessor data send/update

Hi Guys, another problem I have…

I have a grid with a dataprocessor attached. The update method is set to row (dp.setUpdateMode(“row”)). If I have a a number of entries in the grid and I add/delete a row using grid.addRow/grid.deleteRow the data is only sent to the server when I click on another row on the grid. But I want this to happen as soon as I call addRow/deleteRow. This is a bigger problem when there is only one row in the grid, i.e. when I call deleteRow, the row gets a strikethough, but because I don’t have another row to click on in the grid, the actual update (delete) never happens? What could I be doing wrong on the grid that nothing happens until I click on another row?

This is expected behavior of “row” updated mode.
You can try to use dp.setUpdateMode(“cell”)

Hi Olga,

this works (updateMode(“cell”)) when I want to delete a lone row, however it still will not work for when I’m add the very first row to the table. I have only two cells in the row, the first one is a coro and when this is selected a javascript call pulls a default value from the database for the second cell. The user has nowhere (no other row to click) so the data doesn’t get sent… no update happens. The only way I can get it to work is if I select an option for the first cell, then reselect another option. The act of reselecting the second option seems to fire an event to send the data. Is there anyway to call a ‘senddata’ event for the grid/dataprocesser from my code?

thanks

as an update to this, I have two cells in the row, when I changed the update mode to cell, it won’t work when I have the second cell set to not be blank i.e. dp.setVerificator(1, not_empty);

If I remove this verificator the update works, but the valuye passed is ‘0’? As mentioned I populate this cell by a javascript call, perhaps even the cell value is being shown on the grid, its not actually be sent in the data?

the not_empty function is

  	function not_empty(value) 
  	{
			return value != "";
		}

Is there anyway to call a ‘senddata’ event for the grid/dataprocesser from my code?
dp.sendData()

where dp - instance of dataProcessor

Data will be sent automatically in the next cases

“cell” mode - after any successful data edit operation
“row” mode - after row selection change, or Enter key pressed

Try to change your code as

function not_empty(value) { return value !== ""; //strict comparison

Hi Stanislav,

I think the problem might be to do with the data being sent before my code puts the value into the cell. I am using the debug dataprocessor to see whats being sent and the second cell is sent back empty.

I have the following event attached to the grid

crewTasks.attachEvent(“onEditCell”,function(stage,id,ind)
{
if (stage==2)
{
if (ind==0)
{
window.setTimeout(function(){ loadDefaultValues();},1);
}
}

if (id==27000) return true;		//allow edit of new row
  	if (ind==0) return false;
  	
    return true;

});

function loadDefaultValues()
{
var vSelectedRow= crewTasks.getSelectedRowId();
if (crewTasks.cells(vSelectedRow,0).getValue())
{
loader = dhtmlxAjax.postSync(“crewdetail.php?action=taskdefaults&TaskID=”+ crewTasks.cells(vSelectedRow,0).getValue());
}

crewTasks.cells(vSelectedRow,1).setValue(loader.xmlDoc.responseText);
dp.sendData();
}

The value retrieved from the server for cellvalue 1 is inserted into the grid, but is not sent to the server for the update, heres the log from the debug

row 27000 marked [updated,invalid]
Initiating data sending for 27000
Initiating data sending for all rows
Sending all data at once
Server url: crewdetail.php?editing=true&action=crewtasks&CrewID=1141 parameters

27000_gr_id=27000
27000_c0=27
27000_c1=
27000_!nativeeditor_status=inserted
ids=27000

Server response received details

<?xml version='1.0' ?><data><action type='inserted' sid='27000' tid='27000' ></action></data>

Action: inserted SID:27000 TID:27000
row 27000 unmarked [updated,valid]
Initiating data sending for all rows

For info, the grid is constructed as

			crewTasks = crewTabbar.cells("crewrates").attachGrid();
			crewTasks.setImagePath('codebase/imgs/');
			crewTasks.setHeader('Task,Rate');
			crewTasks.setColTypes("coro,ed");	
			crewTasks.setInitWidths("200,200");
			crewTasks.setSkin('light');
			crewTasks.enableContextMenu(RateMenu);
			crewTasks.hdr.id="tasksheader";
			RateMenu.addContextZone("tasksheader");		
			crewTasks.attachEvent("onBeforeContextMenu", function(id,ind,obj){crewTasks.selectRowById(id);return true;});			
			dp= new dataProcessor("crewdetail.php?action=crewtasks&CrewID=0&uid="+(new Date()).valueOf());
			dp.setVerificator(0, not_empty); 
			//dp.setVerificator(1, not_empty); 
			dp.setUpdateMode("cell")

			dp.init(crewTasks);

If you need to send data not after cell-edit operation, but after some custom action ( extra data loading in your case ) - you need to disable auto-sending at all

dp.setUpdateMode(“off”)

With such mode, data will be sent only after sendData call.
By default data is sent after edit operation

To fix your current code, change the next line

crewTasks.cells(vSelectedRow,1).setValue(loader.xmlDoc.responseText);
dp.sendData();

as

crewTasks.cells(vSelectedRow,1).setValue(loader.xmlDoc.responseText);
crewTasks.cells(vSelectedRow,1).cell.wasChanged = true;
dp.sendData();

Thanks Stanislav,

thats seems to have resolved this problem.

regards,
Cyril

Hi Stanislav,

there is still one small problem with this… the changes you suggested do result in the value thats loaded in loadDefault() funtion being sent to the server, however there is another scenario where the user selects a value from the CORO which results in a default value being loaded and then tabbing onto the next cell and entering (or overriding the default). In this case, the updated value is not sent to the server? However if you edit this value as a completely seperate operation it does get sent?

The scenario is :
User Selects a task from the CORO
The code loads a default value from the database into the second cell
The DataProcessor sents these values to the server
The user changes the default value but this is not sent to the server?

If the user goes in subsequently to change a value, the it is sent to the server!

the modified code for the defautl load is

		function loadDefaultValues()
		{
			var vSelectedRow= crewTasks.getSelectedRowId();
			if (crewTasks.cells(vSelectedRow,0).getValue())
			{
				loader = dhtmlxAjax.postSync("crewdetail.php?action=taskdefaults&TaskID="+ crewTasks.cells(vSelectedRow,0).getValue());
				crewTasks.cells(vSelectedRow,1).setValue(loader.xmlDoc.responseText);
			}
			else
				crewTasks.cells(vSelectedRow,1).setValue("0");
			
			crewTasks.cells(vSelectedRow,1).cell.wasChanged = true;	
			dp.sendData();
		}

The code for the changes to the grid is -

			crewTasks.attachEvent("onEditCell",function(stage,id,ind)
			{
			 	if (stage==2)
				{
					if (ind==0)
						window.setTimeout(function(){	loadDefaultValues();},1);
					else //changes to the task rate
					{
						crewTasks.cells(id,1).cell.wasChanged = true;	
						window.setTimeout(function(){	dp.sendData();},1);
					}
				}

				if (id==27000) return true;		//allow edit of new row
  			if (ind==0) return false;
  				
  			return true;
			});

Is problem occurs only for such command sequence, or for any serie of edit operations?

a) double-check response for the first edit operation, if it was not correct, then grid can prevent any further send-data operations, because it still awaiting for data-saving-end.

b) on moment of second edit operation, is first data sending already finished? Grid will not send new data saving request, while first one is not finished. ( when both requests are executed against the same row )

I’m just wondering if it could be in relation to the rowid of the new row? When I create a new row in the grid I give it a row id of 27000. When the row is inserted it then is given the next id in the table as the primary key, and all updates to the table from this point onward use that id.

Is it possible that when I insert the row - the first update happens when the default value is loaded and it uses the grid row id of 27000, but then the seond update when the user overwrites the default value - the update still seems to be using a row id of 27000, when in fact the id has now changed to the id from the table… or at least thats what seems to be happening in the debug.

Because the second update is occuring in the row without the user having ever left the row since the addRow() function perhaps its not picking up the new row id from the server?

but then the seond update when the user overwrites the default value - the update still seems to be using a row id of 27000

If second update is triggered before receiving response for the first update - it will use original ID ( 27000 ) , which may be a reason of problem.
If second updated is triggered when second update already is received - it must not be a problem, because new ID will be used for all operation.

perhaps its not picking up the new row id from the server?
If response for insert command , with new id, was received - all ID references in the grid are changed automatically ( it may be a problem if you are storing ID reference somewhere in the custom code )

If second update is triggered before receiving response for the first update - it will use original ID ( 27000 ) , which may be a reason of problem.
If second updated is triggered when second update already is received - it must not be a problem, because new ID will be used for all operation.

How can I prevent the second update being applied before receiving a response for the first update?

thanks!

After additional checking, I think it also must not be the reason of problem. Dataprocessor will not send data for the same row second time, while response not received.

Can you provide a content of client side log for problematic operation?
( the log , which was published in earlier post doesn’t contain info about row ID changing )

Hi Stanislav,

heres the client side log, in this example I selected a task and the default value pulled from the server for the second cell was 25, I then changed this to 42 in the grid. As you can see this new value was sent up to the server - but it wasn’t updated in the table… I also have the server code below…

Log:
row 27000 marked [inserted,valid]
row 27000 marked [updated,valid]
Initiating data sending for all rows
Sending all data at once
Server url: clientdetail.php?editing=true&action=clienttasks&ClientID=64&uid=1272308533161 parameters

27000_gr_id=27000
27000_c0=27
27000_c1=25
27000_c2=10
27000_!nativeeditor_status=inserted
27000_description=Site%2FSteel
ids=27000

Server response received details

<?xml version='1.0' ?><data><action type='inserted' sid='27000' tid='27000' ></action></data>

Action: inserted SID:27000 TID:27000
row 27000 unmarked [updated,valid]
row 27000 marked [updated,valid]
Initiating data sending for all rows
Sending all data at once
Server url: clientdetail.php?editing=true&action=clienttasks&ClientID=64&uid=1272308533161 parameters

27000_gr_id=27000
27000_c0=27
27000_c1=42
27000_c2=10
27000_!nativeeditor_status=updated
27000_description=Site%2FSteel
ids=27000

Initiating data sending for all rows
Sending all data at once
Server url: clientdetail.php?editing=true&action=clienttasks&ClientID=64&uid=1272308533161 parameters

Server response received details

<?xml version='1.0' ?><data><action type='updated' sid='27000' tid='27000' ></action></data>

Action: updated SID:27000 TID:27000
row 27000 unmarked [updated,valid]

SERVER CODE*

	case "clienttasks":
	
		//retrieve rates for this client
		$GetRatesSQL = "select t1.DefRateID, t1.EntityID, t1.Rate, t1.Hours, t1.TaskID, t2.TaskDesc from calloutrates t1, tasks t2 where EntityID= $_GET[ClientID] and EntityType='Client' and t1.TaskID=t2.TaskID";
	
		$resconn->event->attach("beforeUpdate","logTaskChange");
		$resconn->event->attach("beforeDelete","logTaskChange");
		$resconn->event->attach("beforeInsert","logTaskChange");
	
		$resconn->sql->attach("Delete", "Delete from calloutrates WHERE DefRateID={DefRateID}");
		$resconn->sql->attach("Insert", "Insert into calloutrates (`EntityType`, `EntityID`, `TaskID`, `Rate`, `Hours`) VALUES ('Client', '$_GET[ClientID]', '{TaskDesc}', '{Rate}', '{Hours}')");
		
		$options = new OptionsConnector($connection);
		$options->render_table("tasks","TaskID","TaskID(value),TaskDesc(label)");
		$resconn->set_options("TaskDesc",$options);
		
		$resconn->render_sql($GetRatesSQL,"DefRateID",'TaskDesc,Rate,Hours');	
		
		break;
  • Could it be to do with my custom code -
    $resconn->sql->attach(“Insert”, “Insert into calloutrates (EntityType, EntityID, TaskID, Rate, Hours) VALUES (‘Client’, ‘$_GET[ClientID]’, ‘{TaskDesc}’, ‘{Rate}’, ‘{Hours}’)”);

I’m not sure if/why I have this code… I don’t have a custom ‘update’ though…!

This is the response on insert command

<?xml version='1.0' ?>

Action: inserted SID:27000 TID:27000

tid value is not changed - it means grid will not update row’s ID to the value from database. So next update will come with ID == 27000 as well
It was expected that tid value will have new ID

If you are using connectors - TID will be generated automatically
But if you are using connectors and custom updates logic you need to call

         $action->success($id); 

after successful inserting of new record. Where $id - id of new record.