| DHTMLX Documentation

## Dataprocessor usage

What is a dataprocessor. A dataprocessor is a small library which can integrate ghtmlxGrid (dhtmlxTreeGrid) with server side backend. The library monitors changes in the grid and uses a simple protocol to interchange with the server side code. The dataprocessor consists of two parts - the client side code, which is common for any use-case and the server side code, which works by the same principles but needs to be adjusted for the used business-logic.

### Client side initialization

To initialize DataProcessor and attach it to the grid, the following two commands can be used:

> var dp = new dataProcessor(url)
> dp.init(mygrid)

Where: url - a relative or absolute path to a server side component of the dataprocessor.
mygrid - a dhtmlxGrid object.
By default the dataprocessor will be initialized in the auto update mode, which means that after each change in the grid it will send data to the server. In some cases it makes sense to use the manual update mode:

> dp.setUpdateMode("off")
> ...
> dp.sendData();

In such case the dataprocessor will store the information about all changes in the grid, but will send them to the server only after sendData method is executed.

### Adjusting server side code

The default package contains an example of the server side code for PHP (by additional request the similar code for JSP|ColdFusion|C#.Net|RybyOnRails can be sent).
The code does the following three tasks:
a) Takes parameters from the incoming request;
b) Makes the necessary DB operation;
c) Returns the information about the operation result.
The incoming parameters are:
gr_id - id of a row in the grid for which some operation is executed;
!nativeeditor_status - the status of the operation;
inserted - the row in question was added;
deleted - the row in question was deleted;
... any other value ... - the row was updated;
c0 - the data of the first column in the updated row;
c1 - the data of the second column in the updated row;
....
cN - the data of the (N+1)th column in the grid.
All the parameters are part of GET request.
Based on the value of "!nativeeditor_status" the related section of the server side logic is triggered.
The response must be in the following format:

> <data>
> <action type="some" sid="some" tid="some" />
> </data>

Where:

- type - the type of the operation (it may be "insert", "update", "delete");
- sid - the original row ID (the same as gr_id);
- tid - the ID of the row after the operation (may be the same as gr_id, or some different one - it can be used during a new row adding, when a temporary ID created on the client side is replaced with the ID taken from the DB or by any other business rule).

The response must be a valid XML in order to be processed correctly.

### Debug mode

The dataprocessor can be switched over to the debug mode, in which it will show details about the data sent to the server and the received response:

> dp.enableDebug(true)

### Data sending modes

a) Meaningfull names
The parameters c0-cN, used by default, are not very useful on the server side. The dataprocessor allows to use the grid column IDs instead of them:

> grid.setHeader("Name of the book,Name of the author")
> grid.setColumnIds("book,author");
> ...
> dp.enableDataNames(true);

on the server side:
$_GET['c0'] => $_GET['book']
$_GET['c1'] => $_GET['author']
b) Using POST instead of GET

> dp.setTransactionMode("POST")

c) Sending all at once
By default the update for each row will be sent as a separate request. This means that when 20 rows are updated - 20 requests will be sent to the server. This is not the best approach, so instead of it a single (more complex) request can be sent to the server side:

> dp.setTransactionMode("POST",true)
> or
> dp.setTransactionMode("POST",get)

In such mode the server side receives a slightly different set of parameters:
ids - a comma separated list of updated rows IDs, for each ID there will be set of details in the request.
For example if we have two updated rows on the client side with IDs = r2 and r3, the server side code will receive:
ids = r2,r3
r2_!nativeeditor_status - the status of the operation for row r2;
r2_c0 .. r2_cN - the data for a column of row r2;
r3_!nativeeditor_status - the status of the operation for row r3;
r3_c0 .. r3_cN - the data for a column of row r3.
The awaited server side response must be in the same format as usual, but must include the data for all processed rows:

> <data>
> <action type="some" sid="r2" tid="r2" />
> <action type="some" sid="r3" tid="r3" />
> </data>

### Custom server side responses

The dataprocessor has 3 predefined modes of response:

- Update;
- Insert;
- Delete.

But in some (many) cases you will need a way to return some additional information (the most common use-case - an error during a DB operation). In such case you can introduce an additional response type:

> dp.defineAction("error",my_action)

Where my_action - a custom function, which will be called when the response of "error" type is received.

> <data>
> <action type="error" sid="id" tid="id">Details</action>
> </data>
> function my_action(node){
> alert(node.getAttribute("action")); // error
> alert(node.firstChild.data); // Details
> return false;
> }

### Common tasks

a) Waiting for update finishing
The dataprocessor provides an event, which fires each time when a row is updated on the server:

> dp.setOnAfterUpdate(function(){
> alert("single row updated")
> if (dp.getSyncState())
> alert("all rows updated")
> });

b) Manual row updating
The dataprocessor detects only the row changed by edit operations. If a row was changed by a direct API call it will not be updated. You can manually call the dataprocessor to inform about the update operation:

> grid.cells(id,ind).setValue(new_one)
> dp.setUpdated(id,true);

The row can be marked as "not updated" in the same manner (may be useful in some scenarios):

> dp.setUpdated(id,false);

c) Error catching
While working with a custom response type it may be necessary to stop any further updating operation (an error occurs and any operation must be stopped). This can be done by using the error flag:

> dp.defineAction("error",function(){
> // any code
> dp.stopOnError = true;
> })

### Common errors

a) Incorrect XML error
Most possible reason - it is caused by some server side error, which breaks the XML. You can enable the debug mode and check the response of the server side to receive more information.
b) Deleted rows are not removed from the grid
Actually it is not an error - the rows will be removed only after synchronizing with the server.
c) Deleted rows are not removed from the grid after synchronizing with the server (updated|inserted rows stay bold)
Most possible reason - incorrect values of the "action" attribute in the response XML.
d) JS error after synchronizing with the server
Most possible reason - incorrect values of the "sid" and "tid" attributes in the response XML.
e) Infinite update loop
Such error can occur in case of the auto update mode when the information about a row update was sent to the server, but the response doesn't contain any "action" tag, or action tag has non default type. In such case the row will not be counted as correctly updated and the new request will be initiated. If you are using custom response type you can check the "error catching" solution above.
© DHTMLX, 2008