Tuesday, January 12, 2010

Auto Commit Use Case in Oracle ADF 11g Table Component

It happens to develop such screens, where users can browse through table rows, select any row and using related form update selected row data. Thinking from pure end-user approach, when data table contains many columns, sometimes its easier to edit row data in separate form. Everything is fine with this approach, however there is one thing that can be confusing to the end-user. Let's say, user is editing row data and then suddenly selects another row from the table, without saving changes from previous row. In such way, user can end up with changes in many rows and will loose track what should be saved and what reverted. This use case is from real life.

In order to avoid user confusion with changes in multiple rows, I have developed sample application - TableAutoCommit.zip. This application implements read-only table and editable form, which brings data from currently selected row. Main trick - if user will edit data from selected row and will select another row without saving or reverting his changes, changes will be saved automatically - this will allow end-user to keep track of his changes easier. Of course, its not generic solution and should not be applied everywhere, it should be applied only if its really needed in specific case.

In this example, user selects first row from the table, editable form allows to change selected attributes:



Then he enters phone number:



And selects another row without saving changes he did:



Changes will be saved automatically and message will appear to inform user about latest commit:



When there are no pending changes, user can select any rows, nothing happens:



I will describe how it is implemented - really easy with ADF 11g. Only thing you need to have is custom SelectionListener for table component:



Also there should be method to determine unsaved changes. You can check if there are any, just with ADF standard method - isDirty():



Lastly, if there are unsaved changes, invoke commit operation and display information message. Otherwise, just proceed to the next row selection:


10 comments:

Patrik Frankovic said...

Great post as allways! Just what I needed :). Thank you Andrejus.

Andrej Baranovskij said...

Thanks Patric ;)

Anonymous said...

Really Great post...thank you

Unknown said...

It help for me powerful, thank

Unknown said...

Really great post, just 2 questions.

1. The problem this post manages is related to only loosing the track of changes or loosing the data entered by the user? I mean that if the user changes data and alters row selection without saving, are these data lost or the framework is able to restore changed values somehow? In my use case the data are lost.

2. Is there any way to realize if changes are related to table data and not generally data control? I mean that the dirty state may be related to irrelevant components in the same page that use the same data control.

Thanks.

Andrej Baranovskij said...

This sample saves data on each row selection event, this means it prevents loosing and corrupting data. Its using atomic commits.

Regards,
Andrejus

Unknown said...

Hello Andrejus,
First of all thanks for this great post, really helpful. I sadly have one issue, when I select another row and there were no modifications(is dirty is false) the whole table gets refreshed. I could not figure why. Info: my table is editable and it is a huge inconvenient when the user selects another row the table gets refreshed.
Any ideas on this one?
Thanks in advance,
Cristian

Andrej Baranovskij said...

Hi Cristian,

This happens because you have AutoPPR = TRUE set in Page Definiton, for table Iterator.

Regards,
Andrejus

Unknown said...

Hello,
Thanks for your answer, but in my case i have "ChangeEventPolicy" set to default (none). So it should not trigger the ppr.
Could there be another issue? I have no partial page trigger set on the table so it's not from there.

Thanks,
Cristian

chemic said...

hello Andre...

i got problem, when creating TableAutoSubmit in popup, why when selectOneRow, binding function not work..? can you explain it..

thx
agungdmt