How to avoid firing an OnSave event when clickling on a form

With the possibility in Servoy 3.0 to set autoSave to off (false) new problems arise because the OnRecordSave event is fired not only when you move from one record to another, but also if you click on an unused part of the form you are editing. That means that it is very easy to click somewhere in the form that it is not a field, a button and so on, thus starting the method associated with the OnRecordSave event.

To avoid this I put on the form a field whose dataprovider is a global variable set to null. This field has the same dimensions of the form, it is placed behind all the active elements and it is obviously set to non editable, non printable, cannot be selected on enter and it is transparent.

In my solution this trick seems to work and there are no more OnRecordSave events fired by mistake.

I understand this is not really an elegant workaround, but I could not imagine anything else which does not require writing a lot of code.

Does anyone know a better way to get the same results, and do you think that there could be any serious drawbacks in using the trick I just mentioned? Any help would be greatly appreciated.

Try this:

//Enable/disable the auto save when clicking anywhere on a form and the focus get lost.
application.setFocusLostSaveEnabled(false);

Nicola,

if I am not wrong application.setFocusLostSaveEnabled() is not a function of Servoy 3.0. It is not mentioned anywhere in the docs and it is not listed under the Application node in the method editor. It was present in Servoy 2.0, but not in the new version.

Hi Rioba,

I think that the old application node item is deprecated and is replaced in v3 by:

databaseManager.setAutoSave(true/false)

Cheers
Harry

Harry,

thanks, my original post was about the OnRecordSave event which is always fired even when databaseManager.setAutoSave() is false.

I have a method attached to the onRecordSave event and I want it to execute only when I move out of the record and not simply if I click on any unused portion of the form. Setting databaseManager.setAutoSave(false) does not prevent the event to be fired even if the record is not saved. The question is: how can I avoid this?

Harry wrote:

I have a method attached to the onRecordSave event and I want it to execute only when I move out of the record and not simply if I click on any unused portion of the record itself. Setting databaseManager.setAutoSave(false) does not prevent the event to be fired even if the record is not saved.

In my opinion this is clearly a bug. The same behavior - bug - was present in Servoy 2.

If anyone has any idea of why this should be so can you please explain it?

Best,
Miguel

Are you sure that the changed data is saved into the backend database???

the onSave is (I think) fired, but not really saved into the database
those records are so called: in-memory, so your are save in-memory

if you commit THAN the data is saved into the database.

HJK,

you are perfectly right, the records are not saved to the backend database.

This is another part of the problem, or maybe it is the origin of the problem.

Let me explain better. If I set autosave to false, records are not saved in memory even if the onRecordSave method is fired. This is now clear to me, but if you were a user and not the developer how would you know if the changes you made to a record have been saved or not? What you see is a modified record which does not necessarily reflect the database contents, and this could lead to a lot of confusion.

This is even truer if autosave is set to “true”. If you just click outside a field the changes are saved, even if the user is not aware of this because the onRecordSave is obviously activated in the background.

What I am trying to do is avoiding that any changes to the records are saved (or not saved) without an explicit action by the user. Avoiding that a click on the form could save changes without the user knowing it, is an essential part of this approach.

yes, but the record is NOT saved if you user clicked on the form.

What you want to achieve is simple,

set autosave off.

and make onHide method on the form, with one check

if(!globals.click)
{
rollbackChanges //look for the right syntax, I’m doing this by heart
globals.click = 0
}

I suppose you have a button on the form, where you want explicity SAVE the record. attach this kind of method:

commitChanges //look for the tight syntax
globals.click = 1

that’s it! now the changes are only saved, when a client hits your save button. When a client leaves the form, the changes are automaticly rolled back. There are many other ways to this.

hope this helps

Thanks, HJK

This is a good suggestion. I have just to modify it in order to make it work on a record by record basis (onHide would rollback or save changes made to any record using a particular form). But this is exactly the starting point I was looking for.

I hope if this issue could be resolved in the next Servoy release …

the onRecordEditSave event is renamed to onRecordEditStop in Servoy 3.5

Thanks Jan for your response,

but still this does not solve the problem of initiating a new transaction when entering any field !!!..

I guess that re-hiring this method again supposed to solve this issue

application.setFocusLostSaveEnabled(false);

I don’t know initially, why it was deprecated in 3.x

This is a serious issue

I wish if you can resolve this before the official release of Servoy 3.5…

I already opened a ticket in the support site …

We do not understand why this behaviour is called a bug, considered:
-the onRecordEditSave event is renamed to onRecordEditStop (in 3.5), which the correct name for the event (it should have bin called so from the start)
-the setFocusLostSaveEnabled is depricated and calls setAutoSave
-a servoy client can only start one transaction (not multiple at the same time)
-clicking out of a field fires the onRecordEditStop event
-setAutoSave(false) keeps changes in memory
-save to the database is only done when you tell Servoy todo so

Thanks a lot Jan,

this was very clear…
I finally succeeded to do it