Main Region

automatic change detection on forms with no DB-column based fields
8 answers | 1022 views

JO
Jun 3, 2014 12:42 +00:00

Hi there,

In my understanding, automatic change detection on a grid or a form only works for columns/fields which have a source type of "DB Column".

But in many cases you do not want to have a form with direct CRUD-Operations on the tables. Instead sometimes the CRUD-Operation is done in centralized API-Routines which are called in DAs. Is there any mechanism in place providing a change detection so that the developer is a able to show a "Do you want to discard your changes" before leaving the form or window?

regards Jochen

4 comments

JO
Jochen Jun 6, 2014 05:56 +00:00 

excellent answer - as allways. Thanks.

MN
Matt Nolan Jun 6, 2014 15:07 +00:00 

You need to describe why it's not working e.g. javascript error in the console and provide the error message. Providing your setup helps but you have to include what is happening.

After looking at your setup:

Please note: Your javascript expression is evaluated on page load by APEX regardless of which event you listen to. In this case I suspect that Ext.getCmp('FORM_USER...') raises an exception

Your javascript expression should look like this:

(this.data && Ext.getCmp('FORM_USER...').getForm().isDirty())

The this.data will be valid when the event is triggered by FOEX.

MN
Matt Nolan Jun 9, 2014 06:38 +00:00 

How did you populate the fields in the DA? e.g. FOEX Form Load or using your own APEX Set Value action?

If you populated the form yourself you will need to reset the dirty status of fields.

Please in the future detail the steps you do rather than providing generic statements, i.e. as per my above question.

MN
Matt Nolan Jun 9, 2014 07:56 +00:00 

Why do you not use the Form load dynamic action.... I have noticed a lot of the questions you seem to ask on the forum are related to you working around what the framework provides and not using the built-in functionality. You are creating more work for yourself as well as having to support these custom actions yourself.

Note: the form load will execute all source types not just DB columns

You should create a test case on demo.tryfoexnow.com showing what you are trying to do so we can better advise you how to do things in a more efficient and supportable way.

MN
Jun 3, 2014 17:00 +00:00

Ok it appears there are 2 questions in here:

  1. What is the grid/form behaviour for detecting data collisions and changes?
  2. Adding an alert when there are unsaved changes in a form or grid?

Can you please clarify?

0 comments

JO
Jun 4, 2014 05:53 +00:00

Hi Matt,

you are right.

The answer for number 2 would it be. But answering number 1 would bring even more light to the subject.

To clarify: I have a form (in a popup window) with several items. The user changes some and then closes the window. The save procedure would be handled in a DA-PL/SQL-Procedure-call. Do I have to create a lot of Change-detecting-DAs or can the change detection achieved mor elegantly?

regards Jochen

0 comments

MN
Jun 4, 2014 10:15 +00:00

Ok to shed some light on change detection:

Note: change detection applies only to the serverside CRUD operations. It does not apply to detecting changes locally in the browser.

The Form Plugin

When using a FOEX Form and you perform a database action of Update/Delete within your button definition the form will automatically check the MD5 value of for the current record and match it against the database record contents which means that it checks database columns only. If it detects a difference it will raise an exception to advise that the data has been updated by someone else between the time that your record was loaded and when you issued the request.

Otherwise if the MD5 check is Ok then the operation will continue and after the DML is issued the database record will be requeried after the DML operation to pick up any changes that may occur from triggers etc. It will also sync back changes for externally managed multiselects, file browse items, and grid/tree combo's which set other values. It will recompute all item read only conditions, conditions and authorizations which may change when data values have changed. It will also recompute the conditions/authorizations on buttons.

If you choose to use your own procedure in the "Processing Procedure Override" to manage the form data yourself then your only responsibility is performing the DML which includes the checking of which items have changed and need updating. The "p_crud_request" parameter will have the OLD and NEW records for you to check the values. The plugin will still perform the MD5 check and will re-query the database record after the DML and perform the other operations.

For the inbuilt processing we do not perform change detection on items that are not mapped to a database column since there is no data source to save them to, they are simply derived columns. However we do provide the values of these items in the FX_CRUD_REQUEST_T request object type that is passed into your pre/override/post procedures so you have the option of using them and checking them yourself.

