Validating a record before leaving...

I’m working on a validation method, so that a user cannot exit the form unless the record passes validation. If validation fails, the user should be given a specific error message, or if a transaction is active (for a controlled ‘New’ or ‘Edit’ routine), the user will have the option of rolling back/cancelling.

I’ve put this method as the onSaveRecord property for the form.

Two challenges:

  1. If the user is in a field and clicks the background, the method can’t seem to read the field the user just left. F’rinstance, if the types a Name in a new record, and clicks out, the method sees the Name field as empty.

  2. The onSave doesn’t seem to trigger in the course of leaving the record, by going to the next record, creating a new record, etc. Am I correct in thinking that when you go to the next record, a save occurs?
    Is there an event more closely associated with “leaving the record”? I could revert to the old FM methodology of trying to block all the exits, but I was hoping that onSave would do it.

Hi Cain,

  1. What type of action triggers it? onFocusLost? onDataChange?

  2. onRecordSelection (on the FORM) fires when you change records.

Bob Cusick

I’ve put this method as the onSaveRecord property for the form.

onRecordSelection won’t trigger when you leave the form, will it? Besides, it triggers on the newly selected record, not the record you’re leaving.

A user can leave a record many ways: new, delete, record next, quit… I had thought that in all those cases, a save was occurring, and that onSave would be triggered.

Clariified some offline with Bob. Sharing in case someone else is following along.

The onSave does trigger when the form is left, the record is left, etc. Thing is, after triggerring, Servoy continues the action.

So, after validating the record, the user is taken to another record, form, whatever even if the validation failed.

Per Bob, there doesn’t seem to be a way to prevent this, so it appears I’ll have to add the validation to the start of a ‘new’ method, a ‘delete’ method, etc. to ‘block all the exits’.

Not the end of the world or anything. Servoy still rocks! :-D

you can turn of auto-save and with the onHide you can do youre validation and then call saveData youreself.

OK, the onHide is working now. I’ve managed to capture the users any time they try to leave a record/form, so I can validate and/or commit. Thanks for all your help and patience!

I’m still facing the other challenge from my original post, though:

  1. If the user is in a field and clicks the background, the method can’t seem to read the field the user just left. F’rinstance, if the types a Name in a new record, and clicks out, the method sees the Name field as empty.

To clarify, it’s not just when they click the background; if a method of any sort runs before they’ve left a field, the field is evaluated as it was before they entered it, not as it is now. Thus, if the user goes to the blank address field, enters an address, and then triggers the validation method (by whatever means), the method evaluates the address as empty and therefore invalid.

The onSave method and the evaluation both start with saveData. Is there a step to ‘exit record’ besides saveData? Or, how about a ‘go to next field’?

More frustrating still is that the whole sequence runs find with Debugger enabled. The field is evaluated with actual contents. With the debugger off, though, the field is evaluated with the contents when the field was entered.

how is that method executed?

because if they fill in address and theb press a button save. Then address is commited. If this is not the case then this is a bug.

I’m not assuming it’s a bug.

If I put a button on the form to run the method, the validation does indeed check based on the current data.

I need to trigger the exact same method onSave, though, and then the evaluation doesn’t use the current data. I tried to put saveData at the beginning of the method, but I’m guessing that it can’t “save on save”.

So how do I get out of the record without saveData? I found that if I put a dialog at the beginning of the method, it will leave the field and evaluate correctly. Is there some other step I could use that would be transparent to the user?

ahh so you are saying you have a form with data.
And you have a method that is called with the event onRecordSave()?
Yes onRecordSave is BEFORE the data is commited to the database. Because onRecordSave is meant to be used by for example beans to save its data als to the record.

I will look if we can call it a bit later so that the default things are commited to the record.

Thanks for your attention to this, Johan.

Is there a simple workaround? I’d like to implement this before the next revision, but more importantly, I’d hate to ask you to change the event if it’s currently (and usefully) geared toward something else.

In FM, there’s an ‘Exit Record/Request function’ or ‘Go to next field’ which would seem to serve me well here. If I could just get the user out of the field before validating…

I don’t think there is currently a way to do this. saveData is the way to do an exit record. But the problem is that you are inside the saveData routine.
The only fix for this is that i change the event call to be a bit later
This i can’t do for a 2.1.x release because i don’t know what can be touched at the moment.

To anyone watching this post…

I believe I’ve managed to ‘block all the exits’ without using the onSave trigger. It appears that, rather counter-intuitively, the save is NOT the point at which to validate. You actually want to save, and THEN validate the record.

Some notes on what I’m doing thus far:
-onRecordSelection triggers AFTER leaving the record. I have a global.recordCurrent, which I set to the record I’m ‘supposed’ to be on. When the user selects a new record, the method compares that global to the actual index. If we’re not ‘supposed’ to be here (as when the user hits alt and up, without triggering any method), then we go to the original record, validate it, then come to the target record only if we passed.
-Buttons for first, prev, next,last record need to set their target, then go to that index, due to the onRecordSelection desribed above.
-onHide, of course, needs to return false if invalid. An interesting note is that this won’t work properly with debugger, since events trigger in a slightly different order.
-Just about all the other events, like onSortCmd, onFindCmd, onNewCmd, run the validation routine and only proceed if no errors. Remember that some commands (like deleting) don’t require that the record is valid, but may require other validation.
-Closing the solution or the app can be made to present a dialog, but I can’t get it to not close. If I have a transaction open, though, I can notify that the transaction is being rolled back, and do that automatically.

I hope this helps someone besides myself. :)

onRecordSave will trigger now a slightly bit later in the next release of servoy.
All data is them committed to the in mem record but not yet in the database.

Excellent! Thank you for the update.

Hi Johan,

Where do I turn off auto save?
I cant find it in the online help or in the manuals.

Thanks

Aha! I know this one! ;-)

It’s a method function: application.setFocusLostSaveEnabled(boolean)

Found it .

[enh]-it is now possible to disable the auto save when clicking on form with: application.setFocusLostSaveEnabled(false)

Had looked for auto-save in the manuals.

Whoops

Thanks Cain.

application.setFocusLostSaveEnabled(boolean)