* deleteRow(..): the row disappear from Table (as expected by the user), but is still present in the table. You can access it with ITableRow#getDeletedRows(). Later if you export the form content in the formData, you will get row in the table with the status ITableHolder.STATUS_DELETED and you can persist the deletion in the database:

for (int i = 0; i < formData.getStandardTable().getRowCount(); i++) {
if (formData.getStandardTable().getRowState(i) == ITableHolder.STATUS_DELETED) {
//persist the deletion in the database.
}
}

I often use a switch on getRowState(), because the action I need depend on the row status:

* discardRow(..): the row is removed from the table and lost. Nothing is sent to the server.

Now if you set AutoDiscardOnDelete on the table, calling deleteRow(..) is equivalent to discardRow(..).

The semantic of a discarded row is: the row is deleted + there is no modification to commit to the server. The TableField assume there is no modifications. There is no "saveNeeded" status, the user will not be informed that he has pending modifications on the form...

This is why, in your case I recommend to set AutoDiscardOnDelete to false.

---
Now if you still want to discard a row, and to indicate to the form that you have a modification, you can

Now if for any reason you still want to discard a row, and in the same time indicate a pending modification you can:
* Call touch() on the TableField.
* Override the execIsSaveNeeded() on the TableField (this allow you to implement a custom calculation)

If you want to enforce a form store (like a OK or a SAVE button would do), instead of just indicating a modification on the form, I recommend you to call IForm#doSave() instead of AbstractForm#storeStateInternal(). The doSave() method will perform all the other checks (validations, custom checks...) in order to have a clean state of the form (and of the formData).

---

I hope this helps. Do not hesitate to continue the conversation if you need more informations.

Jeremie thank you, everything was very clear. The switch you suggested seems the way to go.

Do you happen to know the what each status mean??? How do you get an INSERTED row?, they are either in NON_CHANGED (even when they are new), DELETED or UPDATED.

It would be great, at least for me, that if a new row is added, even after the user edits some cell or not, the row would be in INSERTED state at the server. So i don´t have to "guess" if the row is new or not.