| DHTMLX Documentation

## Dataprocessor usage

What is a dataprocessor. A dataprocessor is a small library which can integrate ghtmlxGrid (dhtmlxTreeGrid, dhtmlxTree ) 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.
( Starting dhtmlxSuite 2.1, there are ready to use PHP connectors , which can be used instead of custom coding )

### 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, and will send them to the server only after sendData method is executed.

### Adjusting server side code

If you are using php-connectors - please reffer to connectors documentation.
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

Starting from version 2.0 package includes additional debug console, which can be enabled by including dhtmlxdataprocessor_debug.js in addition to default js files.

### 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 5 predefined modes of response:

- update
- insert
- delete
- invalid
- error

But in some 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("my_error",my_action)

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

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

### Events

custom code can be attached in common way

> dp.attachEvent(event_name, some_function);

onRowMark - occurs each time when row need to be repaint, blockable
- row id
- row state ( true - updated, false - update mark removed )
- mode - updated,deleted,inserted
- invalid - set if row has error or invalid status
onValidatationError - occurs each time when verificator function catch error, blockable
- row id
- array of error messaged
onBeforeUpdate - occurs before data sending to the server, occurs for each row, blockable
- row id
- row status
onBeforeDataSending - occurs when data validated and ready to sending , occurs once for all rows in sending group, blockable
- row id - defined only if one row sent, not defined for multi-sending modes
onAfterUpdate - occurs for each action tag in xml response
- sid
- action
- tid
- xml node object
onAfterUpdateFinish - occurs when current data sync operation finished
onFullSync - occurs when all data saved ( there are no unsaved changes )

### Validation

Grid allow to define validators which will be activated before data sending.
dp.setVerificator(index,method);
index - index of column for which verificator will be assigned
method - verificator function
verificator function is a function which will receive
- value of cell
- id of row
- index of columns
and based on such values must return true or false, to accept or deny value.
If any value was denied during validation - data sending will be blocked.

#### Validate message

If you need to collect all validation errors and output a single error message it can be done by return a text message from validation function instead of false.
You can check 07_basic_validation_with_message.html sample, inside dataprocessor's package, for more details.

### Customizing color-marking

Default styles can be aceessed and updated as
dp.style.updated - style string for updated status
dp.style.inserted- style string for inserted status
dp.style.deleted - style string for deleted status
dp.style.invalid - style string for ivalid status
dp.style.invalid_cell - style assigned to cell which failed validation
dp.style.error - style string for error status
dp.style.clear - default style of row
More complex coloring rules can be defined though onRowMark event.

### Common tasks

a) Waiting for update finishing
There two events which can be used to catch finish of data sync operation

> dp.attachEvent("onAfterUpdateFinish",function(){
> alert("single row updated")
> });
> dp.attachEvent("onFullSync",function(){
> alert("all rows updated")
> });

In any moment of time state of update can be checked as

> dp.getSyncState()

which will return count of changed but not saved rows.
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);

If you want to mark row with status different from "updated" (not sure how it can be useful, but still ) it can be done as

> dp.setUpdated(id,true,"status name");

c) Error catching
Starting version 2.1, dataprocessor has default reaction on "error" response type, which can be used to report about server side errors. Row marked as error will be highlighted in grid. And will not be sent back to server untill one of next events
- user edit data in row
- rows set back to updated status through setUpdated command
d) Sever side validation
There is a built in support for "invalid" status in server side response. Which similar to "error", but have different visual marking.
If you want to extend it, it can be done as

> dp.defineAction("invalid",function(sid,response){
> var message = response.getAttribute("message");
> alert(message);
> return true;
> })

now on server side, if data is not valid you can just output next instead of valid response
<data>
<action sid="{gr_id}" type="invalid" message="Data in first column is not valid" />
</data>
e) Loading extra data during update

> It possible to extend default after-update reaction as dp.defineAction("updated",function(sid,response){
> var sid = response.getAttribute("sid");
> var extra = response.getAttribute("extra");
> this.obj.cells(id,0).setValue(extra);
> return true;
> })

with such code you will be able to specify any additional data which need to be updated in grid after receiving xml response from server
<data>
<action sid="{gr_id}" type="updated" tid="{gr_id}" extra="new value for first column" />
</data>

### Common errors

a) Incorrect XML error
Most possible reason - it is caused by some server side error, which breaks the XML. You can enable debug console and check the response of the server side to receive more information. ( debug console can detect may types of xml related errors and show reasons of problems )
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.
You can define custom marking routine - which will hide rows instead or striking-through them
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.
© DHTMLX, 2008