If you do not use the processing procedure override parameter and perform your own PLSQL in an Dynamic Action "Execute PLSQL Code" block then this is completely outside of the plugin and none of the above will occur. It will be your responsibility to do everything. We strongly recommend that you DO NOT use this method of external PLSQL in a dynamic action, and use the "Processing Procedure Override" plugin attribute in combination with the provided Form Dynamic Actions to perform the saving of data. This is the supported way.

The Grid Plugin

The "Change Detection" attribute controls change detection within the grid.

MD5 Check - for DELETE/UPDATE statements an MD5 checksum will be generated per row and used to check for data collisions. i.e. if changes have been made by another user after the data was fetched from the server. An exception will be raised if it detects a difference and the DML operation (for all grid rows in the transaction) will be rolled back i.e. not saved. There is some additional performance overhead when using this value as each record needs to be re-queried before update/delete.

Before DML - for UPDATE statements each will be queried before the UPDATE operation and compared for change detection, only those values that differ will be updated. If you do not use this setting then all values will be updated.

After DML - for CREATE/UPDATE statements each row will be queried after the UPDATE operation and compared for change detection by any additional changes incurred by triggers. These changes will be sent back to the client (browser) and the associated grid row updated to reflect the new values.

None - the row will not be checked, all columns will be updated and the row will not be requeried to check for changes by triggers.

If you do not use the inbuilt processing of the Grid plugin but provide your own processing procedure override within the plugin settings you will need to manually perform the (optional) step of checking which data values are different and only updating the columns that have changed. The plugin will still perform the MD5 Check and After DML step for you if you have defined these within the change detection setting.

0 comments

MN
Jun 4, 2014 11:17 +00:00

In terms of altering the user when there are unsaved changes, we are going to make some changes in the next release to simplify the setup of this.

Currently there are 2 "Alert on Pending Changes" dynamic actions which are to be used on events like "Before Refresh" which cancel the event if there are unsaved changes. However they do not work when leaving the page since this requires a native alert instead.

If you need an immediate solution it is possible that the Skillbuilders Save Before Exit plugin may provide you the solution you need (however we do not support it): http://www.apex-plugin.com/oracle-apex-plugins/dynamic-action-plugin/skillbuilders-save-before-exit_43.html

To identify if a form has outstanding changes you could use the following:

Ext.getCmp('REGION_STATIC_ID').getForm().isDirty()

To identify if a grid has outstanding changes

Ext.getCmp('REGION_STATIC_ID').getStore().hasPendingRequests() > 0

Making sure you change REGION_STATIC_ID to the Static ID of your plugin region.

Note: when using javascript there is always a possibility that these methods may change between versions which is why we recommend using the provided dynamic actions or waiting until one is provided where possible.

0 comments

JO
Jun 6, 2014 13:56 +00:00

Hi Matt, don't want to bother you to much on this topic. But I tried the Ext.getCmp('REGION_STATIC_ID').getForm().isDirty() - but it is not working.

I set the the function call in the condition of the window-close-DA.

alt text

I also set the trackResetOnLoad-config-setting in the form to {"trackResetOnLoad":true}.

alt text

But maybe I am missing something - as often ;-)

regards Jochen

0 comments

JO
Jun 7, 2014 11:13 +00:00

I ran it in the firebug console. It's allways return "true". I didn't see any exception

0 comments

JO
Jun 7, 2014 11:23 +00:00

the isDirty() function returns false when i initally loaded the main grid. then I call the popup window/form which is hidden on the same page via double click on some row. then I call the isDirty() function again in firebug console and it returns true (but i did not change anything - but populated the fields in a DA) Maybe I have to reset state after populating the fields

0 comments

JO
Jun 9, 2014 07:51 +00:00

Hi Matt, the fields are populated "by myself" indeed. So I already guessed that I have to reset the "isDirty-flag2 after populating the fields in the "bring up the popup window DA", but I didn't find out how to reset it yet

0 comments

You must log in or sign up to post questions and answers.